Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

156 lines
4.1 KiB

  1. /***
  2. *heapsrch.c - search the heap for a free block
  3. *
  4. * Copyright (c) 1989-2001, Microsoft Corporation. All rights reserved.
  5. *
  6. *Purpose:
  7. * Defines the _heap_search() function.
  8. *
  9. *Revision History:
  10. * 06-30-89 GJF Module created. Yea, it's ugly, but it seems to work.
  11. * 07-21-89 GJF Now assumes proverdesc points to the descriptor for
  12. * first free block in the heap, if any, or is plastdesc,
  13. * if there are no free blocks
  14. * 11-08-89 GJF Fixed copyright, added register attribute to vars
  15. * 12-18-89 GJF Removed some redundant code, updated the description,
  16. * changed include file name to heap.h, added explicit
  17. * _cdecl to function definition.
  18. * 12-19-89 GJF Got rid of code to maintain plastdesc
  19. * 03-11-90 GJF Replaced _cdecl with _CALLTYPE1, added #include
  20. * <cruntime.h> and removed #include <register.h>.
  21. * 09-28-90 GJF New-style function declarator.
  22. * 03-05-91 GJF Changed strategy for rover - old version available
  23. * by #define-ing _OLDROVER_.
  24. * 04-06-93 SKS Replace _CRTAPI* with __cdecl
  25. * 02-08-95 GJF Removed obsolete _OLDROVER_ support.
  26. * 04-30-95 GJF Made conditional on WINHEAP.
  27. *
  28. *******************************************************************************/
  29. #ifndef WINHEAP
  30. #include <cruntime.h>
  31. #include <heap.h>
  32. #include <stddef.h>
  33. #define LOOP_FOREVER while(1)
  34. /***
  35. *_PBLKDESC _heap_search(unsigned size) - Find a free block of a least size
  36. * bytes.
  37. *
  38. *Purpose:
  39. * Finds a free block of at least size bytes. Searches the list of block
  40. * descriptors from *proverdesc to the end (marked by the sentinel). The
  41. * search is strictly first fit. Adjacent free blocks are coalesced as
  42. * they are encountered during the search.
  43. *
  44. *Entry:
  45. * unsigned size - size of block requested
  46. *
  47. *Exit:
  48. * Success: Pointer to descriptor for free memory block of at least size
  49. * bytes
  50. * Failure: NULL
  51. *
  52. *Uses:
  53. *
  54. *Exceptions:
  55. *
  56. *******************************************************************************/
  57. _PBLKDESC __cdecl _heap_search (
  58. unsigned size
  59. )
  60. {
  61. REG1 _PBLKDESC pdesc;
  62. REG2 _PBLKDESC pdesc2;
  63. _PBLKDESC pretdesc = NULL;
  64. /* search from proverdesc thru plastdesc, looking for free block of
  65. * at least size bytes. coalesce adjacent free blocks during the
  66. * search. the search is strictly first fit. that is, it terminates
  67. * when the first block is found of adequate size.
  68. */
  69. for ( pdesc = _heap_desc.proverdesc ; pdesc != &(_heap_desc.sentinel) ;
  70. pdesc = pdesc->pnextdesc )
  71. /* is pdesc free?
  72. */
  73. if ( _IS_FREE(pdesc) )
  74. /* coalesce loop
  75. */
  76. LOOP_FOREVER {
  77. /* if pdesc is big enough, return it
  78. */
  79. if ( _BLKSIZE(pdesc) >= size ) {
  80. pretdesc = pdesc;
  81. goto searchdone;
  82. }
  83. /* see if the next block is free and, if so,
  84. * coalesce it with pdesc
  85. */
  86. pdesc2 = pdesc->pnextdesc;
  87. if ( _IS_FREE(pdesc2) ) {
  88. /* coalesce pdesc2 with pdesc
  89. */
  90. pdesc->pnextdesc = pdesc2->pnextdesc;
  91. _PUTEMPTY(pdesc2);
  92. }
  93. else
  94. break;
  95. } /* end LOOP_FOREVER */
  96. for ( pdesc = _heap_desc.pfirstdesc ; pdesc != _heap_desc.proverdesc ;
  97. pdesc = pdesc->pnextdesc )
  98. /* is pdesc free?
  99. */
  100. if ( _IS_FREE(pdesc) )
  101. /* coalesce loop
  102. */
  103. LOOP_FOREVER {
  104. /* if pdesc is big enough, return it
  105. */
  106. if ( _BLKSIZE(pdesc) >= size ) {
  107. pretdesc = pdesc;
  108. goto searchdone;
  109. }
  110. /* see if the next block is free and, if so,
  111. * coalesce it with pdesc
  112. */
  113. pdesc2 = pdesc->pnextdesc;
  114. if ( _IS_FREE(pdesc2) ) {
  115. /* coalesce pdesc2 with pdesc
  116. */
  117. pdesc->pnextdesc = pdesc2->pnextdesc;
  118. _PUTEMPTY(pdesc2);
  119. /* special handling for the case where
  120. * the rover has been coalesced (search
  121. * ends)
  122. */
  123. if ( _heap_desc.proverdesc == pdesc2 )
  124. {
  125. _heap_desc.proverdesc = pdesc;
  126. if ( _BLKSIZE(pdesc) >= size )
  127. pretdesc = pdesc;
  128. goto searchdone;
  129. }
  130. }
  131. else
  132. break;
  133. } /* end LOOP_FOREVER */
  134. searchdone:
  135. /* common exit for all code paths. win, lose or draw, this is the
  136. * only code path back to the caller.
  137. */
  138. return(pretdesc);
  139. }
  140. #endif /* WINHEAP */