int main (int argc, char *argv[]) { int i, j, b; bdescr *a[ARRSIZE]; srand(SEED); hs_init(&argc, &argv); // repeatedly sweep though the array, allocating new random-sized // objects and deallocating the old ones. for (i=0; i < LOOPS; i++) { for (j=0; j < ARRSIZE; j++) { if (i > 0) { IF_DEBUG(block_alloc, debugBelch("A%d: freeing %p, %d blocks @ %p\n", j, a[j], a[j]->blocks, a[j]->start)); freeGroup_lock(a[j]); DEBUG_ONLY(checkFreeListSanity()); } b = (rand() % MAXALLOC) + 1; a[j] = allocGroup_lock(b); IF_DEBUG(block_alloc, debugBelch("A%d: allocated %p, %d blocks @ %p\n", j, a[j], b, a[j]->start)); // allocating zero blocks isn't allowed DEBUG_ONLY(checkFreeListSanity()); } } for (j=0; j < ARRSIZE; j++) { freeGroup_lock(a[j]); } // this time, sweep forwards allocating new blocks, and then // backwards deallocating them. for (i=0; i < LOOPS; i++) { for (j=0; j < ARRSIZE; j++) { b = (rand() % MAXALLOC) + 1; a[j] = allocGroup_lock(b); IF_DEBUG(block_alloc, debugBelch("B%d,%d: allocated %p, %d blocks @ %p\n", i, j, a[j], b, a[j]->start)); DEBUG_ONLY(checkFreeListSanity()); } for (j=ARRSIZE-1; j >= 0; j--) { IF_DEBUG(block_alloc, debugBelch("B%d,%d: freeing %p, %d blocks @ %p\n", i, j, a[j], a[j]->blocks, a[j]->start)); freeGroup_lock(a[j]); DEBUG_ONLY(checkFreeListSanity()); } } DEBUG_ONLY(checkFreeListSanity()); hs_exit(); // will do a memory leak test exit(0); }
// Allocate some memory in an arena void * arenaAlloc( Arena *arena, size_t size ) { void *p; nat size_w; nat req_blocks; bdescr *bd; // round up to nearest alignment chunk. size = ROUNDUP(size,MIN_ALIGN); // size of allocated block in words. size_w = B_TO_W(size); if ( arena->free + size_w < arena->lim ) { // enough room in the current block... p = arena->free; arena->free += size_w; return p; } else { // allocate a fresh block... req_blocks = (W_)BLOCK_ROUND_UP(size) / BLOCK_SIZE; bd = allocGroup_lock(req_blocks); arena_blocks += req_blocks; bd->gen_no = 0; bd->gen = NULL; bd->dest_no = 0; bd->flags = 0; bd->free = bd->start; bd->link = arena->current; arena->current = bd; arena->free = bd->free + size_w; arena->lim = bd->free + bd->blocks * BLOCK_SIZE_W; return bd->start; } }
int main (int argc, char *argv[]) { int i, j, b; bdescr *a[ARRSIZE]; srand(SEED); hs_init(&argc, &argv); memset(a, 0, ARRSIZE * sizeof(bdescr*)); for (i=0; i < LOOPS; i++) { j = rand() % ARRSIZE; if (a[j]) { freeGroup_lock(a[j]); } a[j] = allocGroup_lock(rand() % MAXALLOC + 1); } #ifdef DEBUG { void *p; i = 0; for (p = getFirstMBlock(); p != NULL; p = getNextMBlock(p)) { if (!HEAP_ALLOCED(p)) barf("%p",p); i++; } printf("%d\n", i); } #endif { void *p, *base; j = 0; base = RtsFlags.GcFlags.heapBase; for (i=0; i < LOOPS*2000; i++) { // this is for testing: generate random addresses anywhere // in the address space. // // 48 bits is: 0x800000000000 - 0x7fffffffffff // so ((StgInt)rand() >> 4) varies between -2^27 and 2^27-1. // and << 20 of this is a random signed 48-bit megablock address // // p = (void*)((StgWord)((StgInt)rand() >> 4) << 20); // this is for benchmarking: roughly half of these // addresses will be in the heap. p = base + (((StgWord)rand() << 10) % ((StgWord)ARRSIZE * MAXALLOC * BLOCK_SIZE)); if (HEAP_ALLOCED(p)) { // printf("%p\n",p); j++; } } printf("%d\n", j); } printf("misses: %ld, %ld%%\n", mpc_misses, mpc_misses / (LOOPS*20)); for (i=0; i < ARRSIZE; i++) { if (a[i]) { freeGroup_lock(a[i]); } } hs_exit(); // will do a memory leak test exit(0); }