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.

195 lines
3.5 KiB

  1. /*==========================================================================
  2. *
  3. * Copyright (C) 1995 - 1997 Microsoft Corporation. All Rights Reserved.
  4. *
  5. * File: fpm.c
  6. * Content: fixed size pool manager
  7. *
  8. * History:
  9. * Date By Reason
  10. * ====== == ======
  11. * 12-18-97 aarono Original
  12. ***************************************************************************/
  13. #include "windows.h"
  14. #include "dpsp.h"
  15. #include "fpm.h"
  16. #ifdef SENDEX
  17. BOOL FN_BOOL_DUMMY(void *pvItem)
  18. {
  19. return TRUE;
  20. }
  21. VOID FN_VOID_DUMMY(void *pvItem)
  22. {
  23. return;
  24. }
  25. void * FPM_Get(LPFPOOL this)
  26. {
  27. void * pvItem;
  28. EnterCriticalSection(&this->cs);
  29. if(!this->pPool){
  30. LeaveCriticalSection(&this->cs);
  31. pvItem = GlobalAlloc(GPTR, this->cbItemSize);
  32. if((pvItem) && !(*this->fnBlockInitAlloc)(pvItem) ){
  33. GlobalFree(pvItem);
  34. pvItem=NULL;
  35. }
  36. EnterCriticalSection(&this->cs);
  37. if(pvItem){
  38. this->nAllocated++;
  39. }
  40. } else {
  41. pvItem=this->pPool;
  42. this->pPool=*((void **)pvItem);
  43. }
  44. if(pvItem){
  45. (*this->fnBlockInit)(pvItem);
  46. this->nInUse++;
  47. if(this->nInUse > this->nMaxInUse){
  48. this->nMaxInUse = this->nInUse;
  49. }
  50. }
  51. LeaveCriticalSection(&this->cs);
  52. return pvItem;
  53. }
  54. #ifdef DEBUG
  55. void DebugCheckList(void *pvList, void *pvItem)
  56. {
  57. void *pvWalker;
  58. DWORD n=0;
  59. pvWalker=pvList;
  60. while(pvWalker){
  61. if(pvWalker==pvItem){
  62. DPF(0,"ERROR: Found Item %x in List %x, item # %d\n",pvList,pvItem,n);
  63. DEBUG_BREAK();
  64. }
  65. n++;
  66. pvWalker=*((void **)pvWalker);
  67. }
  68. }
  69. #else
  70. #define DebugCheckList()
  71. #endif
  72. void FPM_Release(LPFPOOL this, void *pvItem)
  73. {
  74. EnterCriticalSection(&this->cs);
  75. DebugCheckList(this->pPool, pvItem); //BUGBUG: debug only.
  76. this->nInUse--;
  77. *((void**)pvItem)=this->pPool;
  78. this->pPool=pvItem;
  79. LeaveCriticalSection(&this->cs);
  80. }
  81. void FPM_Scale(LPFPOOL this)
  82. {
  83. void * pvItem;
  84. if(!InterlockedExchange(&this->bInScale,1)){
  85. EnterCriticalSection(&this->cs);
  86. while((this->nAllocated > this->nMaxInUse) && this->pPool){
  87. pvItem = this->pPool;
  88. this->pPool=*((void **)pvItem);
  89. LeaveCriticalSection(&this->cs);
  90. (*this->fnBlockFini)(pvItem);
  91. GlobalFree(pvItem);
  92. EnterCriticalSection(&this->cs);
  93. this->nAllocated--;
  94. }
  95. this->nMaxInUse=this->nInUse;
  96. LeaveCriticalSection(&this->cs);
  97. InterlockedExchange(&this->bInScale,0);
  98. }
  99. }
  100. VOID FPM_Fini(LPFPOOL this, int bFORCE)
  101. {
  102. void *pvItem;
  103. while(this->pPool){
  104. pvItem = this->pPool;
  105. this->pPool=*((void **)pvItem);
  106. (*this->fnBlockFini)(pvItem);
  107. GlobalFree(pvItem);
  108. this->nAllocated--;
  109. }
  110. if(this->nAllocated){
  111. DPF(0,"WSOCK: Exiting with unfreed FPM pool items\n");
  112. }
  113. DeleteCriticalSection(&this->cs);
  114. GlobalFree(this);
  115. }
  116. LPFPOOL FPM_Init(
  117. unsigned int size,
  118. FN_BLOCKINITALLOC fnBlockInitAlloc,
  119. FN_BLOCKINIT fnBlockInit,
  120. FN_BLOCKFINI fnBlockFini)
  121. {
  122. LPFPOOL pPool;
  123. if(!(pPool=(LPFPOOL)GlobalAlloc(GPTR,sizeof(FPOOL))))
  124. {
  125. return NULL;
  126. }
  127. InitializeCriticalSection(&pPool->cs);
  128. // by zero init.
  129. //pPool.pPool = NULL;
  130. //pPool.nAllocated = 0;
  131. //pPool.nInUse = 0;
  132. //pPool.nMaxInUse = 0;
  133. //pPool.bInScale = FALSE;
  134. if(fnBlockInitAlloc){
  135. pPool->fnBlockInitAlloc = fnBlockInitAlloc;
  136. } else {
  137. pPool->fnBlockInitAlloc = FN_BOOL_DUMMY;
  138. }
  139. if(fnBlockInit){
  140. pPool->fnBlockInit = fnBlockInit;
  141. } else {
  142. pPool->fnBlockInit = FN_VOID_DUMMY;
  143. }
  144. if(fnBlockFini){
  145. pPool->fnBlockFini = fnBlockFini;
  146. } else {
  147. pPool->fnBlockFini = FN_VOID_DUMMY;
  148. }
  149. pPool->Get = FPM_Get;
  150. pPool->Release= FPM_Release;
  151. pPool->Scale = FPM_Scale;
  152. pPool->Fini = FPM_Fini;
  153. pPool->cbItemSize = size;
  154. return pPool;
  155. }
  156. #endif