Index: /branches/eam_branches/ipp-20110505/Ohana/src/libohana/src/ohana_allocate.c
===================================================================
--- /branches/eam_branches/ipp-20110505/Ohana/src/libohana/src/ohana_allocate.c	(revision 31587)
+++ /branches/eam_branches/ipp-20110505/Ohana/src/libohana/src/ohana_allocate.c	(revision 31588)
@@ -31,27 +31,23 @@
 # define STATE_EXTERNAL 3
 
-typedef struct {
+# define OHANA_MEMMAGIC (uint32_t) 0xdeadbeef
+
+typedef struct Memblock {
+  uint32_t startblock;
+  struct Memblock *prevBlock;
+  struct Memblock *nextBlock;
+  size_t size;
   char *file;
-  int   line;
-  void *ptr;   // location of externally visible entry
-  int   size;
-  int   state;
-} Memlist;
-
-// XXX consider fixing the memory tracking model (list?)
-// static long *memsort;
-// static long *memhash;
-static Memlist *memlist = NULL;
-int Nmemlist = 0;
-int NMEMLIST = 0;
-int NMEMBYTE = 0;
+  char *func;
+  int line;
+  uint32_t endblock;
+} Memblock;
+
+static Memblock *lastMemBlock = NULL;
+
+static pthread_mutex_t memBlockListMutex = PTHREAD_MUTEX_INITIALIZER;
 
 void ohana_meminit () {
-  Nmemlist = 0;
-  NMEMLIST = 1000;
-  OHANA_ALLOCATE (memlist, Memlist, NMEMLIST);
-  // OHANA_ALLOCATE (memsort, long, NMEMLIST);
-  // OHANA_ALLOCATE (memhash, long, NMEMLIST);
-  NMEMBYTE = sizeof(size_t);
+  return;
 }
 
@@ -71,34 +67,41 @@
   size_t *marker;
 
-  if (memlist == NULL) ohana_meminit ();
-
   Nelem = MAX (1, Nelem);
   size = Nelem * esize;
 
-  new = malloc (size + 2*NMEMBYTE); /* 2 extra locations to save endposts */
+  new = malloc (sizeof(Memblock) + size + sizeof(void *)); /* memblock + data + endpost */
   if (new == NULL) ohana_memabort ("failed to allocate memory (%s, %d)\n", file, line);
-  ptr = new + NMEMBYTE;
-
-  marker = (size_t *) new;
-  *marker = 0xdeadbeef;
-  marker = (size_t *)(new + size + NMEMBYTE);
-  *marker = 0xdeadbeef;
+  ptr = new + sizeof(Memblock);
+
+  new->startblock = OHANA_MEMMAGIC;
+  new->endblock = OHANA_MEMMAGIC;
+  *(uint32_t *)((char *)(new + 1) + size) = OHANA_MEMMAGIC;
+
+  // marker = (size_t *)(new + size + NMEMBYTE);
+  // *marker = 0xdeadbeef;
 
   /* new memory, add to stack */
-  memlist[Nmemlist].ptr  = ptr;
-  memlist[Nmemlist].file = file;
-  memlist[Nmemlist].line = line;
-  memlist[Nmemlist].size = size;
-  memlist[Nmemlist].state = STATE_ALLOC;
-
-  // before each free, we sort this pair to speed up searching
-  // memsort[Nmemlist] = ptr;
-  // memhash[Nmemlist] = Nmemlist;
-
-  Nmemlist ++;
-  if (Nmemlist == NMEMLIST) {
-    NMEMLIST += 1000;
-    OHANA_REALLOCATE (memlist, Memlist, NMEMLIST);
-  }
+  new->file = file;
+  new->func = func;
+  new->line = line;
+  new->size = size;
+
+  // new memblock becomes the 'lastMemBlock':
+  // lastMemBlock = new
+  // new->prev = (new - 1)
+  // (new - 1)->next = new
+
+  new->nextBlock = NULL;
+
+  pthread_mutex_lock(&memBlockListMutex);
+
+  if (lastMemBlock) {
+    lastMemBlock->nextBlock = new;
+  }
+  new->prevBlock = lastMemBlock;
+  lastMemBlock = new;
+
+  pthread_mutex_unlock(&memBlockListMutex);
+
   return (ptr);
 }
@@ -110,45 +113,48 @@
   size_t *marker;
 
-  if (memlist == NULL) ohana_memabort ("REALLOCATE before ALLOCATE");
+  if (!in) {
+    ptr = ohana_alloc (file, line, Nelem, esize);
+    return ptr;
+  }
+
+  ref = ((Memblock *)in) - 1;
 
   Nelem = MAX (1, Nelem);
   size = Nelem * esize;
 
