#include <memblk.h>
Definition at line 118 of file memblk.h.
void * MEM_ALLOCATOR::alloc | ( | INT32 | size, | |
void * | caller | |||
) |
Return a pointer to a buffer of count bytes aligned for any type.
Definition at line 543 of file memblk.cpp.
References ABORT, MEMUNION::age, biggestblock, MEMBLOCK::blockend, MEMBLOCK::blockstart, check_mem(), currblock, ERRCODE::error(), MEMBLOCK::find_chunk(), MEMBLOCK::freechunk, MEMBLOCK::lowerspace, MEMCHECKS, MEMTOOBIG, new_block(), MEMBLOCK::next, NULL, MEMUNION::owner, set_owner(), MEMUNION::size, topblock, MEMBLOCK::topchunk, totalmem, and MEMBLOCK::upperspace.
Referenced by alloc_big_mem(), alloc_big_zeros(), alloc_mem(), and alloc_p().
00546 { 00547 MEMBLOCK *block; //current block 00548 MEMUNION *chunk; //current chunk 00549 INT32 chunksize; //size of free chunk 00550 MEMUNION *chunkstart; //start of free chunk 00551 00552 if (count < 1 || count > biggestblock) 00553 MEMTOOBIG.error ("alloc_mem", ABORT, "%d", (int) count); 00554 //request too big 00555 00556 count += sizeof (MEMUNION) - 1;//round up to word 00557 count /= sizeof (MEMUNION); 00558 count++; //and add one 00559 if (currblock == NULL) { 00560 //get first block 00561 currblock = new_block (count); 00562 topblock = currblock; 00563 if (currblock == NULL) { 00564 check_mem ("alloc_mem returning NULL", MEMCHECKS); 00565 return NULL; 00566 } 00567 } 00568 block = currblock; //current block 00569 if (block->upperspace <= block->lowerspace) { 00570 //restart chunklist 00571 block->freechunk = block->blockstart; 00572 block->upperspace += block->lowerspace; 00573 block->lowerspace = 0; //correct space counts 00574 } 00575 chunk = block->freechunk; //current free chunk 00576 if (chunk->size < count) { //big enough? 00577 do { 00578 //search for free chunk 00579 chunk = block->find_chunk (count); 00580 if (chunk->size < count) 00581 block = block->next; //try next block 00582 } 00583 //until all tried 00584 while (chunk->size < count && block != currblock); 00585 if (chunk->size < count) { //still no good 00586 //get a new block 00587 currblock = new_block (count); 00588 topblock = currblock; //set perms here too 00589 if (currblock == NULL) { 00590 check_mem ("alloc_mem returning NULL", MEMCHECKS); 00591 return NULL; 00592 } 00593 block = currblock; 00594 chunk = block->freechunk; //bound to be big enough 00595 } 00596 } 00597 chunkstart = chunk; //start of chunk 00598 if (chunk == block->topchunk && chunk + count != block->blockend) 00599 block->topchunk += count; //top has moved 00600 block->upperspace -= count; //upper part used 00601 chunksize = chunk->size; //size of free chunk 00602 chunk->size = -count; //mark as used 00603 chunk += count; //next free space 00604 totalmem -= count; //no of free elements 00605 if (chunksize > count) //bigger than exact? 00606 //remaining space 00607 chunk->size = chunksize - count; 00608 else if (chunk == block->blockend) { 00609 chunk = block->blockstart; //restart block 00610 block->upperspace = block->lowerspace; 00611 block->lowerspace = 0; //fix space counts 00612 } 00613 block->freechunk = chunk; //next free block 00614 if (mem_mallocdepth > 0) { 00615 set_owner(chunkstart, caller); 00616 } 00617 else { 00618 chunkstart->owner = 0; 00619 chunkstart->age = 0; 00620 } 00621 chunkstart++; //start of block 00622 return chunkstart; //pointer to block 00623 }
void * MEM_ALLOCATOR::alloc_p | ( | INT32 | count, | |
void * | caller | |||
) |
Allocate permanent space which will never be returned.
This space is allocated from the top end of a memory block to avoid the fragmentation which would result from alternate use of alloc_mem for permanent and temporary blocks.
Definition at line 485 of file memblk.cpp.
References ABORT, MEMUNION::age, alloc(), biggestblock, check_mem(), currblock, ERRCODE::error(), MEMCHECKS, MEMTOOBIG, new_block(), MEMBLOCK::next, NULL, MEMUNION::owner, set_owner(), MEMUNION::size, topblock, MEMBLOCK::topchunk, and MEMBLOCK::upperspace.
Referenced by alloc_mem_p().
00488 { 00489 MEMBLOCK *block; //current block 00490 MEMUNION *chunk; //current chunk 00491 00492 if (count < 1 || count > biggestblock) 00493 //request too big 00494 MEMTOOBIG.error ("alloc_mem_p", ABORT, "%d", (int) count); 00495 00496 count += sizeof (MEMUNION) - 1;//round up to word 00497 count /= sizeof (MEMUNION); 00498 count++; //and add one 00499 if (topblock == NULL) { 00500 topblock = new_block (count);//get first block 00501 currblock = topblock; 00502 if (topblock == NULL) { 00503 check_mem ("alloc_mem_p returning NULL", MEMCHECKS); 00504 return NULL; 00505 } 00506 } 00507 block = topblock; //current block 00508 do { 00509 chunk = block->topchunk; 00510 if (chunk->size < count) 00511 block = block->next; //try next block 00512 } 00513 //until all tried 00514 while (chunk->size < count && block != topblock); 00515 if (chunk->size < count) { //still no good 00516 chunk = (MEMUNION *) alloc ((count - 1) * sizeof (MEMUNION), caller); 00517 //try last resort 00518 if (chunk != NULL) 00519 return chunk; 00520 check_mem ("alloc_mem_p returning NULL", MEMCHECKS); 00521 return NULL; 00522 } 00523 block->upperspace -= count; //less above freechunk 00524 if (chunk->size > count) { 00525 chunk->size -= count; 00526 chunk += chunk->size; 00527 } 00528 chunk->size = -count; //mark as in use 00529 if (mem_mallocdepth > 0) { 00530 set_owner(chunk, caller); 00531 } 00532 else { 00533 chunk->owner = 0; 00534 chunk->age = 0; 00535 } 00536 return chunk + 1; //created chunk 00537 }
void MEM_ALLOCATOR::check | ( | const char * | string, | |
INT8 | level | |||
) |
Check consistency of all memory controlled by this allocator.
Definition at line 371 of file memblk.cpp.
References ABORT, MEMUNION::age, BADMEMCHUNKS, blockcount, MEMBLOCK::blockend, MEMBLOCK::blockstart, ERRCODE::error(), FULLMEMCHECKS, MEMBLOCK::lowerspace, memblocks, MEMCHECKS, NULL, MEMUNION::owner, MEMUNION::size, MEMBLOCK::topchunk, tprintf(), and MEMBLOCK::upperspace.
Referenced by check_mem().
00374 { 00375 MEMBLOCK *block; //current block 00376 MEMUNION *chunk; //current chunk 00377 MEMUNION *prevchunk; //previous chunk 00378 INT32 chunksize; //size of chunk 00379 INT32 usedcount; //no of used chunks 00380 INT32 usedsize; //size of used chunks 00381 INT32 freecount; //no of free chunks 00382 INT32 freesize; //size of free chunks 00383 INT32 biggest; //biggest free chunk 00384 INT32 totusedcount; //no of used chunks 00385 INT32 totusedsize; //size of used chunks 00386 INT32 totfreecount; //no of free chunks 00387 INT32 totfreesize; //size of free chunks 00388 INT32 totbiggest; //biggest free chunk 00389 INT32 totblocksize; //total size of blocks 00390 INT32 chunkindex; //index of chunk 00391 INT32 blockindex; //index of block 00392 00393 if (level >= MEMCHECKS) 00394 tprintf ("\nMEM_ALLOCATOR::check:at '%s'\n", string); 00395 totusedcount = 0; //grand totals 00396 totusedsize = 0; 00397 totfreecount = 0; 00398 totfreesize = 0; 00399 totbiggest = 0; 00400 totblocksize = 0; 00401 for (blockindex = 0; blockindex < blockcount; blockindex++) { 00402 //current block 00403 block = &memblocks[blockindex]; 00404 if (level >= MEMCHECKS) 00405 tprintf ("Block %d:0x%x-0x%x, size=%d, top=0x%x, l=%d, u=%d\n", 00406 blockindex, block->blockstart, block->blockend, 00407 (block->blockend - block->blockstart) * sizeof (MEMUNION), 00408 block->topchunk, block->lowerspace, block->upperspace); 00409 usedcount = usedsize = 0; //zero counters 00410 freecount = freesize = 0; //zero counters 00411 biggest = 0; 00412 //scan all chunks 00413 for (chunkindex = 0, prevchunk = NULL, chunk = block->blockstart; chunk != block->blockend; chunkindex++, chunk += chunksize) { 00414 chunksize = chunk->size; //size of chunk 00415 if (chunksize < 0) 00416 chunksize = -chunksize; //absolute size 00417 if (level >= FULLMEMCHECKS) { 00418 tprintf ("%5d=%8d%c caller=%d, age=%d ", (int) chunkindex, 00419 chunksize * sizeof (MEMUNION), 00420 chunk->size < 0 ? 'U' : 'F', chunk->owner, chunk->age); 00421 if (chunkindex % 5 == 4) 00422 tprintf ("\n"); 00423 } 00424 //illegal sizes 00425 if (chunksize == 0 || chunk->size == -1 00426 //out of bounds 00427 || chunk + chunksize - block->blockstart <= 0 || block->blockend - (chunk + chunksize) < 0) 00428 BADMEMCHUNKS.error ("check_mem", ABORT, 00429 "Block=%p, Prev chunk=%p, Chunk=%p, Size=%x", 00430 block, prevchunk, chunk, 00431 (int) chunk->size); 00432 00433 else if (chunk->size < 0) { 00434 usedcount++; //used block 00435 usedsize += chunksize; 00436 } 00437 else { 00438 freecount++; //free block 00439 freesize += chunksize; 00440 if (chunksize > biggest) 00441 biggest = chunksize; 00442 } 00443 prevchunk = chunk; 00444 } 00445 if (level >= MEMCHECKS) { 00446 if (level >= FULLMEMCHECKS) 00447 tprintf ("\n"); 00448 tprintf ("%d chunks in use, total size=%d bytes\n", 00449 (int) usedcount, usedsize * sizeof (MEMUNION)); 00450 tprintf ("%d chunks free, total size=%d bytes\n", 00451 (int) freecount, freesize * sizeof (MEMUNION)); 00452 tprintf ("Largest free fragment=%d bytes\n", 00453 biggest * sizeof (MEMUNION)); 00454 } 00455 totusedcount += usedcount; //grand totals 00456 totusedsize += usedsize; 00457 totfreecount += freecount; 00458 totfreesize += freesize; 00459 if (biggest > totbiggest) 00460 totbiggest = biggest; 00461 totblocksize += block->blockend - block->blockstart; 00462 } 00463 if (level >= MEMCHECKS) { 00464 tprintf ("%d total blocks in use, total size=%d bytes\n", 00465 blockcount, totblocksize * sizeof (MEMUNION)); 00466 tprintf ("%d total chunks in use, total size=%d bytes\n", 00467 (int) totusedcount, totusedsize * sizeof (MEMUNION)); 00468 tprintf ("%d total chunks free, total size=%d bytes\n", 00469 (int) totfreecount, totfreesize * sizeof (MEMUNION)); 00470 tprintf ("Largest free fragment=%d bytes\n", 00471 totbiggest * sizeof (MEMUNION)); 00472 } 00473 if (level >= MEMCHECKS) 00474 display_counts(); 00475 }
void MEM_ALLOCATOR::dealloc | ( | void * | oldchunk, | |
void * | caller | |||
) |
Free a block allocated by alloc (or alloc_p).
It checks that the pointer is legal and maintains counts of the amount of free memory above and below the current free pointer.
Definition at line 665 of file memblk.cpp.
References ABORT, MEMBLOCK::blockend, MEMBLOCK::blockstart, callers, MALLOC_CALL::count_freeer(), currblock, ERRCODE::error(), MEMBLOCK::freechunk, FREEFREEDBLOCK, FREEILLEGALPTR, FREENULLPTR, MEMBLOCK::lowerspace, MEMBLOCK::next, NOTMALLOCMEM, NULL, MEMUNION::owner, MEMUNION::size, totalmem, and MEMBLOCK::upperspace.
Referenced by free_big_mem(), and free_mem().
00668 { 00669 MEMUNION *chunk; //current chunk 00670 MEMBLOCK *block; //current block 00671 00672 if (oldchunk == NULL) 00673 FREENULLPTR.error ("free_mem", ABORT, NULL); 00674 chunk = (MEMUNION *) oldchunk; 00675 block = currblock; //current block 00676 if (block == NULL) 00677 NOTMALLOCMEM.error ("free_mem", ABORT, NULL); 00678 do { 00679 block = block->next; 00680 } 00681 //outside the block 00682 while ((chunk - block->blockstart < 0 || block->blockend - chunk <= 0) 00683 && block != currblock); 00684 00685 if (chunk - block->blockstart < 0 || block->blockend - chunk <= 0) 00686 //in no block 00687 NOTMALLOCMEM.error ("free_mem", ABORT, NULL); 00688 00689 chunk--; //point to size 00690 if (chunk->size == 0) 00691 //zero size 00692 FREEILLEGALPTR.error ("free_mem", ABORT, NULL); 00693 else if (chunk->size > 0) 00694 //already free 00695 FREEFREEDBLOCK.error ("free_mem", ABORT, NULL); 00696 chunk->size = -chunk->size; //mark it free 00697 if (mem_freedepth > 0 && callers != NULL) { 00698 //count calls 00699 callers[chunk->owner].count_freeer (caller); 00700 } 00701 totalmem += chunk->size; //total free memory 00702 if (chunk - block->freechunk < 0) 00703 //extra below 00704 block->lowerspace += chunk->size; 00705 else 00706 //extra above 00707 block->upperspace += chunk->size; 00708 }
void MEM_ALLOCATOR::display_counts | ( | ) |
Send counts of outstanding blocks to stderr.
Definition at line 248 of file memblk.cpp.
References MEMUNION::age, blockcount, MEMBLOCK::blockend, MEMBLOCK::blockstart, callers, check_mem(), MALLOC_CALL::counts, entries, JUSTCHECKS, malloc, malloc_div_ratio, malloc_serial, memblocks, NULL, MEMUNION::owner, MEMUNION::size, MEMBLOCK::topchunk, and tprintf().
00248 { //count up 00249 MEMBLOCK *block; //current block 00250 MEMUNION *chunk; //current chunk 00251 INT32 chunksize; //size of chunk 00252 INT32 blockindex; //index of block 00253 INT32 buckets; //required buckets 00254 INT32 bucketsize; //no in each bucket 00255 INT32 callindex; //index to callers 00256 INT32 freeindex; //index to freeers 00257 INT32 freeentries; //table size 00258 INT32 totalchunks; //total chunk counts 00259 INT32 totalspace; //total mem space 00260 INT32 totalpchunks; //permanent chunks 00261 INT32 totalpspace; //permanent space 00262 INT32 totalfrees; //total free calls 00263 00264 if (callers == NULL) 00265 return; //can't do anything 00266 check_mem ("Displaying counts", JUSTCHECKS); 00267 buckets = mem_countbuckets; 00268 bucketsize = (malloc_serial - 1) / buckets + 1; 00269 tprintf ("\nEach bucket covers %g counts.\n", 00270 (double) bucketsize * malloc_div_ratio); 00271 for (callindex = 0; callindex < entries; callindex++) { 00272 if (callers[callindex].free_list != NULL) { 00273 callers[callindex].counts = 00274 (INT32 *) malloc (buckets * 4 * sizeof (INT32)); 00275 memset (callers[callindex].counts, 0, 00276 (size_t) (buckets * 4 * sizeof (INT32))); 00277 } 00278 } 00279 for (blockindex = 0; blockindex < blockcount; blockindex++) { 00280 //current block 00281 block = &memblocks[blockindex]; 00282 //scan all chunks 00283 for (chunk = block->blockstart; chunk != block->topchunk; chunk += chunksize) { 00284 chunksize = chunk->size; //size of chunk 00285 if (chunksize < 0) { 00286 chunksize = -chunksize; //absolute size 00287 callindex = chunk->owner; 00288 if (callers[callindex].counts != NULL) { 00289 callers[callindex].counts[chunk->age / bucketsize * 4]++; 00290 callers[callindex].counts[chunk->age / bucketsize * 4 + 00291 1] += chunksize; 00292 } 00293 } 00294 } 00295 //scan all chunks 00296 for (; chunk != block->blockend; chunk += chunksize) { 00297 chunksize = chunk->size; //size of chunk 00298 if (chunksize < 0) { 00299 chunksize = -chunksize; //absolute size 00300 callindex = chunk->owner; 00301 if (callers[callindex].counts != NULL) { 00302 callers[callindex].counts[chunk->age / bucketsize * 4 + 00303 2]++; 00304 callers[callindex].counts[chunk->age / bucketsize * 4 + 00305 3] += chunksize; 00306 } 00307 } 00308 } 00309 } 00310 for (callindex = 0; callindex < entries; callindex++) { 00311 if (callers[callindex].counts != NULL) { 00312 for (totalspace = 0, totalchunks = 0, totalpspace = 00313 0, totalpchunks = 0, freeindex = 0; freeindex < buckets; 00314 freeindex++) { 00315 totalchunks += callers[callindex].counts[freeindex * 4]; 00316 totalspace += callers[callindex].counts[freeindex * 4 + 1]; 00317 totalpchunks += callers[callindex].counts[freeindex * 4 + 2]; 00318 totalpspace += callers[callindex].counts[freeindex * 4 + 3]; 00319 } 00320 freeentries = 1 << callers[callindex].free_bits; 00321 for (totalfrees = 0, freeindex = 0; freeindex < freeentries; 00322 freeindex++) 00323 totalfrees += callers[callindex].free_list[freeindex].count; 00324 if (totalspace != 0 || totalfrees != 0) { 00325 tprintf ("alloc_mem at %d : total held=%d(%d), frees=%d.\n", 00326 callers[callindex].caller, 00327 totalchunks, totalspace * sizeof (MEMUNION), 00328 totalfrees); 00329 } 00330 if (totalspace > 0) { 00331 for (freeindex = 0; freeindex < buckets; freeindex++) { 00332 tprintf ("%d(%d) ", 00333 callers[callindex].counts[freeindex * 4], 00334 callers[callindex].counts[freeindex * 4 + 00335 1] * sizeof (MEMUNION)); 00336 } 00337 tprintf ("\n"); 00338 } 00339 if (totalfrees != 0) { 00340 tprintf ("Calls to free : "); 00341 for (freeindex = 0; freeindex < freeentries; freeindex++) { 00342 if (callers[callindex].free_list[freeindex].count != 0) 00343 tprintf ("%d : %d ", 00344 callers[callindex].free_list[freeindex].freeer, 00345 callers[callindex].free_list[freeindex].count); 00346 } 00347 tprintf ("\n"); 00348 } 00349 if (totalpspace != 0) { 00350 tprintf ("alloc_mem_p at %d : total held=%d(%d).\n", 00351 callers[callindex].caller, 00352 totalpchunks, totalpspace * sizeof (MEMUNION)); 00353 for (freeindex = 0; freeindex < buckets; freeindex++) { 00354 tprintf ("%d(%d) ", 00355 callers[callindex].counts[freeindex * 4 + 2], 00356 callers[callindex].counts[freeindex * 4 + 00357 3] * sizeof (MEMUNION)); 00358 } 00359 tprintf ("\n"); 00360 } 00361 free (callers[callindex].counts); 00362 callers[callindex].counts = NULL; 00363 } 00364 } 00365 }
UINT16 MEM_ALLOCATOR::hash_caller | ( | void * | addr | ) |
Generate a hash code for a caller, setup the tables if necessary.
Definition at line 117 of file memblk.cpp.
References call_bits, MALLOC_CALL::caller, callers, entries, hash(), init_callers(), MALLOC_CALL::init_freeers(), and NULL.
Referenced by set_owner().
00119 { 00120 INT32 index; //index to table 00121 INT32 initial_hash; //initial index 00122 00123 if (callers == NULL) 00124 init_callers(); //setup table 00125 //get hash code 00126 initial_hash = hash (call_bits, &addr, sizeof (addr)); 00127 if (initial_hash == 0) 00128 initial_hash = 1; 00129 index = initial_hash; 00130 if (callers[index].caller != NULL && callers[index].caller != addr) { 00131 do { 00132 index++; 00133 if (index >= entries) 00134 index = 1; 00135 } 00136 while (callers[index].caller != NULL 00137 && callers[index].caller != addr && index != initial_hash); 00138 if (index == initial_hash) 00139 index = 0; 00140 } 00141 if (callers[index].caller == NULL) { 00142 if (index != 0) 00143 callers[index].caller = addr; 00144 if (callers[index].free_list == NULL) 00145 //setup free table 00146 callers[index].init_freeers (); 00147 } 00148 return (UINT16) index; 00149 }
void MEM_ALLOCATOR::init | ( | void *(*)(INT32) | ext_malloc, | |
void(*)(void *) | ext_free, | |||
INT32 | firstsize, | |||
INT32 | lastsize, | |||
INT32 | maxchunk | |||
) |
Constructor for a memory allocator.
Definition at line 88 of file memblk.cpp.
References biggestblock, blockcount, call_bits, callers, currblock, entries, free, malloc, malloc_auto_count, malloc_div_ratio, malloc_minor_serial, malloc_serial, maxsize, memsize, NULL, topblock, and totalmem.
Referenced by alloc_big_mem(), alloc_big_zeros(), alloc_mem(), and alloc_mem_p().
00094 { 00095 blockcount = 0; 00096 malloc_serial = 0; 00097 topblock = NULL; 00098 currblock = NULL; 00099 callers = NULL; 00100 malloc = ext_malloc; 00101 free = ext_free; 00102 maxsize = lastsize; 00103 biggestblock = maxchunk; 00104 totalmem = 0; 00105 memsize = firstsize; 00106 malloc_div_ratio = 1; 00107 malloc_minor_serial = 0; 00108 malloc_auto_count = 0; 00109 call_bits = 0; 00110 entries = 0; 00111 }
void MEM_ALLOCATOR::init_callers | ( | ) | [private] |
Initialize the callers hash table.
Definition at line 193 of file memblk.cpp.
References call_bits, callers, and entries.
Referenced by hash_caller().
00193 { //setup hash table 00194 INT32 depth = mem_mallocdepth; 00195 00196 mem_mallocdepth.set_value (0); //can't register it 00197 call_bits = mem_mallocbits; 00198 entries = 1 << call_bits; 00199 //make an array 00200 callers = new MALLOC_CALL[entries]; 00201 mem_mallocdepth.set_value (depth); 00202 }
Gets a new big block of memory from malloc for use by alloc_mem.
Definition at line 714 of file memblk.cpp.
References MEMUNION::age, blockcount, MEMBLOCK::blockend, MEMBLOCK::blockstart, check_mem(), currblock, ERRCODE::error(), MEMBLOCK::freechunk, LOG, MEMBLOCK::lowerspace, malloc, MAXBLOCKS, maxsize, memblocks, MEMCHECKS, memsize, MEMBLOCK::next, NOMOREBLOCKS, NOMOREMEM, NULL, MEMUNION::owner, MEMUNION::size, MEMBLOCK::topchunk, totalmem, tprintf(), trace_caller(), and MEMBLOCK::upperspace.
Referenced by alloc(), and alloc_p().
00716 { 00717 MEMBLOCK *newblock; //new block 00718 00719 if (blockcount >= MAXBLOCKS) { 00720 //can't have another 00721 NOMOREBLOCKS.error ("mem_new_block", LOG, NULL); 00722 return NULL; 00723 } 00724 if (mem_checkfreq != 0) { 00725 tprintf ("\nGetting new block due to request size of %d", 00726 minsize * sizeof (MEMUNION)); 00727 tprintf (" from %d from %d from %d from %d from %d\n", 00728 trace_caller (3), trace_caller (4), trace_caller (5), 00729 trace_caller (6), trace_caller (7)); 00730 check_mem ("Getting new block", MEMCHECKS); 00731 } 00732 //get a new one 00733 newblock = &memblocks[blockcount++]; 00734 while (memsize < minsize) 00735 memsize *= 4; //go up in sizes 00736 //get a big block 00737 newblock->blockstart = (MEMUNION *) 00738 malloc (memsize * sizeof (MEMUNION)); 00739 if (newblock->blockstart == NULL) { 00740 NOMOREMEM.error ("mem_new_block", LOG, NULL); 00741 00742 #ifdef __UNIX__ 00743 raise(SIGTTOU); //hangup for js 00744 #endif 00745 return NULL; 00746 } 00747 //end of block 00748 newblock->blockend = newblock->blockstart + memsize; 00749 //first free chunk 00750 newblock->freechunk = newblock->blockstart; 00751 newblock->topchunk = newblock->blockstart; 00752 newblock->lowerspace = 0; 00753 newblock->upperspace = memsize;//amount available 00754 //set pointer 00755 newblock->freechunk->size = memsize; 00756 newblock->freechunk->owner = 0; 00757 newblock->freechunk->age = 0; 00758 00759 totalmem += memsize; //total assigned mem 00760 00761 if (memsize < maxsize) 00762 memsize *= 4; //successively bigger 00763 if (currblock == NULL) { 00764 newblock->next = newblock; //first block 00765 } 00766 else { 00767 //insert in list 00768 newblock->next = currblock->next; 00769 currblock->next = newblock; 00770 } 00771 return newblock; //new block 00772 }
void MEM_ALLOCATOR::reduce_counts | ( | ) |
Divide all ages by 2 to get a log use of counts.
Definition at line 224 of file memblk.cpp.
References MEMUNION::age, blockcount, MEMBLOCK::blockend, MEMBLOCK::blockstart, check_mem(), JUSTCHECKS, memblocks, and MEMUNION::size.
Referenced by set_owner().
00224 { //divide by 2 00225 MEMBLOCK *block; //current block 00226 MEMUNION *chunk; //current chunk 00227 INT32 chunksize; //size of chunk 00228 INT32 blockindex; //index of block 00229 00230 check_mem ("Reducing counts", JUSTCHECKS); 00231 for (blockindex = 0; blockindex < blockcount; blockindex++) { 00232 //current block 00233 block = &memblocks[blockindex]; 00234 //scan all chunks 00235 for (chunk = block->blockstart; chunk != block->blockend; chunk += chunksize) { 00236 chunksize = chunk->size; //size of chunk 00237 if (chunksize < 0) 00238 chunksize = -chunksize; //absolute size 00239 chunk->age /= 2; //divide ages 00240 } 00241 } 00242 }
void MEM_ALLOCATOR::set_owner | ( | MEMUNION * | chunkstart, | |
void * | caller | |||
) | [private] |
Set the owner and time stamp of the block and check if needed.
Definition at line 629 of file memblk.cpp.
References MEMUNION::age, check_mem(), hash_caller(), malloc_auto_count, malloc_div_ratio, malloc_minor_serial, malloc_serial, MAX_INT16, MEMCHECKS, MEMUNION::owner, and reduce_counts().
Referenced by alloc(), and alloc_p().
00632 { 00633 UINT16 callindex; //hash code 00634 00635 callindex = hash_caller (caller); 00636 chunkstart->owner = callindex; 00637 //store evidence 00638 chunkstart->age = malloc_serial; 00639 malloc_minor_serial++; 00640 if (malloc_minor_serial >= malloc_div_ratio) { 00641 malloc_minor_serial = 0; 00642 malloc_serial++; //count calls 00643 if (malloc_serial == 0) { 00644 //wrap around 00645 reduce_counts(); //fix serial numbers 00646 malloc_serial = MAX_INT16 + 1; 00647 //all worth double 00648 malloc_div_ratio += malloc_div_ratio; 00649 } 00650 } 00651 malloc_auto_count++; 00652 if (mem_checkfreq > 0 && malloc_auto_count >= (UINT32) mem_checkfreq) { 00653 malloc_auto_count = 0; 00654 check_mem ("Auto check", MEMCHECKS); 00655 } 00656 }
Definition at line 129 of file memblk.h.
Referenced by alloc(), alloc_big_mem(), alloc_big_zeros(), alloc_mem(), alloc_mem_p(), alloc_p(), and init().
Definition at line 121 of file memblk.h.
Referenced by check(), display_counts(), init(), new_block(), and reduce_counts().
Definition at line 125 of file memblk.h.
Referenced by dealloc(), display_counts(), free_big_mem(), free_mem(), hash_caller(), init(), and init_callers().
Definition at line 136 of file memblk.h.
Referenced by display_counts(), hash_caller(), init(), and init_callers().
void(* MEM_ALLOCATOR::free)(void *) |
Referenced by init().
void*(* MEM_ALLOCATOR::malloc)(INT32) |
Referenced by display_counts(), init(), and new_block().
MEMBLOCK MEM_ALLOCATOR::memblocks[MAXBLOCKS] |
Definition at line 138 of file memblk.h.
Referenced by check(), display_counts(), new_block(), and reduce_counts().