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.

179 lines
4.5 KiB

  1. /*++
  2. Copyright (C) Microsoft Corporation, 1997 - 1999
  3. Module Name:
  4. bcache.hxx
  5. Abstract:
  6. Cached buffer allocation class
  7. Author:
  8. Mario Goertzel [MarioGo]
  9. Revision History:
  10. MarioGo 9/7/1997 Bits 'n pieces
  11. GrigoriK 6/2002 Removed paged bcache and replaced with read-only paged heap.
  12. --*/
  13. #ifndef __BCACHE_HXX
  14. #define __BCACHE_HXX
  15. //
  16. // The RPC buffer cache uses several levels of caching to improve
  17. // performance. The cache has either 2 or 4 fixed buffer sizes that
  18. // it caches. The first level of cache is per-thread. The second
  19. // level is process wide.
  20. //
  21. // Their are two performance goals: make a single alloc/free loop
  22. // execute with a minimum of cycles and scale well on MP machines.
  23. // This implementation can do 8000000 allocs in 761ms using 8 threads
  24. // on a 4xPPro 200.
  25. //
  26. // In the default mode, elements which are the right size for various
  27. // runtime allocations as cached.
  28. //
  29. // Under paged heap or under RPC verifier with the appropriate settings
  30. // all allocations will be done on a read-only paged heap. This is similar
  31. // to the regular paged heap, except the guard page is read-only.
  32. // This allows NDR to temporarily read past the end of the buffer without
  33. // raising exceptions, but writes will AV.
  34. //
  35. struct BUFFER_CACHE_HINTS
  36. {
  37. // When the thread cache is empty, this many blocks are moved
  38. // from the global cache (if possible) to the thread cache.
  39. // When freeing from the thread cache, this many buffers
  40. // are left in the thread cache.
  41. UINT cLowWatermark;
  42. // When per thread cache will reach mark due to a free, blocks
  43. // will be moved to the global cache.
  44. UINT cHighWatermark;
  45. // Summary: The difference between high and low is the number
  46. // of blocks allocated/freed from the global cache at a time.
  47. //
  48. // Lowwater should be the average number of free buffers - 1
  49. // you expect a thread to have. Highwater should be the
  50. // maximum number of free buffers + 1 you expect a thread
  51. // to need.
  52. //
  53. // **** Note: The difference must be two or more. ***
  54. // Example: 1 3
  55. // Alloc called with the thread cache empty, two blocks are removed
  56. // from the global list. One is saved the thread list. The other
  57. // is returned.
  58. //
  59. // Free called with two free buffers in the thread list. A total
  60. // of three buffers. Two buffers are moved to the global cache, one
  61. // stays in the thread cache.
  62. //
  63. //
  64. // The size of the buffers
  65. UINT cSize;
  66. };
  67. extern CONST BUFFER_CACHE_HINTS gCacheHints[4];
  68. extern BUFFER_CACHE_HINTS *pHints;
  69. // Used in all modes, sits at the front of the buffer allocation.
  70. struct BUFFER_HEAD
  71. {
  72. union {
  73. BUFFER_HEAD *pNext; // Valid only in free lists
  74. INT index; // Valid only when allocated
  75. // 1-4 for cachable, -1 for big
  76. };
  77. SIZE_T size; // if index == -1, this is the size. Used only
  78. // for debugging.
  79. };
  80. typedef BUFFER_HEAD *PBUFFER;
  81. // This structure is imbedded into the RPC thread object
  82. struct BCACHE_STATE
  83. {
  84. BUFFER_HEAD *pList;
  85. ULONG cBlocks;
  86. };
  87. // The strucutre parrallels the global cache
  88. struct BCACHE_STATS
  89. {
  90. UINT cBufferCacheCap;
  91. UINT cAllocationHits;
  92. UINT cAllocationMisses;
  93. };
  94. class THREAD;
  95. class BCACHE
  96. {
  97. private:
  98. BCACHE_STATE _bcGlobalState[4];
  99. BCACHE_STATS _bcGlobalStats[4];
  100. MUTEX _csBufferCacheLock;
  101. PVOID AllocHelper(size_t, INT, BCACHE_STATE *);
  102. VOID FreeHelper(PVOID, INT, BCACHE_STATE *);
  103. VOID FreeBuffers(PBUFFER, INT, UINT);
  104. PBUFFER AllocBlock(IN size_t);
  105. VOID FreeBlock(IN PBUFFER);
  106. PBUFFER
  107. BCACHE::AllocPagedBCacheSection (
  108. IN UINT size,
  109. IN ULONG OriginalSize
  110. );
  111. ULONG
  112. GetSegmentIndexFromBuffer (
  113. IN PBUFFER pBuffer,
  114. IN PVOID Allocation
  115. );
  116. public:
  117. BCACHE(RPC_STATUS &);
  118. ~BCACHE();
  119. PVOID Allocate(CONST size_t cSize);
  120. VOID Free(PVOID);
  121. VOID ThreadDetach(THREAD *);
  122. };
  123. extern BCACHE *gBufferCache;
  124. // Helper APIs
  125. inline PVOID
  126. RpcAllocateBuffer(CONST size_t cSize)
  127. {
  128. return(gBufferCache->Allocate(cSize));
  129. }
  130. inline VOID
  131. RpcFreeBuffer(PVOID pBuffer)
  132. {
  133. if (pBuffer == 0)
  134. {
  135. return;
  136. }
  137. gBufferCache->Free(pBuffer);
  138. }
  139. #endif // __BCACHE_HXX