Changeset 31589 for branches/eam_branches/ipp-20110505/Ohana
- Timestamp:
- May 31, 2011, 8:02:50 AM (15 years ago)
- Location:
- branches/eam_branches/ipp-20110505/Ohana/src/libohana
- Files:
-
- 3 edited
-
include/ohana.h (modified) (1 diff)
-
include/ohana_allocate.h (modified) (2 diffs)
-
src/ohana_allocate.c (modified) (8 diffs)
Legend:
- Unmodified
- Added
- Removed
-
branches/eam_branches/ipp-20110505/Ohana/src/libohana/include/ohana.h
r31160 r31589 19 19 # include <readline/readline.h> 20 20 21 # define OHANA_MEMORY 22 21 23 // XXX I was including these before, but RHL claims they are not needed 22 24 // # include <malloc.h> -
branches/eam_branches/ipp-20110505/Ohana/src/libohana/include/ohana_allocate.h
r30726 r31589 5 5 # ifdef OHANA_MEMORY 6 6 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); 7 void *ohana_malloc (char *file, int line, char *func, int Nelem, size_t esize); 8 void *ohana_realloc (char *file, int line, char *func, void *in, int Nelem, size_t esize); 9 void ohana_free (char *file, int line, char *func, void *in); 11 10 void ohana_memdump_func (int mode); 12 11 void ohana_memcheck_func (int mode); 13 12 14 # define ohana_memregister(X) ohana_memregister_func (__FILE__, __LINE__, (X));15 13 # define ohana_memcheck(X) ohana_memcheck_func (X); 16 14 # define ohana_memdump(X) ohana_memdump_func (X); 17 15 18 16 # 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)) } 20 18 # 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)); } 22 20 # 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)); } 24 22 # define CHECK_REALLOCATE(PTR,TYPE,SIZE,NCURR,DELTA) { \ 25 23 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); } } 28 26 # define free(PTR) { ohana_free(__FILE__, __LINE__, PTR); } 27 # define real_free(PTR) { if (PTR) { free(PTR); }} 29 28 30 # else 31 # define ohana_memregister(X) /* NOP */ 29 # else /* OHANA_MEMORY */ 30 32 31 # define ohana_memcheck(X) /* NOP */ 33 32 # define ohana_memdump(X) /* NOP */ 34 # endif /* OHANA_MEMORY */33 # define real_free(PTR) { if (PTR) { free(PTR); }} 35 34 36 35 # ifndef ALLOCATE … … 64 63 # define FREE(PTR) { if (PTR != NULL) { free (PTR); } } 65 64 # endif /* ALLOCATE */ 65 # endif /* OHANA_MEMORY */ 66 66 67 67 # endif /* OHANA_ALLOCATE */ -
branches/eam_branches/ipp-20110505/Ohana/src/libohana/src/ohana_allocate.c
r31588 r31589 2 2 # include <stdlib.h> 3 3 # include <stdarg.h> 4 # include <stdint.h> 5 # include <pthread.h> 4 6 5 7 /* need an internal version that does not use ohana_memory functions */ … … 7 9 # define TRUE 1 8 10 # 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 029 # define STATE_REALLOC 130 # define STATE_FREE 231 # define STATE_EXTERNAL 332 11 33 12 # define OHANA_MEMMAGIC (uint32_t) 0xdeadbeef 34 13 35 14 typedef 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 44 23 } Memblock; 45 24 46 static Memblock *last MemBlock = NULL;25 static Memblock *lastBlock = NULL; 47 26 48 27 static pthread_mutex_t memBlockListMutex = PTHREAD_MUTEX_INITIALIZER; … … 61 40 } 62 41 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;42 void *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) 68 47 69 48 Nelem = MAX (1, Nelem); 70 49 size = Nelem * esize; 71 50 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 76 59 new->startblock = OHANA_MEMMAGIC; 77 60 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; 84 65 new->file = file; 66 new->line = line; 85 67 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 91 71 // new->prev = (new - 1) 92 72 // (new - 1)->next = new 93 73 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 94 80 new->nextBlock = NULL; 95 81 82 // protect the list during this operation 96 83 pthread_mutex_lock(&memBlockListMutex); 97 84 98 if (last MemBlock) {99 last MemBlock->nextBlock = new;100 } 101 new->prevBlock = last MemBlock;102 last MemBlock = new;85 if (lastBlock) { 86 lastBlock->nextBlock = new; 87 } 88 new->prevBlock = lastBlock; 89 lastBlock = new; 103 90 104 91 pthread_mutex_unlock(&memBlockListMutex); … … 107 94 } 108 95 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 96 void *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 115 104 if (!in) { 116 ptr = ohana_ alloc (file, line, Nelem, esize);105 ptr = ohana_malloc (file, line, func, Nelem, esize); 117 106 return ptr; 118 107 } 119 108 120 ref = ((Memblock *)in) - 1; 109 // memblock of supplied pointer 110 old = (Memblock *) in - 1; 121 111 122 112 Nelem = MAX (1, Nelem); … … 124 114 125 115 // requested same size as current allocation 126 if (size == ref->size) {127 return ptr;116 if (size == old->size) { 117 return in; 128 118 } 129 119 130 120 pthread_mutex_lock(&memBlockListMutex); 131 121 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? 161 void 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 132 171 Memblock *nextBlock = ref->nextBlock; 133 172 Memblock *prevBlock = ref->prevBlock; 134 173 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 175 174 if (nextBlock) { 176 175 nextBlock->prevBlock = prevBlock; … … 179 178 prevBlock->nextBlock = nextBlock; 180 179 } 181 if (last MemBlock == ref) {182 last MemBlock = prevBlock;180 if (lastBlock == ref) { 181 lastBlock = prevBlock; 183 182 } 184 183 … … 190 189 } 191 190 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)200 191 void ohana_memcheck_func (int allmemory) { 201 192 202 int i, j, next, prev, header; 203 size_t *marker; 204 char top, bottom; 205 206 if (Nmemlist == 0) { 193 if (!lastBlock) { 207 194 fprintf (stderr, "no memory allocated\n"); 208 195 return; 209 196 } 210 197 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; 222 208 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 ++; 227 228 } 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 251 237 return; 252 238 } … … 254 240 void ohana_memdump_func (int allmemory) { 255 241 256 int i, Ns[4], N; 257 char S[4]; 258 259 if (Nmemlist == 0) { 242 if (!lastBlock) { 260 243 fprintf (stderr, "no memory allocated\n"); 261 244 return; 262 245 } 263 246 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); 282 272 } 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); 287 274 } 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.
