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.

297 lines
8.1 KiB

  1. #include "precomp.h"
  2. DEBUG_FILEZONE(ZONE_T120_MEMORY);
  3. /*
  4. * memmgr.cpp
  5. *
  6. * Copyright (c) 1998 by Microsoft Corporation, Redmond, WA
  7. *
  8. * Abstract:
  9. * This is the implementation file for the T.120 memory allocation mechanism. This
  10. * file contains the code necessary to allocate and distribute memory
  11. * in the form of Memory objects.
  12. *
  13. * This implementation defines priorities of memory allocations. A lower
  14. * priority number implies higher priority. Priority-0 allocations will be
  15. * satisfied, unless the system is out of memory. Priorities 1 and 2
  16. * limit the amount of total memory that can be allocated, but priority 1 (recv priority)
  17. * has higher water mark limits than priority 2 (send priority).
  18. *
  19. * Protected Member Functions:
  20. * None.
  21. *
  22. * Caveats:
  23. * None.
  24. *
  25. * Author:
  26. * Christos Tsollis
  27. */
  28. static int s_anCurrentSize[MEMORY_PRIORITIES] = { 0, 0, 0 };
  29. static const int sc_iLimit[MEMORY_PRIORITIES] = {
  30. 0x7FFFFFFF,
  31. 0x100000,
  32. 0xE0000
  33. };
  34. #ifdef DEBUG
  35. static int s_TotalSize = 0;
  36. #endif // DEBUG
  37. /*
  38. * PMemory AllocateMemory ()
  39. *
  40. * Public
  41. *
  42. * Functional Description:
  43. * This function is used to allocate a buffer together with a
  44. * Memory (buffer header) object
  45. */
  46. PMemory AllocateMemory (
  47. PUChar reference_ptr,
  48. UINT length,
  49. MemoryPriority priority)
  50. {
  51. PUChar copy_ptr;
  52. PMemory memory;
  53. ASSERT (length > 0);
  54. if (s_anCurrentSize[priority] < sc_iLimit[priority]) {
  55. /*
  56. * We attempt to allocate enough space for the buffer and the
  57. * Memory object.
  58. */
  59. #ifdef DEBUG
  60. memory = (PMemory) new BYTE[length + sizeof (Memory)];
  61. #else // DEBUG
  62. memory = (PMemory) LocalAlloc (LMEM_FIXED, length + sizeof (Memory));
  63. #endif // DEBUG
  64. }
  65. else {
  66. /*
  67. * The application has attempted to allocate past its limit
  68. * It is necessary to fail the request.
  69. */
  70. memory = NULL;
  71. WARNING_OUT (("AllocateMemory: attempt to allocate past the allowable limit. "
  72. "Request: %d. Currently allocated: %d. Priority: %d",
  73. length, s_anCurrentSize[priority], priority));
  74. }
  75. /*
  76. * Check to see whether the allocation was successful.
  77. */
  78. if (memory != NULL) {
  79. #ifdef DEBUG
  80. s_TotalSize += (int) length;
  81. #endif // DEBUG
  82. /*
  83. * Update the currently allocated size. Notice that we only
  84. * do this for buffers used in the send/recv code path in
  85. * MCS. Since this is only one thread, we do not have to
  86. * use a critical section to protect the size variable.
  87. */
  88. ASSERT (s_anCurrentSize[priority] >= 0);
  89. s_anCurrentSize[priority] += (int) length;
  90. copy_ptr = (PUChar) memory + sizeof(Memory);
  91. memory->Init (reference_ptr, length, priority, copy_ptr);
  92. TRACE_OUT (("Allocate: successful request. "
  93. "Request: %d. Currently allocated: %d. Total: %d. Priority: %d",
  94. length, s_anCurrentSize[priority], s_TotalSize, priority));
  95. TRACE_OUT (("AllocateMemory: buffer at address %p; memory segment at address %p",
  96. copy_ptr, memory));
  97. }
  98. else {
  99. /*
  100. * We failed to allocate the requested size
  101. * It is necessary to fail the request.
  102. */
  103. WARNING_OUT (("AllocateMemory: failed to allocated buffer. We are out of system memory. "
  104. "Request: %d. Last error: %d",
  105. length, GetLastError()));
  106. }
  107. return (memory);
  108. }
  109. /*
  110. * PUChar ReAllocate ()
  111. *
  112. * Public
  113. *
  114. * Functional Description:
  115. * This function is used to re-allocate a buffer with a Memory
  116. * (buffer header) object. The buffer must have been allocated by
  117. * a call to AllocateMemory. This call assumes RECV_PRIORITY. However,
  118. * it's not restricted in allocations, because, if it did, this might
  119. * cause deadlocks (some memory has already been allocated for the
  120. * new arriving data).
  121. */
  122. BOOL ReAllocateMemory (PMemory *pmemory,
  123. UINT length)
  124. {
  125. PUChar copy_ptr = NULL;
  126. UINT new_length;
  127. MemoryPriority priority;
  128. ASSERT (length > 0);
  129. ASSERT (pmemory != NULL);
  130. ASSERT (*pmemory != NULL);
  131. ASSERT ((*pmemory)->GetPointer());
  132. new_length = length + (*pmemory)->GetLength();
  133. priority = (*pmemory)->GetMemoryPriority();
  134. ASSERT (priority == RECV_PRIORITY);
  135. // We attempt to allocate enough space for the buffer.
  136. #ifdef DEBUG
  137. copy_ptr = (PUChar) new BYTE[new_length + sizeof(Memory)];
  138. if (copy_ptr != NULL) {
  139. memcpy (copy_ptr, *pmemory, (*pmemory)->GetLength() + sizeof(Memory));
  140. delete [] (BYTE *) *pmemory;
  141. }
  142. #else // DEBUG
  143. copy_ptr = (PUChar) LocalReAlloc ((HLOCAL) *pmemory,
  144. new_length + sizeof(Memory),
  145. LMEM_MOVEABLE);
  146. #endif // DEBUG
  147. /*
  148. * Check to see whether the allocation was successful.
  149. */
  150. if (copy_ptr != NULL) {
  151. #ifdef DEBUG
  152. s_TotalSize += (int) length;
  153. #endif // DEBUG
  154. /*
  155. * Update the currently allocated size.
  156. */
  157. ASSERT (s_anCurrentSize[priority] >= 0);
  158. s_anCurrentSize[priority] += (int) length;
  159. *pmemory = (PMemory) copy_ptr;
  160. copy_ptr += sizeof (Memory);
  161. (*pmemory)->Init (NULL, new_length, priority, copy_ptr);
  162. TRACE_OUT (("ReAllocate: successful request. "
  163. "Request: %d. Currently allocated: %d. Total: %d",
  164. length, s_anCurrentSize[priority], s_TotalSize));
  165. TRACE_OUT (("ReAllocate: buffer at address %p; memory segment at address %p",
  166. copy_ptr, *pmemory));
  167. }
  168. else {
  169. /*
  170. * We failed to allocate the requested size
  171. * It is necessary to fail the request.
  172. */
  173. WARNING_OUT (("ReAllocate: failed to allocated buffer. We are out of system memory. "
  174. "Request: %d. Currently allocated: %d. Last error: %d",
  175. length, s_anCurrentSize[priority], GetLastError()));
  176. }
  177. return (copy_ptr != NULL);
  178. }
  179. /*
  180. * Void FreeMemory ()
  181. *
  182. * Public
  183. *
  184. * Functional Description:
  185. * This function is used to release a previously allocated Memory object.
  186. */
  187. void FreeMemory (PMemory memory)
  188. {
  189. if (memory != NULL) {
  190. ASSERT (SIGNATURE_MATCH(memory, MemorySignature));
  191. ASSERT (memory->GetPointer() == (PUChar) memory + sizeof(Memory));
  192. if (memory->Unlock() == 0) {
  193. MemoryPriority priority = memory->GetMemoryPriority();
  194. TRACE_OUT (("FreeMemory: buffer at address %p (memory segment at address %p) freed. Size: %d. ",
  195. memory->GetPointer(), memory, memory->GetLength()));
  196. // We may need to adjust the variable tracking the allocated amount of mem.
  197. ASSERT (s_anCurrentSize[priority] >= (int) memory->GetLength());
  198. s_anCurrentSize[priority] -= memory->GetLength();
  199. ASSERT(s_anCurrentSize[priority] >= 0);
  200. #ifdef DEBUG
  201. s_TotalSize -= memory->GetLength();
  202. #endif // DEBUG
  203. TRACE_OUT(("FreeMemory: Currently allocated: %d. Total: %d.",
  204. s_anCurrentSize[priority], s_TotalSize));
  205. // free the buffer, and the memory
  206. #ifdef DEBUG
  207. delete [] (BYTE *) memory;
  208. #else // DEBUG
  209. LocalFree ((HLOCAL) memory);
  210. #endif // DEBUG
  211. }
  212. }
  213. }
  214. #ifdef DEBUG
  215. /*
  216. * PUChar Allocate ()
  217. *
  218. * Public
  219. *
  220. * Functional Description:
  221. * This function is used to allocate a buffer without a Memory
  222. * (buffer header) object.
  223. */
  224. PUChar Allocate (UINT length)
  225. {
  226. PUChar copy_ptr;
  227. ASSERT (length > 0);
  228. // We attempt to allocate enough space for the buffer.
  229. copy_ptr = (PUChar) new BYTE[length];
  230. /*
  231. * Check to see whether the allocation was successful.
  232. */
  233. if (copy_ptr == NULL) {
  234. /*
  235. * We failed to allocate the requested size
  236. * It is necessary to fail the request.
  237. */
  238. ERROR_OUT (("Allocate: failed to allocated buffer. We are out of system memory. "
  239. "Request: %d. Last error: %d",
  240. length, GetLastError()));
  241. }
  242. return (copy_ptr);
  243. }
  244. #endif // DEBUG
  245. /*
  246. * UINT GetFreeMemory ()
  247. *
  248. * Public
  249. *
  250. * Functional Description:
  251. * This function returns the amount of space that can still be
  252. * allocated at the given priority level. The function should be
  253. * called only when send/recv space is allocated.
  254. */
  255. UINT GetFreeMemory (MemoryPriority priority)
  256. {
  257. int idiff;
  258. ASSERT (priority != HIGHEST_PRIORITY);
  259. idiff = sc_iLimit[priority] - s_anCurrentSize[priority];
  260. return ((idiff > 0) ? (UINT) idiff : 0);
  261. }
  262.