diff options
Diffstat (limited to 'rts/win32')
-rw-r--r-- | rts/win32/OSMem.c | 19 |
1 files changed, 14 insertions, 5 deletions
diff --git a/rts/win32/OSMem.c b/rts/win32/OSMem.c index c62ee3b7a4..57997b1ac5 100644 --- a/rts/win32/OSMem.c +++ b/rts/win32/OSMem.c @@ -144,8 +144,11 @@ findFreeBlocks(uint32_t n) { temp.next=free_blocks; temp.base=0; temp.size=0; prev=&temp; /* TODO: Don't just take first block, find smallest sufficient block */ - for( ; it!=0 && it->size<required_size; prev=it, it=it->next ) {} - if(it!=0) { + for ( ; it; prev=it, it=it->next ) + { + if (!it || it->size < required_size) + continue; + if( (((W_)it->base) & MBLOCK_MASK) == 0) { /* MBlock aligned */ ret = (void*)it->base; if(it->size==required_size) { @@ -155,24 +158,30 @@ findFreeBlocks(uint32_t n) { it->base += required_size; it->size -=required_size; } + break; } else { char* need_base; block_rec* next; int new_size; need_base = (char*)(((W_)it->base) & ((W_)~MBLOCK_MASK)) + MBLOCK_SIZE; + new_size = need_base - it->base; + /* Make sure that after alignment we have enough space. */ + W_ total_size = new_size + required_size; + if (total_size > it->size) + continue; 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); + next->size = it->size - total_size; it->size = new_size; next->next = it->next; it->next = next; ret=(void*)need_base; + break; } - } + } free_blocks=temp.next; return ret; } |