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.

206 lines
4.8 KiB

  1. /*****************************************************************************
  2. *
  3. * mem.c
  4. *
  5. * Low-level memory management.
  6. *
  7. *****************************************************************************/
  8. #include "m4.h"
  9. #ifdef DEBUG
  10. AR g_arHead = { parHead, parHead };
  11. #define cbExtra (offsetof(AR, rgb)+1)
  12. #else
  13. #define cbExtra 0
  14. #endif
  15. #ifdef DEBUG
  16. /*****************************************************************************
  17. *
  18. * InsertPar
  19. *
  20. * Insert an arena record onto the list.
  21. *
  22. *****************************************************************************/
  23. void InsertPar(PAR par)
  24. {
  25. par->parPrev = parHead;
  26. par->parNext = parHead->parNext;
  27. parHead->parNext->parPrev = par;
  28. parHead->parNext = par;
  29. }
  30. /*****************************************************************************
  31. *
  32. * UnlinkPar
  33. *
  34. * Unlink an arena from the chain.
  35. *
  36. *****************************************************************************/
  37. void STDCALL
  38. UnlinkPar(PAR par)
  39. {
  40. Assert(par->parNext->parPrev == par);
  41. Assert(par->parPrev->parNext == par);
  42. par->parNext->parPrev = par->parPrev;
  43. par->parPrev->parNext = par->parNext;
  44. D(par->rgb[par->cb] = 0xFF);
  45. D(par->tm = (TM)-1);
  46. }
  47. /*****************************************************************************
  48. *
  49. * InitParCb
  50. *
  51. * Initialize the arena fields that will be asserted later.
  52. *
  53. *****************************************************************************/
  54. void STDCALL
  55. InitParCb(PAR par, CB cb)
  56. {
  57. par->cb = cb;
  58. par->rgb[cb] = 0xCC; /* Overflow at end */
  59. par->tm = g_tmNow; /* Underflow at beginning */
  60. }
  61. /*****************************************************************************
  62. *
  63. * AssertPar
  64. *
  65. * Check that the arena is still okay.
  66. *
  67. *****************************************************************************/
  68. void STDCALL
  69. AssertPar(PCAR par)
  70. {
  71. Assert(par->rgb[par->cb] == 0xCC); /* Overflow at end */
  72. Assert(par->tm == g_tmNow); /* Underflow at beginning */
  73. Assert(par->parNext->parPrev == par);
  74. Assert(par->parPrev->parNext == par);
  75. }
  76. /*****************************************************************************
  77. *
  78. * MemCheck
  79. *
  80. * Walk the entire list of memory arenas, making sure all is well.
  81. *
  82. *****************************************************************************/
  83. void STDCALL
  84. MemCheck(void)
  85. {
  86. PAR par;
  87. for (par = parHead->parNext; par != parHead; par = par->parNext) {
  88. AssertPar(par);
  89. }
  90. }
  91. #else
  92. #define InsertPar(par)
  93. #define UnlinkPar(par)
  94. #define InitParCb(par, cb)
  95. #define MemCheck()
  96. #endif
  97. /*****************************************************************************
  98. *
  99. * FreePv
  100. *
  101. * Free an arbitrary hunk of memory.
  102. *
  103. * The incoming pointer really is the rgb of an arena.
  104. *
  105. *****************************************************************************/
  106. void STDCALL
  107. FreePv(PVOID pv)
  108. {
  109. MemCheck();
  110. if (pv) {
  111. PAR par = parPv(pv);
  112. AssertPar(par);
  113. UnlinkPar(par);
  114. #ifdef DEBUG
  115. if (par->cb >= 4) {
  116. par->rgb[3]++; /* Kill the signature */
  117. }
  118. #endif
  119. _FreePv(par);
  120. }
  121. MemCheck();
  122. }
  123. /*****************************************************************************
  124. *
  125. * pvAllocCb
  126. *
  127. * Allocate a hunk of memory.
  128. *
  129. * We really allocate an arena, but return the rgb.
  130. *
  131. * We allow allocation of zero bytes, which allocates nothing and returns
  132. * NULL.
  133. *
  134. *****************************************************************************/
  135. PVOID STDCALL
  136. pvAllocCb(CB cb)
  137. {
  138. PAR par;
  139. MemCheck();
  140. if (cb) {
  141. par = _pvAllocCb(cb + cbExtra);
  142. if (par) {
  143. InitParCb(par, cb);
  144. InsertPar(par);
  145. } else {
  146. Die("out of memory");
  147. }
  148. MemCheck();
  149. return &par->rgb;
  150. } else {
  151. return 0;
  152. }
  153. }
  154. /*****************************************************************************
  155. *
  156. * pvReallocPvCb
  157. *
  158. * Change the size of a hunk of memory.
  159. *
  160. *****************************************************************************/
  161. PVOID STDCALL
  162. pvReallocPvCb(PVOID pv, CB cb)
  163. {
  164. MemCheck();
  165. if (pv) {
  166. PAR par_t, par = parPv(pv);
  167. Assert(cb);
  168. AssertPar(par);
  169. UnlinkPar(par);
  170. par_t = _pvReallocPvCb(par, cb + cbExtra);
  171. if (par_t) {
  172. par = par_t;
  173. InitParCb(par, cb);
  174. InsertPar(par);
  175. } else {
  176. Die("out of memory");
  177. }
  178. MemCheck();
  179. return &par->rgb;
  180. } else {
  181. return pvAllocCb(cb);
  182. }
  183. }