X-Git-Url: http://git.megacz.com/?p=ghc-hetmet.git;a=blobdiff_plain;f=rts%2FMBlock.c;h=85fe02da6e12a411b255e9194a8ce8e440f0a8b4;hp=e3acea8f486afa9ef65d9b24950d74e460fbd4bc;hb=9da4639011348fb6c318e3cba4b08622f811d9c4;hpb=83c42354f92a2cd23cadd6998156a51f61ab53ee diff --git a/rts/MBlock.c b/rts/MBlock.c index e3acea8..85fe02d 100644 --- a/rts/MBlock.c +++ b/rts/MBlock.c @@ -329,26 +329,27 @@ static block_rec* free_blocks = 0; static alloc_rec* allocNew(nat n) { - alloc_rec* rec = (alloc_rec*)malloc(sizeof(alloc_rec)); + alloc_rec* rec; + rec = (alloc_rec*)stgMallocBytes(sizeof(alloc_rec),"getMBlocks: allocNew"); rec->size = (n+1)*MBLOCK_SIZE; rec->base = VirtualAlloc(NULL, rec->size, MEM_RESERVE, PAGE_READWRITE); if(rec->base==0) { - free((void*)rec); + stgFree((void*)rec); rec=0; - errorBelch( - "getMBlocks: VirtualAlloc MEM_RESERVE %d blocks failed with: %ld\n" - , n, GetLastError()); + sysErrorBelch( + "getMBlocks: VirtualAlloc MEM_RESERVE %d blocks failed", n); } else { - if(allocs==0) { - allocs=rec; - rec->next=0; - } else { - alloc_rec* it=allocs; - for(; it->next!=0 && it->next->basebase; it=it->next) ; - rec->next=it->next; - it->next=rec; - } + alloc_rec temp; + temp.base=0; temp.size=0; temp.next=allocs; + + alloc_rec* it; + it=&temp; + for(; it->next!=0 && it->next->basebase; it=it->next) ; + rec->next=it->next; + it->next=rec; + + allocs=temp.next; debugTrace(DEBUG_gc, "allocated %d megablock(s) at 0x%x",n,(nat)rec->base); } return rec; @@ -358,17 +359,19 @@ static void insertFree(char* alloc_base, int alloc_size) { block_rec temp; - temp.base=0; temp.size=0; temp.next=free_blocks; + block_rec* it; + block_rec* prev; - block_rec* it = free_blocks; - block_rec* prev = &temp; - for( ; it!=0 && it->basenext) ; + temp.base=0; temp.size=0; temp.next=free_blocks; + it = free_blocks; + prev = &temp; + for( ; it!=0 && it->basenext) {} if(it!=0 && alloc_base+alloc_size == it->base) { if(prev->base + prev->size == alloc_base) { /* Merge it, alloc, prev */ prev->size += alloc_size + it->size; prev->next = it->next; - free(it); + stgFree(it); } else { /* Merge it, alloc */ it->base = alloc_base; it->size += alloc_size; @@ -376,8 +379,8 @@ insertFree(char* alloc_base, int alloc_size) { } else if(prev->base + prev->size == alloc_base) { /* Merge alloc, prev */ prev->size += alloc_size; } else { /* Merge none */ - block_rec* rec = (block_rec*)malloc(sizeof(block_rec)); - /* TODO: Check malloc failure */ + block_rec* rec; + rec = (block_rec*)stgMallocBytes(sizeof(block_rec),"getMBlocks: insertFree"); rec->base=alloc_base; rec->size=alloc_size; rec->next = it; @@ -390,28 +393,36 @@ static void* findFreeBlocks(nat n) { void* ret=0; - block_rec* it=free_blocks; - int required_size = n*MBLOCK_SIZE; - /* TODO: Don't just take first block, find smallest sufficient block */ + block_rec* it; block_rec temp; + block_rec* prev; + + int required_size; + it=free_blocks; + required_size = n*MBLOCK_SIZE; temp.next=free_blocks; temp.base=0; temp.size=0; - block_rec* prev=&temp; - for( ; it!=0 && it->sizenext ) ; + prev=&temp; + /* TODO: Don't just take first block, find smallest sufficient block */ + for( ; it!=0 && it->sizenext ) {} if(it!=0) { if( (((unsigned long)it->base) & MBLOCK_MASK) == 0) { /* MBlock aligned */ ret = (void*)it->base; if(it->size==required_size) { - prev->next=0; - free(it); + prev->next=it->next; + stgFree(it); } else { it->base += required_size; it->size -=required_size; } } else { - char* need_base = (char*)(((unsigned long)it->base) & ((unsigned long)~MBLOCK_MASK)) + MBLOCK_SIZE; - block_rec* next = (block_rec*)malloc(sizeof(block_rec)); - /* TODO: Check malloc failure */ - int new_size = need_base - it->base; + char* need_base; + block_rec* next; + int new_size; + need_base = (char*)(((unsigned long)it->base) & ((unsigned long)~MBLOCK_MASK)) + MBLOCK_SIZE; + next = (block_rec*)stgMallocBytes( + sizeof(block_rec) + , "getMBlocks: findFreeBlocks: splitting"); + new_size = need_base - it->base; next->base = need_base +required_size; next->size = it->size - (new_size+required_size); it->size = new_size; @@ -429,14 +440,19 @@ findFreeBlocks(nat n) { (ordered) allocated blocks. */ static void commitBlocks(char* base, int size) { - alloc_rec* it=allocs; - for( ; it!=0 && (it->base+it->size)next ) ; + alloc_rec* it; + it=allocs; + for( ; it!=0 && (it->base+it->size)<=base; it=it->next ) {} for( ; it!=0 && size>0; it=it->next ) { - int size_delta = it->size - (base-it->base); + int size_delta; + void* temp; + size_delta = it->size - (base-it->base); if(size_delta>size) size_delta=size; - void* temp = VirtualAlloc(base, size_delta, MEM_COMMIT, PAGE_READWRITE); - if(temp==0) - debugBelch("getMBlocks: VirtualAlloc MEM_COMMIT failed: %ld", GetLastError()); + temp = VirtualAlloc(base, size_delta, MEM_COMMIT, PAGE_READWRITE); + if(temp==0) { + sysErrorBelch("getMBlocks: VirtualAlloc MEM_COMMIT failed"); + stg_exit(EXIT_FAILURE); + } size-=size_delta; base+=size_delta; } @@ -444,28 +460,34 @@ commitBlocks(char* base, int size) { void * getMBlocks(nat n) { - void* ret=0; + void* ret; ret = findFreeBlocks(n); if(ret==0) { - alloc_rec* alloc = allocNew(n); + alloc_rec* alloc; + alloc = allocNew(n); /* We already belch in allocNew if it fails */ - if(alloc) { + if (alloc == 0) { + stg_exit(EXIT_FAILURE); + } else { insertFree(alloc->base, alloc->size); ret = findFreeBlocks(n); - } + } } if(ret!=0) { /* (In)sanity tests */ - if (((W_)ret & MBLOCK_MASK) != 0) barf("getMBlocks: misaligned block returned"); + if (((W_)ret & MBLOCK_MASK) != 0) { + barf("getMBlocks: misaligned block returned"); + } commitBlocks(ret, MBLOCK_SIZE*n); /* Global bookkeeping */ mblocks_allocated += n; - int i=0; - for(; i<(int)n; ++i) + int i; + for(i=0; i<(int)n; ++i) { markHeapAlloced( ret + i * MBLOCK_SIZE ); + } } return ret; @@ -475,24 +497,28 @@ void freeAllMBlocks(void) { { - block_rec* next = 0; - block_rec* it = free_blocks; + block_rec* next; + block_rec* it; + next=0; + it = free_blocks; for(; it!=0; ) { - if(!VirtualFree((void*)it->base, it->size, MEM_DECOMMIT)) - debugBelch("freeAllMBlocks: VirtualFree MEM_DECOMMIT failed with %ld", GetLastError()); next = it->next; - free(it); + stgFree(it); it=next; } } { - alloc_rec* next = 0; - alloc_rec* it = allocs; + alloc_rec* next; + alloc_rec* it; + next=0; + it=allocs; for(; it!=0; ) { - if(!VirtualFree((void*)it->base, 0, MEM_RELEASE)) - debugBelch("freeAllMBlocks: VirtualFree MEM_RELEASE failed with %ld", GetLastError()); + if(!VirtualFree((void*)it->base, 0, MEM_RELEASE)) { + sysErrorBelch("freeAllMBlocks: VirtualFree MEM_RELEASE failed"); + stg_exit(EXIT_FAILURE); + } next = it->next; - free(it); + stgFree(it); it=next; } }