Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

lookasid.c

Go to the documentation of this file.
00001 /*++ 00002 00003 Copyright (c) 1995 Microsoft Corporation 00004 00005 Module Name: 00006 00007 lookasid.c 00008 00009 Abstract: 00010 00011 This module implements heap lookaside list function. 00012 00013 Author: 00014 00015 David N. Cutler (davec) 19-Feb-1995 00016 00017 Revision History: 00018 00019 --*/ 00020 00021 #include "ntrtlp.h" 00022 #include "heap.h" 00023 #include "heappriv.h" 00024 00025 00026 // 00027 // Define Minimum lookaside list depth. 00028 // 00029 00030 #define MINIMUM_LOOKASIDE_DEPTH 4 00031 00032 // 00033 // Define minimum allocation threshold. 00034 // 00035 00036 #define MINIMUM_ALLOCATION_THRESHOLD 25 00037 00038 // 00039 // Define forward referenced function prototypes. 00040 // 00041 00042 00043 00044 VOID 00045 RtlpInitializeHeapLookaside ( 00046 IN PHEAP_LOOKASIDE Lookaside, 00047 IN USHORT Depth 00048 ) 00049 00050 /*++ 00051 00052 Routine Description: 00053 00054 This function initializes a heap lookaside list structure 00055 00056 Arguments: 00057 00058 Lookaside - Supplies a pointer to a heap lookaside list structure. 00059 00060 Allocate - Supplies a pointer to an allocate function. 00061 00062 Free - Supplies a pointer to a free function. 00063 00064 HeapHandle - Supplies a pointer to the heap that backs this lookaside list 00065 00066 Flags - Supplies a set of heap flags. 00067 00068 Size - Supplies the size for the lookaside list entries. 00069 00070 Depth - Supplies the maximum depth of the lookaside list. 00071 00072 Return Value: 00073 00074 None. 00075 00076 --*/ 00077 00078 { 00079 00080 // 00081 // Initialize the lookaside list structure. 00082 // 00083 00084 RtlpInitializeSListHead(&Lookaside->ListHead); 00085 00086 Lookaside->Depth = MINIMUM_LOOKASIDE_DEPTH; 00087 Lookaside->MaximumDepth = 256; //Depth; 00088 Lookaside->TotalAllocates = 0; 00089 Lookaside->AllocateMisses = 0; 00090 Lookaside->TotalFrees = 0; 00091 Lookaside->FreeMisses = 0; 00092 00093 Lookaside->LastTotalAllocates = 0; 00094 Lookaside->LastAllocateMisses = 0; 00095 00096 return; 00097 } 00098 00099 00100 VOID 00101 RtlpDeleteHeapLookaside ( 00102 IN PHEAP_LOOKASIDE Lookaside 00103 ) 00104 00105 /*++ 00106 00107 Routine Description: 00108 00109 This function frees any entries specified by the lookaside structure. 00110 00111 Arguments: 00112 00113 Lookaside - Supplies a pointer to a heap lookaside list structure. 00114 00115 Return Value: 00116 00117 None. 00118 00119 --*/ 00120 00121 { 00122 00123 PVOID Entry; 00124 00125 return; 00126 } 00127 00128 00129 VOID 00130 RtlpAdjustHeapLookasideDepth ( 00131 IN PHEAP_LOOKASIDE Lookaside 00132 ) 00133 00134 /*++ 00135 00136 Routine Description: 00137 00138 This function is called periodically to adjust the maximum depth of 00139 a single heap lookaside list. 00140 00141 Arguments: 00142 00143 Lookaside - Supplies a pointer to a heap lookaside list structure. 00144 00145 Return Value: 00146 00147 None. 00148 00149 --*/ 00150 00151 { 00152 ULONG Allocates; 00153 ULONG Misses; 00154 00155 // 00156 // Compute the total number of allocations and misses for this scan 00157 // period. 00158 // 00159 00160 Allocates = Lookaside->TotalAllocates - Lookaside->LastTotalAllocates; 00161 Lookaside->LastTotalAllocates = Lookaside->TotalAllocates; 00162 Misses = Lookaside->AllocateMisses - Lookaside->LastAllocateMisses; 00163 Lookaside->LastAllocateMisses = Lookaside->AllocateMisses; 00164 00165 // 00166 // Compute target depth of lookaside list. 00167 // 00168 00169 { 00170 ULONG Ratio; 00171 ULONG Target; 00172 00173 // 00174 // If the allocate rate is less than the mimimum threshold, then lower 00175 // the maximum depth of the lookaside list. Otherwise, if the miss rate 00176 // is less than .5%, then lower the maximum depth. Otherwise, raise the 00177 // maximum depth based on the miss rate. 00178 // 00179 00180 if (Misses >= Allocates) { 00181 Misses = Allocates; 00182 } 00183 00184 if (Allocates == 0) { 00185 Allocates = 1; 00186 } 00187 00188 Ratio = (Misses * 1000) / Allocates; 00189 Target = Lookaside->Depth; 00190 if (Allocates < MINIMUM_ALLOCATION_THRESHOLD) { 00191 if (Target > (MINIMUM_LOOKASIDE_DEPTH + 10)) { 00192 Target -= 10; 00193 00194 } else { 00195 Target = MINIMUM_LOOKASIDE_DEPTH; 00196 } 00197 00198 } else if (Ratio < 5) { 00199 if (Target > (MINIMUM_LOOKASIDE_DEPTH + 1)) { 00200 Target -= 1; 00201 00202 } else { 00203 Target = MINIMUM_LOOKASIDE_DEPTH; 00204 } 00205 00206 } else { 00207 Target += ((Ratio * Lookaside->MaximumDepth) / (1000 * 2)) + 5; 00208 if (Target > Lookaside->MaximumDepth) { 00209 Target = Lookaside->MaximumDepth; 00210 } 00211 } 00212 00213 Lookaside->Depth = (USHORT)Target; 00214 } 00215 00216 return; 00217 } 00218 00219 00220 00221 PVOID 00222 RtlpAllocateFromHeapLookaside ( 00223 IN PHEAP_LOOKASIDE Lookaside 00224 ) 00225 00226 /*++ 00227 00228 Routine Description: 00229 00230 This function removes (pops) the first entry from the specified 00231 heap lookaside list. 00232 00233 Arguments: 00234 00235 Lookaside - Supplies a pointer to a paged lookaside list structure. 00236 00237 Return Value: 00238 00239 If an entry is removed from the specified lookaside list, then the 00240 address of the entry is returned as the function value. Otherwise, 00241 NULL is returned. 00242 00243 --*/ 00244 00245 { 00246 00247 PVOID Entry; 00248 00249 Lookaside->TotalAllocates += 1; 00250 00251 // 00252 // We need to protect ourselves from a second thread that can cause us 00253 // to fault on the pop. If we do fault then we'll just do a regular pop 00254 // operation 00255 // 00256 00257 #if defined(_X86_) 00258 00259 if (USER_SHARED_DATA->ProcessorFeatures[PF_COMPARE_EXCHANGE_DOUBLE]) { 00260 00261 #endif // defined(_X86_) 00262 00263 try { 00264 00265 Entry = RtlpInterlockedPopEntrySList(&Lookaside->ListHead); 00266 00267 } except (EXCEPTION_EXECUTE_HANDLER) { 00268 00269 Entry = NULL; 00270 } 00271 00272 if (Entry != NULL) { 00273 00274 return Entry; 00275 } 00276 #if defined(_X86_) 00277 00278 } 00279 00280 #endif // defined(_X86_) 00281 00282 Lookaside->AllocateMisses += 1; 00283 return NULL; 00284 } 00285 00286 00287 BOOLEAN 00288 RtlpFreeToHeapLookaside ( 00289 IN PHEAP_LOOKASIDE Lookaside, 00290 IN PVOID Entry 00291 ) 00292 00293 /*++ 00294 00295 Routine Description: 00296 00297 This function inserts (pushes) the specified entry into the specified 00298 paged lookaside list. 00299 00300 Arguments: 00301 00302 Lookaside - Supplies a pointer to a paged lookaside list structure. 00303 00304 Entry - Supples a pointer to the entry that is inserted in the 00305 lookaside list. 00306 00307 Return Value: 00308 00309 BOOLEAN - TRUE if the entry was put on the lookaside list and FALSE 00310 otherwise. 00311 00312 --*/ 00313 00314 { 00315 Lookaside->TotalFrees += 1; 00316 00317 #if defined(_X86_) 00318 00319 if (USER_SHARED_DATA->ProcessorFeatures[PF_COMPARE_EXCHANGE_DOUBLE]) { 00320 00321 #endif // defined(_X86_) 00322 00323 if (RtlpQueryDepthSList(&Lookaside->ListHead) < Lookaside->Depth) { 00324 00325 // 00326 // We need to protect ourselves from a second thread that can 00327 // cause us to fault on the push. If we do fault then we'll 00328 // just do a regular free operation 00329 // 00330 00331 try { 00332 00333 RtlpInterlockedPushEntrySList(&Lookaside->ListHead, 00334 (PSINGLE_LIST_ENTRY)Entry); 00335 00336 } except (EXCEPTION_EXECUTE_HANDLER) { 00337 00338 Lookaside->FreeMisses += 1; 00339 00340 return FALSE; 00341 } 00342 00343 return TRUE; 00344 } 00345 00346 #if defined(_X86_) 00347 00348 } 00349 00350 #endif // defined(_X86_) 00351 00352 Lookaside->FreeMisses += 1; 00353 00354 return FALSE; 00355 } 00356

Generated on Sat May 15 19:40:39 2004 for test by doxygen 1.3.7