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.

257 lines
5.0 KiB

  1. /*++
  2. Copyright (c) 1996,1997 Microsoft Corporation
  3. Module Name:
  4. FRAMEBUF.CPP
  5. Abstract:
  6. Manages Memory for Send/Receive Frames.
  7. ISSUE: when you have time do an intelligent implementation,
  8. for now this is just a frame cache.
  9. - not likely now, DP4 is being put to bed AO 04/03/2001
  10. Author:
  11. Aaron Ogus (aarono)
  12. Environment:
  13. Win32/COM
  14. Revision History:
  15. Date Author Description
  16. ====== ====== ============================================================
  17. 12/10/96 aarono Original
  18. 6/6/98 aarono More debug checks, shrink pool.
  19. --*/
  20. #include <windows.h>
  21. #include "newdpf.h"
  22. #include <dplay.h>
  23. #include <dplaysp.h>
  24. #include <dplaypr.h>
  25. #include "mydebug.h"
  26. #include "bufmgr.h"
  27. #include "macros.h"
  28. #define MAX_FRAMES_ON_LIST 16
  29. #define MIN_FRAMES_ON_LIST 8
  30. typedef struct _frame
  31. {
  32. BILINK Bilink;
  33. UINT len;
  34. UCHAR data[0];
  35. } FRAME, *PFRAME;
  36. BILINK FrameList;
  37. UINT nFramesOnList=0;
  38. UINT TotalFrameMemory=0;
  39. CRITICAL_SECTION FrameLock;
  40. #ifdef DEBUG
  41. void DebugChkFrameList()
  42. {
  43. BILINK *pBilink;
  44. PFRAME pFrameWalker;
  45. DWORD count=0;
  46. DWORD totalsize=0;
  47. DWORD fBreak=FALSE;
  48. Lock(&FrameLock);
  49. pBilink=FrameList.next;
  50. while(pBilink != &FrameList){
  51. pFrameWalker=CONTAINING_RECORD(pBilink,FRAME,Bilink);
  52. pBilink=pBilink->next;
  53. count++;
  54. totalsize+=pFrameWalker->len;
  55. }
  56. if(totalsize != TotalFrameMemory){
  57. DPF(0, "Total Frame Memory says %d but I count %d\n",TotalFrameMemory, totalsize);
  58. fBreak=TRUE;
  59. }
  60. if(count != nFramesOnList){
  61. DPF(0, "nFramesOnList %d but I count %d\n",nFramesOnList, count);
  62. fBreak=TRUE;
  63. }
  64. if(fBreak){
  65. DEBUG_BREAK();
  66. }
  67. Unlock(&FrameLock);
  68. }
  69. #else
  70. #define DebugChkFrameList()
  71. #endif
  72. VOID InitFrameBuffers(VOID)
  73. {
  74. InitBilink(&FrameList);
  75. InitializeCriticalSection(&FrameLock);
  76. nFramesOnList=0;
  77. TotalFrameMemory=0;
  78. }
  79. VOID FiniFrameBuffers(VOID)
  80. {
  81. BILINK *pBilink;
  82. PFRAME pFrame;
  83. Lock(&FrameLock);
  84. while(!EMPTY_BILINK(&FrameList)){
  85. pBilink=FrameList.next;
  86. pFrame=CONTAINING_RECORD(pBilink,FRAME,Bilink);
  87. Delete(pBilink);
  88. My_GlobalFree(pFrame);
  89. }
  90. nFramesOnList=0;
  91. TotalFrameMemory=0;
  92. Unlock(&FrameLock);
  93. DeleteCriticalSection(&FrameLock);
  94. }
  95. VOID ReleaseFrameBufferMemory(PUCHAR pFrameData)
  96. {
  97. PFRAME pFrame;
  98. BILINK FramesToFree;
  99. BILINK *pBilink;
  100. Lock(&FrameLock);
  101. DebugChkFrameList();
  102. InitBilink(&FramesToFree);
  103. pFrame=CONTAINING_RECORD(pFrameData,FRAME,data);
  104. InsertAfter(&pFrame->Bilink, &FrameList);
  105. nFramesOnList++;
  106. TotalFrameMemory+=pFrame->len;
  107. if(nFramesOnList > MAX_FRAMES_ON_LIST){
  108. while(nFramesOnList > MIN_FRAMES_ON_LIST){
  109. pBilink=FrameList.next;
  110. pFrame=CONTAINING_RECORD(pBilink,FRAME,Bilink);
  111. nFramesOnList--;
  112. TotalFrameMemory-=pFrame->len;
  113. Delete(pBilink);
  114. DebugChkFrameList();
  115. InsertAfter(pBilink, &FramesToFree);
  116. }
  117. }
  118. DebugChkFrameList();
  119. ASSERT(nFramesOnList);
  120. Unlock(&FrameLock);
  121. // Drop lock before freeing, to make more effecient.
  122. while(!EMPTY_BILINK(&FramesToFree)){
  123. pBilink=FramesToFree.next;
  124. pFrame=CONTAINING_RECORD(pBilink,FRAME,Bilink);
  125. Delete(pBilink);
  126. My_GlobalFree(pFrame);
  127. }
  128. DebugChkFrameList();
  129. }
  130. PBUFFER GetFrameBuffer(UINT FrameLen)
  131. {
  132. PBUFFER pBuffer;
  133. PFRAME pFrame;
  134. MEMDESC memdesc;
  135. BILINK *pBilinkWalker;
  136. PFRAME pFrameBest=NULL, pFrameWalker;
  137. UINT difference=FrameLen;
  138. DPF(9,"==>GetFrameBuffer Len %d\n",FrameLen);
  139. Lock(&FrameLock);
  140. if(!EMPTY_BILINK(&FrameList)){
  141. ASSERT(nFramesOnList);
  142. pBilinkWalker=FrameList.next;
  143. while(pBilinkWalker != &FrameList){
  144. pFrameWalker=CONTAINING_RECORD(pBilinkWalker, FRAME, Bilink);
  145. if(pFrameWalker->len >= FrameLen){
  146. if(FrameLen-pFrameWalker->len < difference){
  147. difference=FrameLen-pFrameWalker->len;
  148. pFrameBest=pFrameWalker;
  149. if(!difference){
  150. break;
  151. }
  152. }
  153. }
  154. pBilinkWalker=pBilinkWalker->next;
  155. }
  156. if(!pFrameBest){
  157. goto alloc_new_frame;
  158. } else {
  159. pFrame=pFrameBest;
  160. }
  161. DebugChkFrameList();
  162. Delete(&pFrame->Bilink);
  163. nFramesOnList--;
  164. TotalFrameMemory-=pFrame->len;
  165. DebugChkFrameList();
  166. Unlock(&FrameLock);
  167. } else {
  168. alloc_new_frame:
  169. Unlock(&FrameLock);
  170. pFrame=(PFRAME)My_GlobalAlloc(GMEM_FIXED,FrameLen+sizeof(FRAME));
  171. if(!pFrame){
  172. return NULL;
  173. }
  174. pFrame->len=FrameLen;
  175. }
  176. memdesc.pData=&pFrame->data[0];
  177. memdesc.len=pFrame->len;
  178. pBuffer=BuildBufferChain((&memdesc),1);
  179. if(!pBuffer){
  180. ReleaseFrameBufferMemory(pFrame->data);
  181. DPF(9,"<==GetFrameBuffer FAILED returning %x\n",pBuffer);
  182. } else {
  183. pBuffer->dwFlags |= BFLAG_FRAME;
  184. DPF(9,"<==GetFrameBuffer %x, len %d\n",pBuffer, pFrame->len);
  185. }
  186. DebugChkFrameList();
  187. return pBuffer;
  188. }
  189. // Release the buffer, put the memory back on the frame buffer list.
  190. VOID FreeFrameBuffer(PBUFFER pBuffer)
  191. {
  192. ASSERT(pBuffer->dwFlags & BFLAG_FRAME);
  193. ReleaseFrameBufferMemory(pBuffer->pData);
  194. FreeBuffer(pBuffer);
  195. }