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.

284 lines
6.7 KiB

  1. /*++
  2. Copyright (c) 1991 Microsoft Corporation
  3. Module Name:
  4. oscheap.c
  5. Abstract:
  6. This module contains "local" heap management code for OS Chooser.
  7. Author:
  8. Geoff Pease (gpease) May 28 1998
  9. Revision History:
  10. --*/
  11. #ifdef i386
  12. #include "bldrx86.h"
  13. #endif
  14. #if defined(_IA64_)
  15. #include "bldria64.h"
  16. #endif
  17. #include "netfs.h"
  18. #include "oscheap.h"
  19. #define FREE_POOL_TAG 0x0
  20. #define ALLOC_POOL_TAG 0x1
  21. typedef struct _LOCAL_MEMORY_DESCRIPTOR {
  22. //
  23. // We create a union to make sure that this struct is always at least the size of a
  24. // pointer, and thus will be pointer aligned.
  25. //
  26. union {
  27. struct {
  28. ULONG Tag;
  29. ULONG Size;
  30. };
  31. struct {
  32. void *Align;
  33. };
  34. };
  35. } LOCAL_MEMORY_DESCRIPTOR, *PLOCAL_MEMORY_DESCRIPTOR;
  36. //
  37. // Variable for holding our memory together.
  38. //
  39. #ifdef EFI
  40. #define OSCHEAPSIZE 0x4000 // 16k
  41. #else
  42. #define OSCHEAPSIZE 0x2000 // 8k
  43. #endif
  44. CHAR OscHeap[ OSCHEAPSIZE ];
  45. //
  46. // Functions
  47. //
  48. void
  49. OscHeapInitialize(
  50. VOID
  51. )
  52. /*++
  53. Routine Description:
  54. This routine initializes the internal memory management system.
  55. Arguments:
  56. None.
  57. Return Value:
  58. None.
  59. --*/
  60. {
  61. PLOCAL_MEMORY_DESCRIPTOR LocalDescriptor;
  62. LocalDescriptor = (PLOCAL_MEMORY_DESCRIPTOR)OscHeap;
  63. LocalDescriptor->Tag = FREE_POOL_TAG;
  64. LocalDescriptor->Size = OSCHEAPSIZE - sizeof(LOCAL_MEMORY_DESCRIPTOR);
  65. memset((PVOID)(LocalDescriptor + 1), 0, LocalDescriptor->Size);
  66. }
  67. PCHAR
  68. OscHeapAlloc(
  69. IN UINT iSize
  70. )
  71. /*++
  72. Routine Description:
  73. This routine allocates memory from our internal structures.
  74. Arguments:
  75. iSize - Number of bytes the client wants.
  76. Return Value:
  77. A pointer to the allocated block if successful, else NULL
  78. --*/
  79. {
  80. PLOCAL_MEMORY_DESCRIPTOR LocalDescriptor;
  81. PLOCAL_MEMORY_DESCRIPTOR NextDescriptor;
  82. LONG ThisBlockSize;
  83. ULONG BytesToAllocate;
  84. //
  85. // Always allocate in increments of a pointer, minmally.
  86. //
  87. if (iSize & (sizeof(void *) - 1)) {
  88. iSize += sizeof(void *) - (iSize & (sizeof(void *) - 1));
  89. }
  90. LocalDescriptor = (PLOCAL_MEMORY_DESCRIPTOR)OscHeap;
  91. ThisBlockSize = OSCHEAPSIZE - sizeof(LOCAL_MEMORY_DESCRIPTOR);
  92. while (ThisBlockSize > 0) {
  93. if ((LocalDescriptor->Tag == FREE_POOL_TAG) &&
  94. (LocalDescriptor->Size >= iSize)) {
  95. goto FoundBlock;
  96. }
  97. ThisBlockSize -= (LocalDescriptor->Size + sizeof(LOCAL_MEMORY_DESCRIPTOR));
  98. LocalDescriptor = (PLOCAL_MEMORY_DESCRIPTOR)(((PUCHAR)LocalDescriptor) +
  99. LocalDescriptor->Size +
  100. sizeof(LOCAL_MEMORY_DESCRIPTOR)
  101. );
  102. }
  103. //
  104. // There is no memory block big enough to hold the request.
  105. //
  106. return NULL;
  107. FoundBlock:
  108. //
  109. // Jump to here when a memory descriptor of the right size has been found. It is expected that
  110. // LocalDescriptor points to the correct block.
  111. //
  112. if (LocalDescriptor->Size > iSize + sizeof(LOCAL_MEMORY_DESCRIPTOR)) {
  113. //
  114. // Make a descriptor of the left over parts of this block.
  115. //
  116. NextDescriptor = (PLOCAL_MEMORY_DESCRIPTOR)(((PUCHAR)LocalDescriptor) +
  117. sizeof(LOCAL_MEMORY_DESCRIPTOR) +
  118. iSize
  119. );
  120. NextDescriptor->Tag = FREE_POOL_TAG;
  121. NextDescriptor->Size = (ULONG)(LocalDescriptor->Size - iSize - sizeof(LOCAL_MEMORY_DESCRIPTOR));
  122. LocalDescriptor->Size = (ULONG)iSize;
  123. }
  124. LocalDescriptor->Tag = ALLOC_POOL_TAG;
  125. memset((LocalDescriptor+1), 0, iSize);
  126. return (PCHAR)(LocalDescriptor + 1);
  127. }
  128. PCHAR
  129. OscHeapFree(
  130. IN PCHAR Pointer
  131. )
  132. /*++
  133. Routine Description:
  134. This routine frees a block previously allocated from the internal memory management system.
  135. Arguments:
  136. Pointer - A pointer to free.
  137. Return Value:
  138. NULL.
  139. --*/
  140. {
  141. LONG ThisBlockSize;
  142. PLOCAL_MEMORY_DESCRIPTOR LocalDescriptor;
  143. PLOCAL_MEMORY_DESCRIPTOR PrevDescriptor;
  144. PLOCAL_MEMORY_DESCRIPTOR ThisDescriptor;
  145. LocalDescriptor = (PLOCAL_MEMORY_DESCRIPTOR)(((PUCHAR)Pointer) - sizeof(LOCAL_MEMORY_DESCRIPTOR));
  146. //
  147. // Find the memory block in the heap
  148. //
  149. PrevDescriptor = NULL;
  150. ThisDescriptor = (PLOCAL_MEMORY_DESCRIPTOR)OscHeap;
  151. ThisBlockSize = OSCHEAPSIZE - sizeof(LOCAL_MEMORY_DESCRIPTOR);
  152. while (ThisBlockSize > 0) {
  153. if (ThisDescriptor == LocalDescriptor) {
  154. goto FoundBlock;
  155. }
  156. ThisBlockSize -= (ThisDescriptor->Size + sizeof(LOCAL_MEMORY_DESCRIPTOR));
  157. PrevDescriptor = ThisDescriptor;
  158. ThisDescriptor = (PLOCAL_MEMORY_DESCRIPTOR)(((PUCHAR)ThisDescriptor) +
  159. ThisDescriptor->Size +
  160. sizeof(LOCAL_MEMORY_DESCRIPTOR)
  161. );
  162. }
  163. return NULL;
  164. FoundBlock:
  165. //
  166. // Jump to here when the proper memory descriptor has been found.
  167. //
  168. if (LocalDescriptor->Tag == FREE_POOL_TAG) {
  169. //
  170. // Ouch! We tried to free something twice, skip it before bad things happen.
  171. //
  172. return NULL;
  173. }
  174. LocalDescriptor->Tag = FREE_POOL_TAG;
  175. //
  176. // If possible, merge this memory block with the next one.
  177. //
  178. if ((ULONG)ThisBlockSize > (LocalDescriptor->Size + sizeof(LOCAL_MEMORY_DESCRIPTOR))) {
  179. ThisDescriptor = (PLOCAL_MEMORY_DESCRIPTOR)(((PUCHAR)LocalDescriptor) +
  180. LocalDescriptor->Size +
  181. sizeof(LOCAL_MEMORY_DESCRIPTOR)
  182. );
  183. if (ThisDescriptor->Tag == FREE_POOL_TAG) {
  184. LocalDescriptor->Size += ThisDescriptor->Size + sizeof(LOCAL_MEMORY_DESCRIPTOR);
  185. ThisDescriptor->Tag = 0;
  186. ThisDescriptor->Size = 0;
  187. }
  188. }
  189. //
  190. // Now see if we can merge this block with a previous block.
  191. //
  192. if ((PrevDescriptor != NULL) && (PrevDescriptor->Tag == FREE_POOL_TAG)) {
  193. PrevDescriptor->Size += LocalDescriptor->Size + sizeof(LOCAL_MEMORY_DESCRIPTOR);
  194. LocalDescriptor->Tag = 0;
  195. LocalDescriptor->Size = 0;
  196. }
  197. return NULL;
  198. }