home *** CD-ROM | disk | FTP | other *** search
- /***
- *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 <cruntime.h>
- #include <heap.h>
- #include <stddef.h>
-
- #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 */
-