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.

263 lines
8.0 KiB

  1. #ifndef _CACHE_HPP_
  2. #define _CACHE_HPP_
  3. // Ruler
  4. // 1 2 3 4 5 6 7 8
  5. //345678901234567890123456789012345678901234567890123456789012345678901234567890
  6. /********************************************************************/
  7. /* */
  8. /* The standard layout. */
  9. /* */
  10. /* The standard layout for 'hpp' files for this code is as */
  11. /* follows: */
  12. /* */
  13. /* 1. Include files. */
  14. /* 2. Constants exported from the class. */
  15. /* 3. Data structures exported from the class. */
  16. /* 4. Forward references to other data structures. */
  17. /* 5. Class specifications (including inline functions). */
  18. /* 6. Additional large inline functions. */
  19. /* */
  20. /* Any portion that is not required is simply omitted. */
  21. /* */
  22. /********************************************************************/
  23. #include "Global.hpp"
  24. #include "Bucket.hpp"
  25. #include "Find.hpp"
  26. #include "NewPage.hpp"
  27. /********************************************************************/
  28. /* */
  29. /* The allocation cache. */
  30. /* */
  31. /* The memory allocation cache consists of two stacks. The */
  32. /* first stack contains preallocated elements which are */
  33. /* available for use. The second stack contains elements */
  34. /* which have been deallocated and are about to be recycled. */
  35. /* */
  36. /********************************************************************/
  37. class CACHE : public BUCKET
  38. {
  39. //
  40. // Private data.
  41. //
  42. // A cache sits on top of a bucket and shields
  43. // it from being swamped by calls. The 'Active'
  44. // flag is set when the cache is active. The
  45. // 'Stealing' flag indicates that deallocated
  46. // memory can be stolen and reallocated. The
  47. // 'ThreadSafe' flag indicates that locking is
  48. // required.
  49. //
  50. BOOLEAN Active;
  51. BOOLEAN Stealing;
  52. BOOLEAN ThreadSafe;
  53. #ifdef ENABLE_HEAP_STATISTICS
  54. //
  55. // When we are collecting statistics we enable
  56. // the following variables. The 'CacheFills'
  57. // count keeps track of the number of times
  58. // the cache was filled from the bucket. The
  59. // 'CacheFlushes' count keeps track of the
  60. // number of times the cache flushed deleted
  61. // elements to the bucket. The 'HighTide' count
  62. // keeps track the the highest number of outstanding
  63. // allocations since the last "DeleteAll()'. The
  64. // 'HighWater' count keeps track of the maximum
  65. // number of allocations at any point. The
  66. // 'InUse' counts the the current number of outstanding
  67. // allocations.
  68. //
  69. SBIT32 CacheFills;
  70. SBIT32 CacheFlushes;
  71. SBIT32 HighTide;
  72. SBIT32 HighWater;
  73. SBIT32 InUse;
  74. #endif
  75. //
  76. // A cache can be controlled by the user. The
  77. // 'CacheSize' controls the number of allocations
  78. // that can be preallocated or queued for
  79. // deletion. The 'NumberOfChildren' is a count
  80. // of the number of caches that allocate space
  81. // from this cache.
  82. //
  83. SBIT16 CacheSize;
  84. SBIT16 FillSize;
  85. SBIT16 NumberOfChildren;
  86. //
  87. // The cache consists of two stacks. The
  88. // 'DeleteStack' contains elements that are
  89. // waiting to be deleted. The 'NewStack'
  90. // contains elements waiting to be allocated.
  91. //
  92. ADDRESS_AND_PAGE *DeleteStack;
  93. VOID **NewStack;
  94. //
  95. // The top of the deleted stack is kept in
  96. // 'TopOfDeleteStack' and the top of the new
  97. // stack is kept in 'TopOfNewStack'.
  98. //
  99. SBIT32 TopOfDeleteStack;
  100. SBIT32 TopOfNewStack;
  101. //
  102. // The 'Spinlock' is a fast lock employed to
  103. // make the cache multi-threaded if 'ThreadSafe'
  104. // is true.
  105. //
  106. SPINLOCK Spinlock;
  107. public:
  108. //
  109. // Public functions.
  110. //
  111. // The cacahe is a subset of the full haep interface
  112. // a certain calls simply bypass it. However, there
  113. // are a few additional functions for cases where the
  114. // cache needs to be notified of significant heap
  115. // events.
  116. //
  117. CACHE
  118. (
  119. SBIT32 NewAllocationSize,
  120. SBIT32 NewCacheSize,
  121. SBIT32 NewChunkSize,
  122. SBIT32 NewPageSize,
  123. BOOLEAN NewStealing,
  124. BOOLEAN NewThreadSafe
  125. );
  126. VOID *CreateDataPage( VOID );
  127. BOOLEAN Delete( VOID *Address,PAGE *Page,SBIT32 Version );
  128. VOID DeleteAll( VOID );
  129. BOOLEAN DeleteDataPage( VOID *Address );
  130. BOOLEAN MultipleNew
  131. (
  132. SBIT32 *Actual,
  133. VOID *Array[],
  134. SBIT32 Requested
  135. );
  136. VOID *New( VOID );
  137. VOID *New( BOOLEAN SubDivided,SBIT32 NewSize = NoSize );
  138. VOID ReleaseSpace( SBIT32 MaxActivePages );
  139. BOOLEAN SearchCache( VOID *Address );
  140. BOOLEAN Truncate( VOID );
  141. VOID UpdateCache
  142. (
  143. FIND *NewFind,
  144. HEAP *NewHeap,
  145. NEW_PAGE *NewPages,
  146. CACHE *NewParentCache
  147. );
  148. ~CACHE( VOID );
  149. //
  150. // Public inline functions.
  151. //
  152. // A cache just like its parent bucket is closely
  153. // coupled to various other classes and provides
  154. // then is vital information.
  155. //
  156. INLINE VOID ClaimCacheLock( VOID )
  157. {
  158. if ( (ThreadSafe) && (Find -> GetLockCount() == 0) )
  159. { Spinlock.ClaimLock(); }
  160. }
  161. INLINE PAGE *FindChildPage( VOID *Address )
  162. {
  163. return Find -> FindPage
  164. (
  165. ((VOID*) (((BIT32) Address) & ~(GetAllocationSize()-1))),
  166. (CACHE*) this
  167. );
  168. }
  169. INLINE PAGE *FindParentPage( VOID *Address )
  170. {
  171. return Find -> FindPage
  172. (
  173. ((VOID*) (((BIT32) Address) & ~(GetPageSize()-1))),
  174. ParentCache
  175. );
  176. }
  177. INLINE SBIT16 GetCacheSize( VOID )
  178. { return CacheSize; }
  179. INLINE SBIT32 GetNumberOfChildren( VOID )
  180. { return NumberOfChildren; }
  181. INLINE VOID ReleaseCacheLock( VOID )
  182. {
  183. if ( (ThreadSafe) && (Find -> GetLockCount() == 0) )
  184. { Spinlock.ReleaseLock(); }
  185. }
  186. INLINE BOOLEAN Walk( SEARCH_PAGE *Details )
  187. { return NewPage -> Walk( Details ); }
  188. #ifdef ENABLE_HEAP_STATISTICS
  189. //
  190. // Cache statistics.
  191. //
  192. // A cache has a collection statistics which it
  193. // uses to measure how it is doing. It is possible
  194. // to get access to this data for the purpose of
  195. // outputing various reports.
  196. //
  197. INLINE SBIT32 GetCacheFills( VOID )
  198. { return CacheFills; }
  199. INLINE SBIT32 GetCacheFlushes( VOID )
  200. { return CacheFlushes; }
  201. INLINE SBIT32 GetHighWater( VOID )
  202. { return HighWater; }
  203. #endif
  204. private:
  205. //
  206. // Private functions.
  207. //
  208. // A cache is initially inactive. If at least one
  209. // allocation request is made it will spring into
  210. // life, allocate any space needed and prepare itself
  211. // for use.
  212. //
  213. VOID CreateCacheStacks( VOID );
  214. #ifdef ENABLE_HEAP_STATISTICS
  215. VOID ComputeHighWater( SBIT32 Size );
  216. #endif
  217. //
  218. // Disabled operations.
  219. //
  220. // All copy constructors and class assignment
  221. // operations are disabled.
  222. //
  223. CACHE( CONST CACHE & Copy );
  224. VOID operator=( CONST CACHE & Copy );
  225. };
  226. #endif