home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Tricks of the Windows Gam…ming Gurus (2nd Edition)
/
Disc2.iso
/
vc98
/
crt
/
src
/
heapsrch.c
< prev
next >
Wrap
C/C++ Source or Header
|
1998-06-17
|
5KB
|
138 lines
/***
*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 */