IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Changeset 31589


Ignore:
Timestamp:
May 31, 2011, 8:02:50 AM (15 years ago)
Author:
eugene
Message:

updates for ohana malloc

Location:
branches/eam_branches/ipp-20110505/Ohana/src/libohana
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • branches/eam_branches/ipp-20110505/Ohana/src/libohana/include/ohana.h

    r31160 r31589  
    1919# include <readline/readline.h>
    2020
     21# define OHANA_MEMORY
     22
    2123// XXX I was including these before, but RHL claims they are not needed
    2224// # include <malloc.h>
  • branches/eam_branches/ipp-20110505/Ohana/src/libohana/include/ohana_allocate.h

    r30726 r31589  
    55# ifdef OHANA_MEMORY
    66
    7 void *ohana_malloc (char *file, int line, int Nelem, size_t esize);
    8 void *ohana_realloc (char *file, int line, void *in, int Nelem, size_t esize);
    9 void  ohana_free (char *file, int line, void *in);
    10 void  ohana_memregister_func (char *file, int line, void *ptr);
     7void *ohana_malloc (char *file, int line, char *func, int Nelem, size_t esize);
     8void *ohana_realloc (char *file, int line, char *func, void *in, int Nelem, size_t esize);
     9void  ohana_free (char *file, int line, char *func, void *in);
    1110void  ohana_memdump_func (int mode);
    1211void  ohana_memcheck_func (int mode);
    1312
    14 # define ohana_memregister(X) ohana_memregister_func (__FILE__, __LINE__, (X));
    1513# define ohana_memcheck(X) ohana_memcheck_func (X);
    1614# define ohana_memdump(X) ohana_memdump_func (X);
    1715
    1816# define ALLOCATE(PTR,TYPE,SIZE) \
    19   { PTR = (TYPE *) ohana_malloc (__FILE__, __LINE__, (SIZE), sizeof(TYPE)) }
     17  { PTR = (TYPE *) ohana_malloc (__FILE__, __LINE__, __func__, (SIZE), sizeof(TYPE)) }
    2018# define ALLOCATE_ZERO(PTR,TYPE,SIZE)                                   \
    21   { PTR = (TYPE *) ohana_malloc (__FILE__, __LINE__, (SIZE), sizeof(TYPE)); memset (PTR, 0, (SIZE)*sizeof(TYPE)); }
     19  { PTR = (TYPE *) ohana_malloc (__FILE__, __LINE__, __func__, (SIZE), sizeof(TYPE)); memset (PTR, 0, (SIZE)*sizeof(TYPE)); }
    2220# define REALLOCATE(PTR,TYPE,SIZE) \
    23   { PTR = (TYPE *) ohana_realloc(__FILE__, __LINE__, PTR, (SIZE), sizeof(TYPE)); }
     21  { PTR = (TYPE *) ohana_realloc(__FILE__, __LINE__, __func__, PTR, (SIZE), sizeof(TYPE)); }
    2422# define CHECK_REALLOCATE(PTR,TYPE,SIZE,NCURR,DELTA) {                  \
    2523  if ((NCURR) >= (SIZE)) { SIZE += DELTA;                               \
    26     PTR = (TYPE *) ohana_realloc(__FILE__, __LINE__, PTR, (SIZE), sizeof(TYPE)); } }
    27 # define FREE(PTR) { if (PTR != NULL) { ohana_free (__FILE__, __LINE__, PTR); } }
     24    PTR = (TYPE *) ohana_realloc(__FILE__, __LINE__, __func__, PTR, (SIZE), sizeof(TYPE)); } }
     25# define FREE(PTR) { if (PTR != NULL) { ohana_free (__FILE__, __LINE__, __func__, PTR); } }
    2826# define free(PTR) { ohana_free(__FILE__, __LINE__, PTR); }
     27# define real_free(PTR) { if (PTR) { free(PTR); }}
    2928
    30 # else
    31 # define ohana_memregister(X) /* NOP */
     29# else  /* OHANA_MEMORY */
     30
    3231# define ohana_memcheck(X) /* NOP */
    3332# define ohana_memdump(X) /* NOP */
    34 # endif /* OHANA_MEMORY */
     33# define real_free(PTR) { if (PTR) { free(PTR); }}
    3534
    3635# ifndef ALLOCATE
     
    6463# define FREE(PTR) { if (PTR != NULL) { free (PTR); } }
    6564# endif /* ALLOCATE */
     65# endif /* OHANA_MEMORY */
    6666
    6767# endif /* OHANA_ALLOCATE */
  • branches/eam_branches/ipp-20110505/Ohana/src/libohana/src/ohana_allocate.c

    r31588 r31589  
    22# include <stdlib.h>
    33# include <stdarg.h>
     4# include <stdint.h>
     5# include <pthread.h>
    46
    57/* need an internal version that does not use ohana_memory functions */
     
    79# define TRUE 1
    810# define MAX(X,Y) ((X) > (Y) ? (X) : (Y))
    9 # define OHANA_ALLOCATE(X,T,S)  \
    10   X = (T *) malloc ((unsigned)(MAX(((S)*((int)sizeof(T))),1))); \
    11   if (X == NULL) { \
    12     fprintf(stderr,"failed malloc at %d in %s\n", __LINE__, __FILE__);\
    13     abort(); }
    14 # define OHANA_REALLOCATE(X,T,S) \
    15   X = (T *) realloc(X,(unsigned)(MAX(((S)*((int)sizeof(T))),1))); \
    16   if (X == NULL) { \
    17     fprintf(stderr,"failed realloc at %d in %s\n", __LINE__, __FILE__);\
    18     abort(); }
    19 # define OHANA_CHECK_REALLOCATE(X,T,S,N,D) \
    20   if ((N) >= (S)) { \
    21     S += D; \
    22     X = (T *) realloc(X,(unsigned)(MAX(((S)*((int)sizeof(T))),1))); \
    23     if (X == NULL) { \
    24       fprintf(stderr,"failed realloc increment at %d in %s\n", __LINE__, __FILE__);\
    25       abort(); } }
    26 # define OHANA_FREE(X) free(X)
    27 
    28 # define STATE_ALLOC    0
    29 # define STATE_REALLOC  1
    30 # define STATE_FREE     2
    31 # define STATE_EXTERNAL 3
    3211
    3312# define OHANA_MEMMAGIC (uint32_t) 0xdeadbeef
    3413
    3514typedef struct Memblock {
    36   uint32_t startblock;
    37   struct Memblock *prevBlock;
    38   struct Memblock *nextBlock;
    39   size_t size;
    40   char *file;
    41   char *func;
    42   int line;
    43   uint32_t endblock;
     15  uint32_t startblock;        // endpost marker
     16  struct Memblock *prevBlock; // previously allocated memory
     17  struct Memblock *nextBlock; // next allocated memory
     18  size_t size;                // size of memory
     19  char *file;                 // file (re)allocated
     20  char *func;                 // func (re)allocated
     21  int line;                   // line (re)allocated
     22  uint32_t endblock;          // endpost marker
    4423} Memblock;
    4524
    46 static Memblock *lastMemBlock = NULL;
     25static Memblock *lastBlock = NULL;
    4726
    4827static pthread_mutex_t memBlockListMutex = PTHREAD_MUTEX_INITIALIZER;
     
    6140}
    6241
    63 void *ohana_malloc (char *file, int line, int Nelem, size_t esize) {
    64 
    65   void *ptr, *new;
    66   int size;
    67   size_t *marker;
     42void *ohana_malloc (char *file, int line, char *func, size_t Nelem, size_t esize) {
     43
     44  void *ptr;                  // actual user memory allocated
     45  Memblock *new;              // new memblock created to track the user memory
     46  size_t size;                // total number of bytes requested (not items)
    6847
    6948  Nelem = MAX (1, Nelem);
    7049  size = Nelem * esize;
    7150
    72   new = malloc (sizeof(Memblock) + size + sizeof(void *)); /* memblock + data + endpost */
    73   if (new == NULL) ohana_memabort ("failed to allocate memory (%s, %d)\n", file, line);
    74   ptr = new + sizeof(Memblock);
    75 
     51  // total size is : memblock + data + endpost
     52  new = (Memblock *) malloc (sizeof(Memblock) + size + sizeof(void *));
     53  if (new == NULL) ohana_memabort ("failed to allocate memory (%s, %d, %s)\n", file, line, func);
     54
     55  // pointer to the start of the user memory
     56  ptr = (char *)(new + 1);
     57
     58  // set the end-post values
    7659  new->startblock = OHANA_MEMMAGIC;
    7760  new->endblock = OHANA_MEMMAGIC;
    78   *(uint32_t *)((char *)(new + 1) + size) = OHANA_MEMMAGIC;
    79 
    80   // marker = (size_t *)(new + size + NMEMBYTE);
    81   // *marker = 0xdeadbeef;
    82 
    83   /* new memory, add to stack */
     61  *(uint32_t *)(ptr + size) = OHANA_MEMMAGIC;
     62
     63  // set the memory metadata
     64  new->size = size;
    8465  new->file = file;
     66  new->line = line;
    8567  new->func = func;
    86   new->line = line;
    87   new->size = size;
    88 
    89   // new memblock becomes the 'lastMemBlock':
    90   // lastMemBlock = new
     68
     69  // new memblock becomes the 'lastBlock':
     70  // lastBlock = new
    9171  // new->prev = (new - 1)
    9272  // (new - 1)->next = new
    9373
     74  // for memory allocated in the order m0, m1, m2
     75  // m0->next = m1, m1->next = m2, m2->next = NULL
     76  // m2->prev = m1, m1->prev = m0, m0->prev = NULL
     77  // lastBlock = m2
     78
     79  // set up the pointers
    9480  new->nextBlock = NULL;
    9581
     82  // protect the list during this operation
    9683  pthread_mutex_lock(&memBlockListMutex);
    9784
    98   if (lastMemBlock) {
    99     lastMemBlock->nextBlock = new;
    100   }
    101   new->prevBlock = lastMemBlock;
    102   lastMemBlock = new;
     85  if (lastBlock) {
     86    lastBlock->nextBlock = new;
     87  }
     88  new->prevBlock = lastBlock;
     89  lastBlock = new;
    10390
    10491  pthread_mutex_unlock(&memBlockListMutex);
     
    10794}
    10895
    109 void *ohana_realloc (char *file, int line, void *in, int Nelem, size_t esize) {
    110 
    111   int i, size;
    112   void *ptr, *ref, *new;
    113   size_t *marker;
    114 
     96void *ohana_realloc (char *file, int line, char *func, void *in, size_t Nelem, size_t esize) {
     97
     98  void *ptr;                  // actual user memory allocated
     99  Memblock *old;              // original memblock associated with user memory
     100  Memblock *new;              // new memblock associated with user memory
     101  size_t size;
     102
     103  // just allocate if not previously allocated
    115104  if (!in) {
    116     ptr = ohana_alloc (file, line, Nelem, esize);
     105    ptr = ohana_malloc (file, line, func, Nelem, esize);
    117106    return ptr;
    118107  }
    119108
    120   ref = ((Memblock *)in) - 1;
     109  // memblock of supplied pointer
     110  old = (Memblock *) in - 1;
    121111
    122112  Nelem = MAX (1, Nelem);
     
    124114
    125115  // requested same size as current allocation
    126   if (size == ref->size) {
    127     return ptr;
     116  if (size == old->size) {
     117    return in;
    128118  }
    129119
    130120  pthread_mutex_lock(&memBlockListMutex);
    131121
     122  Memblock *nextBlock = old->nextBlock;
     123  Memblock *prevBlock = old->prevBlock;
     124
     125  int isLast = (old == lastBlock);
     126
     127  // ask for new memory
     128  // total size is : memblock + data + endpost
     129  new = (Memblock *) realloc (old, sizeof(Memblock) + size + sizeof(void *));
     130  if (new == NULL) ohana_memabort ("failed to reallocate memory (%s, %d, %s)\n", file, line, func);
     131  ptr = (char *) (new + 1);
     132 
     133  // give the realloc location:
     134  new->size = size;
     135  new->file = file;
     136  new->line = line;
     137  new->func = func;
     138
     139  // update the endpost (the others were set originally
     140  *(uint32_t *)(ptr + size) = OHANA_MEMMAGIC;
     141
     142  // need to reset lastBlock in case we moved
     143  if (isLast) {
     144    lastBlock = new;
     145  }
     146
     147  // need to adjust the neighbors' pointers:
     148  if (nextBlock) {
     149    nextBlock->prevBlock = new;
     150  }
     151  if (prevBlock) {
     152    prevBlock->nextBlock = new;
     153  }
     154 
     155  pthread_mutex_unlock(&memBlockListMutex);
     156
     157  return (ptr);
     158}
     159
     160// this is very slow.  should we speed this up by indexing on the ptr?
     161void ohana_free (char *file, int line, char *func, void *in) {
     162
     163  Memblock *ref;
     164
     165  if (!in) return;
     166
     167  ref = (Memblock *) in - 1;
     168
     169  pthread_mutex_lock(&memBlockListMutex);
     170 
    132171  Memblock *nextBlock = ref->nextBlock;
    133172  Memblock *prevBlock = ref->prevBlock;
    134173
    135   int isLast = (ref == lastMemBlock);
    136 
    137   /* ask for new memory */
    138   new = realloc (ref, sizeof(Memblock) + size + sizeof(void *)); /* memblock + data + endpost */
    139   if (new == NULL) ohana_memabort ("failed to reallocate memory (%s, %d)\n", file, line);
    140   ptr = new + sizeof(Memblock);
    141  
    142   new->size = size;
    143   *(uint32_t *)((char *)(new + 1) + size) = OHANA_MEMMAGIC;
    144 
    145   if (isLast) {
    146     lastMemBlock = new;
    147   }
    148 
    149   if (nextBlock) {
    150     nextBlock->prevBlock = memBlock;
    151   }
    152   if (prevBlock) {
    153     prevBlock->nextBlock = memBlock;
    154   }
    155  
    156   pthread_mutex_unlock(&memBlockListMutex);
    157 
    158   return (ptr);
    159 }
    160 
    161 // this is very slow.  should we speed this up by indexing on the ptr?
    162 void ohana_free (char *file, int line, void *in) {
    163 
    164   int i;
    165 
    166   if (!in) return NULL;
    167 
    168   ref = ((Memblock *) ptr) - 1;
    169 
    170   pthread_mutex_lock(&memBlockListMutex);
    171  
    172   Memblock *nextBlock = ref->nextBlock;
    173   Memblock *prevBlock = ref->prevBlock;
    174 
    175174  if (nextBlock) {
    176175    nextBlock->prevBlock = prevBlock;
     
    179178    prevBlock->nextBlock = nextBlock;
    180179  }
    181   if (lastMemBlock == ref) {
    182     lastMemBlock = prevBlock;
     180  if (lastBlock == ref) {
     181    lastBlock = prevBlock;
    183182  }
    184183 
     
    190189}
    191190
    192 /* register externally allocated memory with ohana memory manager */
    193 void ohana_memregister_func (char *file, int line, void *ptr) {
    194 
    195   // is this needed?
    196   return;
    197 }
    198 
    199 # if (0)
    200191void ohana_memcheck_func (int allmemory) {
    201192
    202   int i, j, next, prev, header;
    203   size_t *marker;
    204   char top, bottom;
    205 
    206   if (Nmemlist == 0) {
     193  if (!lastBlock) {
    207194    fprintf (stderr, "no memory allocated\n");
    208195    return;
    209196  }
    210197
    211   header = FALSE;
    212   fprintf (stderr, "checking %d memory blocks\n", Nmemlist);
    213   for (i = 0; i < Nmemlist; i++) {
    214     if (memlist[i].state == STATE_EXTERNAL) continue;
    215     if ((allmemory == 0) && (memlist[i].state == STATE_FREE)) continue;
    216 
    217     top = bottom = 'Y';
    218     marker = (size_t *)(memlist[i].ptr - NMEMBYTE);
    219     if (*marker == 0xdeadbeef) bottom = 'N';
    220     marker = (size_t *)(memlist[i].ptr + memlist[i].size);
    221     if (*marker == 0xdeadbeef) top = 'N';
     198  Memblock *thisBlock = lastBlock;
     199
     200  size_t Ngood  = 0;
     201  size_t Nbad   = 0;
     202  size_t Ntotal = 0;
     203  size_t Nbytes = 0;
     204
     205  while (thisBlock) {
     206
     207    int good = TRUE;
    222208   
    223     if ((top == 'N') && (bottom == 'N')) continue;
    224     if (!header) {
    225       fprintf (stderr, "         Nmem start end file            line\n");
    226       header = TRUE;
     209    if (thisBlock->startblock != OHANA_MEMMAGIC) good = FALSE;
     210    if (thisBlock->endblock != OHANA_MEMMAGIC) good = FALSE;
     211
     212    // pointer to the start of the user memory
     213    char *ptr = (char *)(thisBlock + 1) + thisBlock->size;
     214    uint32_t endpost = *(uint32_t *)ptr;
     215    if (endpost != OHANA_MEMMAGIC) good = FALSE;
     216
     217    // XXX keep checking even if memory is corrupted?
     218    if (!good) {
     219      if (Nbad < 1) {
     220        fprintf (stderr, "memory corruption\n");
     221      }
     222      if (Nbad < 100) {
     223        fprintf (stderr, "  file: %s, line: %d, func: %s\n", thisBlock->file, thisBlock->line, thisBlock->func);
     224      }
     225      Nbad ++;
     226    } else {
     227      Ngood ++;
    227228    }
    228     fprintf (stderr, "corrupt:  %3d   %c    %c  %-15s %3d\n", i, bottom, top, memlist[i].file, memlist[i].line);
    229     prev = next = -1;
    230     for (j = 0; j < Nmemlist; j++) {
    231       if (memlist[j].ptr < memlist[i].ptr) {
    232         if (prev == -1) prev = j;
    233         if (memlist[j].ptr > memlist[prev].ptr) prev = j;
    234       }
    235       if (memlist[j].ptr > memlist[i].ptr) {
    236         if (next == -1) next = j;
    237         if (memlist[j].ptr < memlist[next].ptr) next = j;
    238       }
    239     }     
    240     if (prev == -1) {
    241       fprintf (stderr, "no previous memory block\n");
    242     } else {
    243       fprintf (stderr, "prev:     %3d           %-15s %3d\n", prev, memlist[prev].file, memlist[prev].line);
    244     }
    245     if (next == -1) {
    246       fprintf (stderr, "no next memory block\n");
    247     } else {
    248       fprintf (stderr, "next:     %3d           %-15s %3d\n", next, memlist[next].file, memlist[next].line);
    249     }
    250   }
     229    Ntotal ++;
     230    Nbytes += thisBlock->size;
     231
     232    thisBlock = thisBlock->prevBlock;
     233  }
     234 
     235  fprintf (stderr, "%zd memory blocks allocated (%zd bytes total), %zd good, %zd bad\n", Ntotal, Nbytes, Ngood, Nbad);
     236
    251237  return;
    252238}
     
    254240void ohana_memdump_func (int allmemory) {
    255241
    256   int i, Ns[4], N;
    257   char S[4];
    258 
    259   if (Nmemlist == 0) {
     242  if (!lastBlock) {
    260243    fprintf (stderr, "no memory allocated\n");
    261244    return;
    262245  }
    263246
    264   S[0] = 'A';
    265   S[1] = 'R';
    266   S[2] = 'F';
    267   S[3] = 'X';
    268   Ns[0] = Ns[1] = Ns[2] = Ns[3] = 0;
    269   N = 0;
    270 
    271   for (i = 0; i < Nmemlist; i++) {
    272     if (memlist[i].state == STATE_ALLOC)    N = 0;
    273     if (memlist[i].state == STATE_REALLOC)  N = 1;
    274     if (memlist[i].state == STATE_FREE)     N = 2;
    275     if (memlist[i].state == STATE_EXTERNAL) N = 2;
    276     Ns[N] ++;
    277     if ((allmemory == 0) && (memlist[i].state == STATE_FREE)) continue;
    278     if (memlist[i].state == STATE_EXTERNAL) {
    279       fprintf (stderr, "%3d %4d %lx : %lx - extern (extern     extern) %c %s %d\n",
    280                Ns[N], i, (long)memlist[i].ptr, (long)memlist[i].ptr,
    281                S[N], memlist[i].file, memlist[i].line);
     247  Memblock *thisBlock = lastBlock;
     248
     249  size_t Ntotal = 0;
     250  size_t Nbytes = 0;
     251
     252  fprintf (stderr, " entry | bytes | cumulative | STATUS | file | line | function\n");
     253
     254  while (thisBlock) {
     255
     256    int good = TRUE;
     257   
     258    if (thisBlock->startblock != OHANA_MEMMAGIC) good = FALSE;
     259    if (thisBlock->endblock != OHANA_MEMMAGIC) good = FALSE;
     260
     261    // pointer to the start of the user memory
     262    char *ptr = (char *)(thisBlock + 1) + thisBlock->size;
     263    uint32_t endpost = *(uint32_t *)ptr;
     264    if (endpost != OHANA_MEMMAGIC) good = FALSE;
     265
     266    // XXX keep checking even if memory is corrupted?
     267    Ntotal ++;
     268    Nbytes += thisBlock->size;
     269
     270    if (good) {
     271      fprintf (stderr, "  %zd  %zd  %zd  GOOD  %s %d, func: %s\n", Ntotal, thisBlock->size, Nbytes, thisBlock->file, thisBlock->line, thisBlock->func);
    282272    } else {
    283       fprintf (stderr, "%3d %4d %lx : %lx - %lx (%lx %lx) %c %s %d\n",
    284                Ns[N], i, (long)memlist[i].ptr, (long)(memlist[i].ptr - NMEMBYTE), (long)(memlist[i].ptr + memlist[i].size + NMEMBYTE),
    285                *(long *)(memlist[i].ptr - NMEMBYTE), *(long *)(memlist[i].ptr + memlist[i].size),
    286                S[N], memlist[i].file, memlist[i].line);
     273      fprintf (stderr, "  %zd  %zd  %zd  BAD   %s %d, func: %s\n", Ntotal, thisBlock->size, Nbytes, thisBlock->file, thisBlock->line, thisBlock->func);
    287274    }
    288   }
    289   fprintf (stderr, "Nused: %d (Nalloc: %d, Nrealloc: %d), Nfree: %d\n",
    290            Ns[0]+Ns[1], Ns[0], Ns[1], Ns[2]);
    291   return;
    292 }
    293 # endif
     275
     276    thisBlock = thisBlock->prevBlock;
     277  }
     278  return;
     279}
Note: See TracChangeset for help on using the changeset viewer.