/*** *heapsrch.c - search the heap for a free block * * Copyright (c) 1989-1997, Microsoft Corporation. All rights reserved. * *Purpose: * Defines the _heap_search() function. * *******************************************************************************/ #ifndef WINHEAP #include #include #include #define LOOP_FOREVER while(1) /*** *_PBLKDESC _heap_search(unsigned size) - Find a free block of a least size * bytes. * *Purpose: * Finds a free block of at least size bytes. Searches the list of block * descriptors from *proverdesc to the end (marked by the sentinel). The * search is strictly first fit. Adjacent free blocks are coalesced as * they are encountered during the search. * *Entry: * unsigned size - size of block requested * *Exit: * Success: Pointer to descriptor for free memory block of at least size * bytes * Failure: NULL * *Uses: * *Exceptions: * *******************************************************************************/ _PBLKDESC __cdecl _heap_search ( unsigned size ) { REG1 _PBLKDESC pdesc; REG2 _PBLKDESC pdesc2; _PBLKDESC pretdesc = NULL; /* search from proverdesc thru plastdesc, looking for free block of * at least size bytes. coalesce adjacent free blocks during the * search. the search is strictly first fit. that is, it terminates * when the first block is found of adequate size. */ for ( pdesc = _heap_desc.proverdesc ; pdesc != &(_heap_desc.sentinel) ; pdesc = pdesc->pnextdesc ) /* is pdesc free? */ if ( _IS_FREE(pdesc) ) /* coalesce loop */ LOOP_FOREVER { /* if pdesc is big enough, return it */ if ( _BLKSIZE(pdesc) >= size ) { pretdesc = pdesc; goto searchdone; } /* see if the next block is free and, if so, * coalesce it with pdesc */ pdesc2 = pdesc->pnextdesc; if ( _IS_FREE(pdesc2) ) { /* coalesce pdesc2 with pdesc */ pdesc->pnextdesc = pdesc2->pnextdesc; _PUTEMPTY(pdesc2); } else break; } /* end LOOP_FOREVER */ for ( pdesc = _heap_desc.pfirstdesc ; pdesc != _heap_desc.proverdesc ; pdesc = pdesc->pnextdesc ) /* is pdesc free? */ if ( _IS_FREE(pdesc) ) /* coalesce loop */ LOOP_FOREVER { /* if pdesc is big enough, return it */ if ( _BLKSIZE(pdesc) >= size ) { pretdesc = pdesc; goto searchdone; } /* see if the next block is free and, if so, * coalesce it with pdesc */ pdesc2 = pdesc->pnextdesc; if ( _IS_FREE(pdesc2) ) { /* coalesce pdesc2 with pdesc */ pdesc->pnextdesc = pdesc2->pnextdesc; _PUTEMPTY(pdesc2); /* special handling for the case where * the rover has been coalesced (search * ends) */ if ( _heap_desc.proverdesc == pdesc2 ) { _heap_desc.proverdesc = pdesc; if ( _BLKSIZE(pdesc) >= size ) pretdesc = pdesc; goto searchdone; } } else break; } /* end LOOP_FOREVER */ searchdone: /* common exit for all code paths. win, lose or draw, this is the * only code path back to the caller. */ return(pretdesc); } #endif /* WINHEAP */