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.

282 lines
5.4 KiB

  1. /*++
  2. Copyright (c) 1998, Microsoft Corporation
  3. Module Name:
  4. buffer.c
  5. Abstract:
  6. This module contains code for buffer-management.
  7. Author:
  8. Abolade Gbadegesin (aboladeg) 2-Mar-1998
  9. Revision History:
  10. --*/
  11. #include "precomp.h"
  12. #include "list.h"
  13. #pragma hdrstop
  14. #define NH_ALLOCATE(s) HeapAlloc(GetProcessHeap(), 0, (s))
  15. #define NH_FREE(p) HeapFree(GetProcessHeap(), 0, (p))
  16. LIST_ENTRY MyHelperpBufferQueue;
  17. LONG MyHelperpBufferQueueLength;
  18. CRITICAL_SECTION MyHelperpBufferQueueLock;
  19. PNH_BUFFER
  20. MyHelperAcquireFixedLengthBuffer(
  21. VOID
  22. )
  23. /*++
  24. Routine Description:
  25. This routine is invoked to acquire an I/O buffer.
  26. If no buffer is available on the buffer queue, a new one is obtained.
  27. Arguments:
  28. none.
  29. Return Value:
  30. PNH_BUFFER - the buffer allocated
  31. --*/
  32. {
  33. MYTRACE_ENTER_NOSHOWEXIT("MyHelperAcquireFixedLengthBuffer");
  34. PNH_BUFFER Buffer;
  35. PLIST_ENTRY Link;
  36. EnterCriticalSection(&MyHelperpBufferQueueLock);
  37. if ( !IsListEmpty(&MyHelperpBufferQueue) )
  38. {
  39. Link = RemoveHeadList(&MyHelperpBufferQueue);
  40. LeaveCriticalSection(&MyHelperpBufferQueueLock);
  41. InterlockedDecrement(&MyHelperpBufferQueueLength);
  42. Buffer = CONTAINING_RECORD(Link, NH_BUFFER, Link);
  43. Buffer->Type = MyHelperFixedLengthBufferType;
  44. return Buffer;
  45. }
  46. LeaveCriticalSection(&MyHelperpBufferQueueLock);
  47. Buffer = NH_ALLOCATE_BUFFER();
  48. if (Buffer) {
  49. Buffer->Type = MyHelperFixedLengthBufferType;
  50. }
  51. return Buffer;
  52. } // MyHelperAcquireFixedLengthBuffer
  53. PNH_BUFFER
  54. MyHelperAcquireVariableLengthBuffer(
  55. ULONG Length
  56. )
  57. /*++
  58. Routine Description:
  59. This routine is invoked to acquire an I/O buffer of non-standard size.
  60. If the length requested is less than or equal to 'NH_BUFFER_SIZE',
  61. a buffer from the shared buffer-queue is returned.
  62. Otherwise, a buffer is especially allocated for the caller.
  63. Arguments:
  64. Length - the length of the buffer required.
  65. Return Value:
  66. PNH_BUFFER - the buffer allocated.
  67. --*/
  68. {
  69. MYTRACE_ENTER_NOSHOWEXIT(">>>MyHelperAcquireVariableLengthBuffer");
  70. PNH_BUFFER Buffer;
  71. if (Length <= NH_BUFFER_SIZE) {
  72. return MyHelperAcquireFixedLengthBuffer();
  73. }
  74. Buffer = reinterpret_cast<PNH_BUFFER>(
  75. NH_ALLOCATE(FIELD_OFFSET(NH_BUFFER, Buffer[Length]))
  76. );
  77. if (Buffer) { Buffer->Type = MyHelperVariableLengthBufferType; }
  78. return Buffer;
  79. } // MyHelperAcquireVariableLengthBuffer
  80. PNH_BUFFER
  81. MyHelperDuplicateBuffer(
  82. PNH_BUFFER Bufferp
  83. )
  84. /*++
  85. Routine Description:
  86. This routine creates a duplicate of the given buffer,
  87. including both its data and its control information.
  88. N.B. Variable-length buffers cannot be duplicated by this routine.
  89. Arguments:
  90. Bufferp - the buffer to be duplicated
  91. Return Value:
  92. PNH_BUFFER - a pointer to the duplicate
  93. --*/
  94. {
  95. PNH_BUFFER Duplicatep;
  96. _ASSERT(Bufferp->Type == MyHelperFixedLengthBufferType);
  97. if (!(Duplicatep = MyHelperAcquireBuffer()))
  98. {
  99. return NULL;
  100. }
  101. *Duplicatep = *Bufferp;
  102. return Duplicatep;
  103. } // MyHelperDuplicateBuffer
  104. ULONG
  105. MyHelperInitializeBufferManagement(
  106. VOID
  107. )
  108. /*++
  109. Routine Description:
  110. This routine readies the buffer-management for operation.
  111. Arguments:
  112. none.
  113. Return Value:
  114. ULONG - Win32 status code.
  115. --*/
  116. {
  117. ULONG Error = NO_ERROR;
  118. InitializeListHead(&MyHelperpBufferQueue);
  119. MyHelperpBufferQueueLength = 0;
  120. __try
  121. {
  122. InitializeCriticalSection(&MyHelperpBufferQueueLock);
  123. }
  124. __except(EXCEPTION_EXECUTE_HANDLER)
  125. {
  126. //MyHelperTrace(
  127. //TRACE_FLAG_BUFFER,
  128. //"MyHelperInitializeBufferManagement: exception %d creating lock",
  129. //Error = GetExceptionCode()
  130. //);
  131. }
  132. return Error;
  133. } // MyHelperInitializeBufferManagement
  134. VOID
  135. MyHelperReleaseBuffer(
  136. PNH_BUFFER Bufferp
  137. )
  138. /*++
  139. Routine Description:
  140. This routine is called to release a buffer to the buffer queue.
  141. It attempts to place the buffer on the queue for re-use, unless
  142. the queue is full in which case the buffer is immediately freed.
  143. Arguments:
  144. Bufferp - the buffer to be released
  145. Return Value:
  146. none.
  147. --*/
  148. {
  149. MYTRACE_ENTER_NOSHOWEXIT("<<<MyHelperReleaseBuffer");
  150. if (MyHelperpBufferQueueLength > NH_MAX_BUFFER_QUEUE_LENGTH || Bufferp->Type != MyHelperFixedLengthBufferType)
  151. {
  152. NH_FREE_BUFFER(Bufferp);
  153. }
  154. else
  155. {
  156. EnterCriticalSection(&MyHelperpBufferQueueLock);
  157. InsertHeadList(&MyHelperpBufferQueue, &Bufferp->Link);
  158. LeaveCriticalSection(&MyHelperpBufferQueueLock);
  159. InterlockedIncrement(&MyHelperpBufferQueueLength);
  160. }
  161. } // MyHelperReleaseBuffer
  162. VOID
  163. MyHelperShutdownBufferManagement(
  164. VOID
  165. )
  166. /*++
  167. Routine Description:
  168. This routine cleans up resources used by the buffer-management module.
  169. It assumes the list will not be accessed while the clean up is in progress.
  170. Arguments:
  171. none.
  172. Return Value:
  173. none.
  174. --*/
  175. {
  176. PLIST_ENTRY Link;
  177. PNH_BUFFER Bufferp;
  178. while (!IsListEmpty(&MyHelperpBufferQueue))
  179. {
  180. Link = RemoveHeadList(&MyHelperpBufferQueue);
  181. Bufferp = CONTAINING_RECORD(Link, NH_BUFFER, Link);
  182. NH_FREE_BUFFER(Bufferp);
  183. }
  184. DeleteCriticalSection(&MyHelperpBufferQueueLock);
  185. MyHelperpBufferQueueLength = 0;
  186. } // MyHelperShutdownBufferManagement