-  ref = in - NMEMBYTE;
-
-  /* find old entry, update ptr, file, line */
-  for (i = 0; i < Nmemlist; i++) {
-    if (memlist[i].state == STATE_FREE) continue;
-    if (memlist[i].ptr == in) {
-
-      if (memlist[i].state == STATE_EXTERNAL) ohana_memabort ("ERROR: realloc of external memory");
-
-      /* ask for new memory */
-      new = realloc (ref, size + 2*NMEMBYTE); /* 2 extra slots to save endposts */
-      if (new == NULL) ohana_memabort ("failed to reallocate memory (%s, %d)\n", file, line);
-      ptr = new + NMEMBYTE;
-      
-      /* set the marker */
-      marker = (size_t *) new;
-      *marker = 0xdeadbeef;
-      marker = (size_t *)(ptr + size);
-      *marker = 0xdeadbeef;
-
-      /* otherwise, update memory new location */
-      memlist[i].ptr = ptr;
-      memlist[i].size = size;
-      memlist[i].state = STATE_REALLOC;
-
-      /* if new memory in new location, update references */
-      if (ptr != in) {
-	memlist[i].file = file;
-	memlist[i].line = line;
-      }
-
-      return (ptr);
-    }
-  }
-  ohana_memabort ("allocated memory not found for realloc (%s, %d)\n", file, line);
-  return (NULL);
+  // requested same size as current allocation
+  if (size == ref->size) {
+    return ptr;
+  }
+
+  pthread_mutex_lock(&memBlockListMutex);
+
+  Memblock *nextBlock = ref->nextBlock;
+  Memblock *prevBlock = ref->prevBlock;
+
+  int isLast = (ref == lastMemBlock);
+
+  /* ask for new memory */
+  new = realloc (ref, sizeof(Memblock) + size + sizeof(void *)); /* memblock + data + endpost */
+  if (new == NULL) ohana_memabort ("failed to reallocate memory (%s, %d)\n", file, line);
+  ptr = new + sizeof(Memblock);
+  
+  new->size = size; 
+  *(uint32_t *)((char *)(new + 1) + size) = OHANA_MEMMAGIC;
+
+  if (isLast) {
+    lastMemBlock = new;
+  }
+
+  if (nextBlock) {
+    nextBlock->prevBlock = memBlock;
+  }
+  if (prevBlock) {
+    prevBlock->nextBlock = memBlock;
+  }
+  
+  pthread_mutex_unlock(&memBlockListMutex);
+
+  return (ptr);
 }
 
@@ -158,23 +164,27 @@
   int i;
 
-  if (memlist == NULL) ohana_memabort ("FREE before ALLOCATE");
-
-  /* find old entry, set state */
-  for (i = 0; i < Nmemlist; i++) {
-    if (memlist[i].state == STATE_FREE) continue;
-    if (memlist[i].ptr == in) {
-      memlist[i].state = STATE_FREE;
-      return;
-    }
-  }
-
-  /* find already freed examples */
-  for (i = 0; i < Nmemlist; i++) {
-    if (memlist[i].ptr == in) {
-      fprintf (stderr, "used here: %4d %s %d\n", i, memlist[i].file, memlist[i].line);
-    }
-  }
-
-  ohana_memabort ("allocated memory not found for free (%s, %d : %x)\n", file, line, in);
+  if (!in) return NULL;
+
+  ref = ((Memblock *) ptr) - 1;
+
+  pthread_mutex_lock(&memBlockListMutex);
+  
+  Memblock *nextBlock = ref->nextBlock;
+  Memblock *prevBlock = ref->prevBlock;
+
+  if (nextBlock) {
+    nextBlock->prevBlock = prevBlock;
+  }
+  if (prevBlock) {
+    prevBlock->nextBlock = nextBlock;
+  }
+  if (lastMemBlock == ref) {
+    lastMemBlock = prevBlock;
+  }
+  
+  pthread_mutex_unlock(&memBlockListMutex);
+  
+  free (ref);
+
   return;
 }
@@ -183,19 +193,9 @@
 void ohana_memregister_func (char *file, int line, void *ptr) {
 
-  if (memlist == NULL) ohana_meminit ();
-
-  /* add to stack */
-  memlist[Nmemlist].ptr  = ptr;
-  memlist[Nmemlist].file = file;
-  memlist[Nmemlist].line = line;
-  memlist[Nmemlist].state = STATE_EXTERNAL;
-  Nmemlist ++;
-  if (Nmemlist == NMEMLIST) {
-    NMEMLIST += 1000;
-    OHANA_REALLOCATE (memlist, Memlist, NMEMLIST);
-  }
-  return;
-}
-
+  // is this needed?
+  return;
+}
+
+# if (0)
 void ohana_memcheck_func (int allmemory) {
 
@@ -291,2 +291,3 @@
   return;
 }
+# endif
