Source code of Windows XP (NT5)
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.

296 lines
7.9 KiB

  1. /***
  2. *free.c - free an entry in the heap
  3. *
  4. * Copyright (c) 1989-2001, Microsoft Corporation. All rights reserved.
  5. *
  6. *Purpose:
  7. * Defines the following functions:
  8. * free() - free a memory block in the heap
  9. *
  10. *Revision History:
  11. * 06-30-89 JCR Module created
  12. * 07-07-89 GJF Fixed test for resetting proverdesc
  13. * 11-10-89 GJF Added MTHREAD support. Also, a little cleanup.
  14. * 12-18-89 GJF Change header file name to heap.h, added register
  15. * declarations and added explicit _cdecl to function
  16. * definitions
  17. * 03-09-90 GJF Replaced _cdecl with _CALLTYPE1, added #include
  18. * <cruntime.h> and removed #include <register.h>.
  19. * 09-27-90 GJF New-style function declarators. Also, rewrote expr.
  20. * so that a cast was not used as an lvalue.
  21. * 03-05-91 GJF Changed strategy for rover - old version available
  22. * by #define-ing _OLDROVER_.
  23. * 04-08-91 GJF Temporary hack for Win32/DOS folks - special version
  24. * of free that just calls HeapFree. Change conditioned
  25. * on _WIN32DOS_.
  26. * 04-06-93 SKS Replace _CRTAPI* with __cdecl
  27. * 11-12-93 GJF Incorporated Jonathan Mark's suggestion for reducing
  28. * fragmentation: if the block following the newly freed
  29. * block is the rover block, reset the rover to the
  30. * newly freed block. Also, replaced MTHREAD with _MT
  31. * and deleted obsolete WIN32DOS support.
  32. * 05-19-94 GJF Added __mark_block_as_free() for the sole use by
  33. * __dllonexit() in the Win32s version of msvcrt*.dll.
  34. * 06-06-94 GJF Removed __mark_block_as_free()!
  35. * 11-03-94 CFW Debug heap support.
  36. * 12-01-94 CFW Simplify debug interface.
  37. * 01-12-95 GJF Fixed bogus test to reset rover. Also, purged
  38. * _OLDROVER_ code.
  39. * 02-01-95 GJF #ifdef out the *_base names for the Mac builds
  40. * (temporary).
  41. * 02-09-95 GJF Restored *_base names.
  42. * 04-30-95 GJF Made conditional on WINHEAP.
  43. * 03-01-96 GJF Added support fro small-block heap.
  44. * 04-10-96 GJF Return type of __sbh_find_block and __sbh_free_block
  45. * changed to __map_t *.
  46. * 05-30-96 GJF Minor changes for latest version of small-block heap.
  47. * 05-22-97 RDK New small-block heap scheme implemented.
  48. * 09-26-97 BWT Fix POSIX
  49. * 11-05-97 GJF Small POSIX fix from Roger Lanser.
  50. * 12-17-97 GJF Exception-safe locking.
  51. * 05-22-98 JWM Support for KFrei's RTC work.
  52. * 07-28-98 JWM RTC update.
  53. * 09-29-98 GJF Bypass all small-block heap code when __sbh_initialized
  54. * is 0.
  55. * 11-16-98 GJF Merged in VC++ 5.0 version of small-block heap.
  56. * 05-01-99 PML Disable small-block heap for Win64.
  57. * 05-17-99 PML Remove all Macintosh support.
  58. * 05-26-99 KBF Updated RTC hook func params
  59. * 06-22-99 GJF Removed old small-block heap from static libs.
  60. *
  61. *******************************************************************************/
  62. #ifdef WINHEAP
  63. #include <cruntime.h>
  64. #include <malloc.h>
  65. #include <winheap.h>
  66. #include <windows.h>
  67. #include <internal.h>
  68. #include <mtdll.h>
  69. #include <dbgint.h>
  70. #include <rtcsup.h>
  71. /***
  72. *void free(pblock) - free a block in the heap
  73. *
  74. *Purpose:
  75. * Free a memory block in the heap.
  76. *
  77. * Special ANSI Requirements:
  78. *
  79. * (1) free(NULL) is benign.
  80. *
  81. *Entry:
  82. * void *pblock - pointer to a memory block in the heap
  83. *
  84. *Return:
  85. * <void>
  86. *
  87. *******************************************************************************/
  88. void __cdecl _free_base (void * pBlock)
  89. {
  90. #ifdef _POSIX_
  91. HeapFree(_crtheap,
  92. 0,
  93. pBlock
  94. );
  95. #else /* _POSIX_ */
  96. #ifdef HEAPHOOK
  97. /* call heap hook if installed */
  98. if (_heaphook)
  99. {
  100. if ((*_heaphook)(_HEAP_FREE, 0, pBlock, NULL))
  101. return;
  102. }
  103. #endif /* HEAPHOOK */
  104. if (pBlock == NULL)
  105. return;
  106. RTCCALLBACK(_RTC_Free_hook, (pBlock, 0));
  107. #ifndef _WIN64
  108. if ( __active_heap == __V6_HEAP )
  109. {
  110. PHEADER pHeader;
  111. #ifdef _MT
  112. _mlock( _HEAP_LOCK );
  113. __try {
  114. #endif
  115. if ((pHeader = __sbh_find_block(pBlock)) != NULL)
  116. __sbh_free_block(pHeader, pBlock);
  117. #ifdef _MT
  118. }
  119. __finally {
  120. _munlock( _HEAP_LOCK );
  121. }
  122. #endif
  123. if (pHeader == NULL)
  124. HeapFree(_crtheap, 0, pBlock);
  125. }
  126. #ifdef CRTDLL
  127. else if ( __active_heap == __V5_HEAP )
  128. {
  129. __old_sbh_region_t *preg;
  130. __old_sbh_page_t * ppage;
  131. __old_page_map_t * pmap;
  132. #ifdef _MT
  133. _mlock(_HEAP_LOCK );
  134. __try {
  135. #endif
  136. if ( (pmap = __old_sbh_find_block(pBlock, &preg, &ppage)) != NULL )
  137. __old_sbh_free_block(preg, ppage, pmap);
  138. #ifdef _MT
  139. }
  140. __finally {
  141. _munlock(_HEAP_LOCK );
  142. }
  143. #endif
  144. if (pmap == NULL)
  145. HeapFree(_crtheap, 0, pBlock);
  146. }
  147. #endif /* CRTDLL */
  148. else // __active_heap == __SYSTEM_HEAP
  149. #endif /* ndef _WIN64 */
  150. {
  151. HeapFree(_crtheap, 0, pBlock);
  152. }
  153. #endif /* _POSIX_ */
  154. }
  155. #else /* ndef WINHEAP */
  156. #include <cruntime.h>
  157. #include <heap.h>
  158. #include <malloc.h>
  159. #include <mtdll.h>
  160. #include <stdlib.h>
  161. #include <dbgint.h>
  162. /***
  163. *void free(pblock) - free a block in the heap
  164. *
  165. *Purpose:
  166. * Free a memory block in the heap.
  167. *
  168. * Special Notes For Multi-thread: The non-multi-thread version is renamed
  169. * to _free_lk(). The multi-thread free() simply locks the heap, calls
  170. * _free_lk(), then unlocks the heap and returns.
  171. *
  172. *Entry:
  173. * void *pblock - pointer to a memory block in the heap
  174. *
  175. *Return:
  176. * <void>
  177. *
  178. *******************************************************************************/
  179. #ifdef _MT
  180. void __cdecl _free_base (
  181. void *pblock
  182. )
  183. {
  184. /* lock the heap
  185. */
  186. _mlock(_HEAP_LOCK);
  187. /* free the block
  188. */
  189. _free_base_lk(pblock);
  190. /* unlock the heap
  191. */
  192. _munlock(_HEAP_LOCK);
  193. }
  194. /***
  195. *void _free_lk(pblock) - non-locking form of free
  196. *
  197. *Purpose:
  198. * Same as free() except that no locking is performed
  199. *
  200. *Entry:
  201. * See free
  202. *
  203. *Return:
  204. *
  205. *******************************************************************************/
  206. void __cdecl _free_base_lk (
  207. #else /* ndef _MT */
  208. void __cdecl _free_base (
  209. #endif /* _MT */
  210. REG1 void *pblock
  211. )
  212. {
  213. REG2 _PBLKDESC pdesc;
  214. #ifdef HEAPHOOK
  215. /* call heap hook if installed */
  216. if (_heaphook) {
  217. if ((*_heaphook)(_HEAP_FREE, 0, pblock, NULL))
  218. return;
  219. }
  220. #endif /* HEAPHOOK */
  221. /*
  222. * If the pointer is NULL, just return [ANSI].
  223. */
  224. if (pblock == NULL)
  225. return;
  226. /*
  227. * Point to block header and get the pointer back to the heap desc.
  228. */
  229. pblock = (char *)pblock - _HDRSIZE;
  230. pdesc = *(_PBLKDESC*)pblock;
  231. /*
  232. * Validate the back pointer.
  233. */
  234. if (_ADDRESS(pdesc) != pblock)
  235. _heap_abort();
  236. /*
  237. * Pointer is ok. Mark block free.
  238. */
  239. _SET_FREE(pdesc);
  240. /*
  241. * Check for special conditions under which the rover is reset.
  242. */
  243. if ( (_heap_resetsize != 0xffffffff) &&
  244. (_heap_desc.proverdesc->pblock > pdesc->pblock) &&
  245. (_BLKSIZE(pdesc) >= _heap_resetsize) )
  246. {
  247. _heap_desc.proverdesc = pdesc;
  248. }
  249. else if ( _heap_desc.proverdesc == pdesc->pnextdesc )
  250. {
  251. _heap_desc.proverdesc = pdesc;
  252. }
  253. }
  254. #endif /* WINHEAP */