00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
#include "ntrtlp.h"
00022 
#include "heap.h"
00023 
#include "heappriv.h"
00024 
00025 
00026 
00027 
00028 
00029 
00030 #define MINIMUM_LOOKASIDE_DEPTH 4
00031 
00032 
00033 
00034 
00035 
00036 #define MINIMUM_ALLOCATION_THRESHOLD 25
00037 
00038 
00039 
00040 
00041 
00042 
00043 
00044 
VOID
00045 RtlpInitializeHeapLookaside (
00046     IN 
PHEAP_LOOKASIDE Lookaside,
00047     IN USHORT Depth
00048     )
00049 
00050 
00051 
00052 
00053 
00054 
00055 
00056 
00057 
00058 
00059 
00060 
00061 
00062 
00063 
00064 
00065 
00066 
00067 
00068 
00069 
00070 
00071 
00072 
00073 
00074 
00075 
00076 
00077 
00078 {
00079 
00080     
00081     
00082     
00083 
00084     
RtlpInitializeSListHead(&Lookaside->ListHead);
00085 
00086     Lookaside->Depth = 
MINIMUM_LOOKASIDE_DEPTH;
00087     Lookaside->MaximumDepth = 256; 
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 
00108 
00109 
00110 
00111 
00112 
00113 
00114 
00115 
00116 
00117 
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 
00137 
00138 
00139 
00140 
00141 
00142 
00143 
00144 
00145 
00146 
00147 
00148 
00149 
00150 
00151 {
00152     ULONG Allocates;
00153     ULONG Misses;
00154 
00155     
00156     
00157     
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     
00167     
00168 
00169     {
00170         ULONG Ratio;
00171         ULONG Target;
00172 
00173         
00174         
00175         
00176         
00177         
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 
00229 
00230 
00231 
00232 
00233 
00234 
00235 
00236 
00237 
00238 
00239 
00240 
00241 
00242 
00243 
00244 
00245 {
00246 
00247     PVOID Entry;
00248 
00249     Lookaside->TotalAllocates += 1;
00250 
00251     
00252     
00253     
00254     
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 
00296 
00297 
00298 
00299 
00300 
00301 
00302 
00303 
00304 
00305 
00306 
00307 
00308 
00309 
00310 
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             
00327             
00328             
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