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.

202 lines
5.1 KiB

  1. //
  2. // REGMEM.C
  3. //
  4. // Copyright (C) Microsoft Corporation, 1995
  5. //
  6. // Upper-level memory management functions that discards unlocked memory blocks
  7. // as required to fulfill allocation requests.
  8. //
  9. // For the ring zero version of this code, only large requests will call these
  10. // functions. For most registry files, these requests will already be an
  11. // integral number of pages, so it's best just to do page allocations. Small
  12. // allocations, such as key handles, will use the heap services and not go
  13. // through this code.
  14. //
  15. // For all other models of this code, all memory requests will go through this
  16. // code and memory is allocated from the heap.
  17. //
  18. #include "pch.h"
  19. DECLARE_DEBUG_COUNT(g_RgMemoryBlockCount);
  20. // For the ring zero version, only large allocations that should be page
  21. // aligned will pass through these functions.
  22. #ifdef VXD
  23. // Converts number of bytes to number of whole pages.
  24. #define ConvertToMemoryUnits(cb) \
  25. ((((cb) + (PAGESIZE - 1)) & ~(PAGESIZE - 1)) >> PAGESHIFT)
  26. // Generates smaller code if we don't just make this a macro...
  27. LPVOID
  28. INTERNAL
  29. RgAllocMemoryUnits(
  30. UINT nPages
  31. )
  32. {
  33. return AllocPages(nPages);
  34. }
  35. // Generates smaller code if we don't just make this a macro...
  36. LPVOID
  37. INTERNAL
  38. RgReAllocMemoryUnits(
  39. LPVOID lpMemory,
  40. UINT nPages
  41. )
  42. {
  43. return ReAllocPages(lpMemory, nPages);
  44. }
  45. #define RgFreeMemoryUnits FreePages
  46. // For non-ring zero version of the registry code, all allocations will funnel
  47. // through these functions. All allocations are off the heap.
  48. #else
  49. #define ConvertToMemoryUnits(cb) (cb)
  50. #define RgAllocMemoryUnits AllocBytes
  51. #define RgReAllocMemoryUnits ReAllocBytes
  52. #define RgFreeMemoryUnits FreeBytes
  53. #endif
  54. //
  55. // RgAllocMemory
  56. //
  57. LPVOID
  58. INTERNAL
  59. RgAllocMemory(
  60. UINT cbBytes
  61. )
  62. {
  63. UINT MemoryUnits;
  64. LPVOID lpMemory;
  65. ASSERT(cbBytes > 0);
  66. MemoryUnits = ConvertToMemoryUnits(cbBytes);
  67. // Can we allocate from available memory?
  68. if (!IsNullPtr((lpMemory = RgAllocMemoryUnits(MemoryUnits)))) {
  69. INCREMENT_DEBUG_COUNT(g_RgMemoryBlockCount);
  70. return lpMemory;
  71. }
  72. RgEnumFileInfos(RgSweepFileInfo);
  73. // Can we allocate after sweeping all old memory blocks?
  74. if (!IsNullPtr((lpMemory = RgAllocMemoryUnits(MemoryUnits)))) {
  75. INCREMENT_DEBUG_COUNT(g_RgMemoryBlockCount);
  76. return lpMemory;
  77. }
  78. // The first sweep will have cleared all the access bits of every memory
  79. // block. This sweep will effectively discard all unlocked blocks.
  80. RgEnumFileInfos(RgSweepFileInfo);
  81. // Can we allocate after sweeping all unlocked and clean memory blocks?
  82. if (!IsNullPtr((lpMemory = RgAllocMemoryUnits(MemoryUnits)))) {
  83. INCREMENT_DEBUG_COUNT(g_RgMemoryBlockCount);
  84. return lpMemory;
  85. }
  86. // Flush out every dirty memory block and sweep again.
  87. RgEnumFileInfos(RgFlushFileInfo);
  88. RgEnumFileInfos(RgSweepFileInfo);
  89. // Can we allocate after sweeping all unlocked memory blocks?
  90. if (!IsNullPtr((lpMemory = RgAllocMemoryUnits(MemoryUnits)))) {
  91. INCREMENT_DEBUG_COUNT(g_RgMemoryBlockCount);
  92. return lpMemory;
  93. }
  94. DEBUG_OUT(("RgAllocMemory failure\n"));
  95. // Return lpMemory, which must be NULL if we're here, generates smaller
  96. // code.
  97. return lpMemory; // Must be NULL if we're here
  98. }
  99. //
  100. // RgReAllocMemory
  101. //
  102. LPVOID
  103. INTERNAL
  104. RgReAllocMemory(
  105. LPVOID lpOldMemory,
  106. UINT cbBytes
  107. )
  108. {
  109. UINT MemoryUnits;
  110. LPVOID lpMemory;
  111. ASSERT(!IsNullPtr(lpOldMemory));
  112. ASSERT(cbBytes > 0);
  113. MemoryUnits = ConvertToMemoryUnits(cbBytes);
  114. // Can we allocate from available memory?
  115. if (!IsNullPtr((lpMemory = RgReAllocMemoryUnits(lpOldMemory, MemoryUnits))))
  116. return lpMemory;
  117. RgEnumFileInfos(RgSweepFileInfo);
  118. // Can we allocate after sweeping all old memory blocks?
  119. if (!IsNullPtr((lpMemory = RgReAllocMemoryUnits(lpOldMemory, MemoryUnits))))
  120. return lpMemory;
  121. // The first sweep will have cleared all the access bits of every memory
  122. // block. This sweep will effectively discard all unlocked blocks.
  123. RgEnumFileInfos(RgSweepFileInfo);
  124. // Can we allocate after sweeping all unlocked and clean memory blocks?
  125. if (!IsNullPtr((lpMemory = RgReAllocMemoryUnits(lpOldMemory, MemoryUnits))))
  126. return lpMemory;
  127. // Flush out every dirty memory block and sweep again.
  128. RgEnumFileInfos(RgFlushFileInfo);
  129. RgEnumFileInfos(RgSweepFileInfo);
  130. // Can we allocate after sweeping all unlocked memory blocks?
  131. if (!IsNullPtr((lpMemory = RgReAllocMemoryUnits(lpOldMemory, MemoryUnits))))
  132. return lpMemory;
  133. DEBUG_OUT(("RgReAllocMemory failure\n"));
  134. // Return lpMemory, which must be NULL if we're here, generates smaller
  135. // code.
  136. return lpMemory;
  137. }
  138. #ifdef DEBUG
  139. //
  140. // RgFreeMemory
  141. //
  142. VOID
  143. INTERNAL
  144. RgFreeMemory(
  145. LPVOID lpMemory
  146. )
  147. {
  148. ASSERT(!IsNullPtr(lpMemory));
  149. DECREMENT_DEBUG_COUNT(g_RgMemoryBlockCount);
  150. #ifdef ZEROONFREE
  151. ZeroMemory(lpMemory, MemorySize(lpMemory));
  152. #endif
  153. RgFreeMemoryUnits(lpMemory);
  154. }
  155. #endif