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 lookaside list function. 00012 00013 Author: 00014 00015 David N. Cutler (davec) 19-Feb-1995 00016 00017 Revision History: 00018 00019 --*/ 00020 00021 #include "exp.h" 00022 00023 // 00024 // Define maximum dynamic adjustment scan periods. 00025 // 00026 00027 #define MAXIMUM_SCAN_PERIOD 4 00028 00029 // 00030 // Define Minimum lookaside list depth. 00031 // 00032 00033 #define MINIMUM_LOOKASIDE_DEPTH 4 00034 00035 // 00036 // Define minimum allocation threshold. 00037 // 00038 00039 #define MINIMUM_ALLOCATION_THRESHOLD 25 00040 00041 // 00042 // Define forward referenced function prototypes. 00043 // 00044 00045 LOGICAL 00046 ExpComputeLookasideDepth ( 00047 IN ULONG Allocates, 00048 IN ULONG Misses, 00049 IN USHORT MaximumDepth, 00050 IN OUT PUSHORT Depth 00051 ); 00052 00053 PVOID 00054 ExpDummyAllocate ( 00055 IN POOL_TYPE PoolType, 00056 IN SIZE_T NumberOfBytes, 00057 IN ULONG Tag 00058 ); 00059 00060 LOGICAL 00061 ExpScanGeneralLookasideList ( 00062 IN PLIST_ENTRY ListHead, 00063 IN PKSPIN_LOCK SpinLock 00064 ); 00065 00066 LOGICAL 00067 ExpScanPoolLookasideList ( 00068 IN PLIST_ENTRY ListHead 00069 ); 00070 00071 // 00072 // Define the global nonpaged and paged lookaside list data. 00073 // 00074 00075 LIST_ENTRY ExNPagedLookasideListHead; 00076 KSPIN_LOCK ExNPagedLookasideLock; 00077 LIST_ENTRY ExPagedLookasideListHead; 00078 KSPIN_LOCK ExPagedLookasideLock; 00079 LIST_ENTRY ExPoolLookasideListHead; 00080 00081 // 00082 // Define lookaside list dynamic adjustment data. 00083 // 00084 00085 ULONG ExpAdjustScanPeriod = 1; 00086 ULONG ExpCurrentScanPeriod = 1; 00087 00088 VOID 00089 ExAdjustLookasideDepth ( 00090 VOID 00091 ) 00092 00093 /*++ 00094 00095 Routine Description: 00096 00097 This function is called periodically to adjust the maximum depth of 00098 all lookaside lists. 00099 00100 Arguments: 00101 00102 None. 00103 00104 Return Value: 00105 00106 None. 00107 00108 --*/ 00109 00110 { 00111 00112 LOGICAL Changes; 00113 00114 // 00115 // Decrement the scan period and check if it is time to dynamically 00116 // adjust the maximum depth of lookaside lists. 00117 // 00118 00119 ExpCurrentScanPeriod -= 1; 00120 if (ExpCurrentScanPeriod == 0) { 00121 Changes = FALSE; 00122 00123 // 00124 // Scan the general paged and nonpaged lookaside lists. 00125 // 00126 00127 Changes |= ExpScanGeneralLookasideList(&ExNPagedLookasideListHead, 00128 &ExNPagedLookasideLock); 00129 00130 Changes |= ExpScanGeneralLookasideList(&ExPagedLookasideListHead, 00131 &ExPagedLookasideLock); 00132 00133 // 00134 // Scan the pool paged and nonpaged lookaside lists; 00135 // 00136 00137 Changes |= ExpScanPoolLookasideList(&ExPoolLookasideListHead); 00138 00139 // 00140 // If any changes were made to the depth of any lookaside list during 00141 // this scan period, then lower the scan period to the minimum value. 00142 // Otherwise, attempt to raise the scan period. 00143 // 00144 00145 if (Changes != FALSE) { 00146 ExpAdjustScanPeriod = 1; 00147 00148 } else { 00149 if (ExpAdjustScanPeriod != MAXIMUM_SCAN_PERIOD) { 00150 ExpAdjustScanPeriod += 1; 00151 } 00152 } 00153 00154 ExpCurrentScanPeriod = ExpAdjustScanPeriod; 00155 } 00156 00157 return; 00158 } 00159 00160 LOGICAL 00161 ExpComputeLookasideDepth ( 00162 IN ULONG Allocates, 00163 IN ULONG Misses, 00164 IN USHORT MaximumDepth, 00165 IN OUT PUSHORT Depth 00166 ) 00167 00168 /*++ 00169 00170 Routine Description: 00171 00172 This function computes the target depth of a lookaside list given the 00173 total allocations and misses during the last scan period and the current 00174 depth. 00175 00176 Arguments: 00177 00178 Allocates - Supplies the total number of allocations during the last 00179 scan period. 00180 00181 Misses - Supplies the total number of allocate misses during the last 00182 scan period. 00183 00184 MaximumDepth - Supplies the maximum depth the lookaside list is allowed 00185 to reach. 00186 00187 Depth - Supplies a pointer to the current lookaside list depth which 00188 receives the target depth. 00189 00190 Return Value: 00191 00192 If the target depth is greater than the current depth, then a value of 00193 TRUE is returned as the function value. Otherwise, a value of FALSE is 00194 returned. 00195 00196 --*/ 00197 00198 { 00199 00200 LOGICAL Changes; 00201 ULONG Ratio; 00202 ULONG Target; 00203 00204 // 00205 // If the allocate rate is less than the mimimum threshold, then lower 00206 // the maximum depth of the lookaside list. Otherwise, if the miss rate 00207 // is less than .5%, then lower the maximum depth. Otherwise, raise the 00208 // maximum depth based on the miss rate. 00209 // 00210 00211 Changes = FALSE; 00212 if (Misses >= Allocates) { 00213 Misses = Allocates; 00214 } 00215 00216 if (Allocates == 0) { 00217 Allocates = 1; 00218 } 00219 00220 Ratio = (Misses * 1000) / Allocates; 00221 Target = *Depth; 00222 if ((Allocates / ExpAdjustScanPeriod) < MINIMUM_ALLOCATION_THRESHOLD) { 00223 if (Target > (MINIMUM_LOOKASIDE_DEPTH + 10)) { 00224 Target -= 10; 00225 00226 } else { 00227 Target = MINIMUM_LOOKASIDE_DEPTH; 00228 } 00229 00230 } else if (Ratio < 5) { 00231 if (Target > (MINIMUM_LOOKASIDE_DEPTH + 1)) { 00232 Target -= 1; 00233 00234 } else { 00235 Target = MINIMUM_LOOKASIDE_DEPTH; 00236 } 00237 00238 } else { 00239 Changes = TRUE; 00240 Target += ((Ratio * MaximumDepth) / (1000 * 2)) + 5; 00241 if (Target > MaximumDepth) { 00242 Target = MaximumDepth; 00243 } 00244 } 00245 00246 *Depth = (USHORT)Target; 00247 return Changes; 00248 } 00249 00250 LOGICAL 00251 ExpScanGeneralLookasideList ( 00252 IN PLIST_ENTRY ListHead, 00253 IN PKSPIN_LOCK SpinLock 00254 ) 00255 00256 /*++ 00257 00258 Routine Description: 00259 00260 This function scans the specified list of general lookaside descriptors 00261 and adjusts the maximum depth as necessary. 00262 00263 Arguments: 00264 00265 ListHead - Supplies the address of the listhead for a list of lookaside 00266 descriptors. 00267 00268 SpinLock - Supplies the address of the spinlock to be used to synchronize 00269 access to the list of lookaside descriptors. 00270 00271 Return Value: 00272 00273 A value of TRUE is returned if the maximum depth of any lookaside list 00274 is changed. Otherwise, a value of FALSE is returned. 00275 00276 --*/ 00277 00278 { 00279 00280 ULONG Allocates; 00281 LOGICAL Changes; 00282 PLIST_ENTRY Entry; 00283 PPAGED_LOOKASIDE_LIST Lookaside; 00284 ULONG Misses; 00285 KIRQL OldIrql; 00286 00287 // 00288 // Raise IRQL and acquire the specified spinlock. 00289 // 00290 00291 Changes = FALSE; 00292 ExAcquireSpinLock(SpinLock, &OldIrql); 00293 00294 // 00295 // Scan the specified list of lookaside descriptors and adjust the 00296 // maximum depth as necessary. 00297 // 00298 // N.B. All lookaside list descriptor are treated as if they were 00299 // paged descriptor even though they may be nonpaged descriptors. 00300 // This is possible since both structures are identical except 00301 // for the locking fields which are the last structure fields. 00302 00303 Entry = ListHead->Flink; 00304 while (Entry != ListHead) { 00305 Lookaside = CONTAINING_RECORD(Entry, 00306 PAGED_LOOKASIDE_LIST, 00307 L.ListEntry); 00308 00309 // 00310 // Compute the total number of allocations and misses per second for 00311 // this scan period. 00312 // 00313 00314 Allocates = Lookaside->L.TotalAllocates - Lookaside->L.LastTotalAllocates; 00315 Lookaside->L.LastTotalAllocates = Lookaside->L.TotalAllocates; 00316 Misses = Lookaside->L.AllocateMisses - Lookaside->L.LastAllocateMisses; 00317 Lookaside->L.LastAllocateMisses = Lookaside->L.AllocateMisses; 00318 00319 // 00320 // Compute target depth of lookaside list. 00321 // 00322 00323 Changes |= ExpComputeLookasideDepth(Allocates, 00324 Misses, 00325 Lookaside->L.MaximumDepth, 00326 &Lookaside->L.Depth); 00327 00328 Entry = Entry->Flink; 00329 } 00330 00331 // 00332 // Release spinlock, lower IRQL, and return function value. 00333 // 00334 00335 ExReleaseSpinLock(SpinLock, OldIrql); 00336 return Changes; 00337 } 00338 00339 LOGICAL 00340 ExpScanPoolLookasideList ( 00341 IN PLIST_ENTRY ListHead 00342 ) 00343 00344 /*++ 00345 00346 Routine Description: 00347 00348 This function scans the specified pool lookaside descriptors and adjusts 00349 the maximum depth as necessary. 00350 00351 Arguments: 00352 00353 ListHead - Supplies a pointer to the list of pool lookaside structures. 00354 00355 Return Value: 00356 00357 A value of TRUE is returned if the maximum depth of any lookaside list 00358 is changed. Otherwise, a value of FALSE is returned. 00359 00360 --*/ 00361 00362 { 00363 00364 ULONG Allocates; 00365 LOGICAL Changes; 00366 PNPAGED_LOOKASIDE_LIST Lookaside; 00367 PLIST_ENTRY NextEntry; 00368 ULONG Misses; 00369 00370 // 00371 // Scan the specified list of lookaside descriptors and adjust the 00372 // maximum depth as necessary. 00373 // 00374 00375 Changes = FALSE; 00376 NextEntry = ListHead->Flink; 00377 while (NextEntry != ListHead) { 00378 Lookaside = CONTAINING_RECORD(NextEntry, 00379 NPAGED_LOOKASIDE_LIST, 00380 L.ListEntry); 00381 00382 // 00383 // Compute the total number of allocations and misses per second for 00384 // this scan period. 00385 // 00386 00387 Allocates = Lookaside->L.TotalAllocates - Lookaside->L.LastTotalAllocates; 00388 Lookaside->L.LastTotalAllocates = Lookaside->L.TotalAllocates; 00389 Misses = Allocates - (Lookaside->L.AllocateHits - Lookaside->L.LastAllocateHits); 00390 Lookaside->L.LastAllocateHits = Lookaside->L.AllocateHits; 00391 00392 // 00393 // Compute target depth of lookaside list. 00394 // 00395 00396 Changes |= ExpComputeLookasideDepth(Allocates, 00397 Misses, 00398 Lookaside->L.MaximumDepth, 00399 &Lookaside->L.Depth); 00400 00401 NextEntry = NextEntry->Flink; 00402 } 00403 00404 return Changes; 00405 } 00406 00407 VOID 00408 ExInitializeNPagedLookasideList ( 00409 IN PNPAGED_LOOKASIDE_LIST Lookaside, 00410 IN PALLOCATE_FUNCTION Allocate, 00411 IN PFREE_FUNCTION Free, 00412 IN ULONG Flags, 00413 IN SIZE_T Size, 00414 IN ULONG Tag, 00415 IN USHORT Depth 00416 ) 00417 00418 /*++ 00419 00420 Routine Description: 00421 00422 This function initializes a nonpaged lookaside list structure and inserts 00423 the structure in the system nonpaged lookaside list. 00424 00425 Arguments: 00426 00427 Lookaside - Supplies a pointer to a nonpaged lookaside list structure. 00428 00429 Allocate - Supplies an optional pointer to an allocate function. 00430 00431 Free - Supplies an optional pointer to a free function. 00432 00433 Flags - Supplies the pool allocation flags which are merged with the 00434 pool allocation type (NonPagedPool) to control pool allocation. 00435 00436 Size - Supplies the size for the lookaside list entries. 00437 00438 Tag - Supplies the pool tag for the lookaside list entries. 00439 00440 Depth - Supplies the maximum depth of the lookaside list. 00441 00442 Return Value: 00443 00444 None. 00445 00446 --*/ 00447 00448 { 00449 00450 // 00451 // Initialize the lookaside list structure. 00452 // 00453 00454 ExInitializeSListHead(&Lookaside->L.ListHead); 00455 Lookaside->L.Depth = MINIMUM_LOOKASIDE_DEPTH; 00456 Lookaside->L.MaximumDepth = 256; //Depth; 00457 Lookaside->L.TotalAllocates = 0; 00458 Lookaside->L.AllocateMisses = 0; 00459 Lookaside->L.TotalFrees = 0; 00460 Lookaside->L.FreeMisses = 0; 00461 Lookaside->L.Type = NonPagedPool | Flags; 00462 Lookaside->L.Tag = Tag; 00463 Lookaside->L.Size = (ULONG)Size; 00464 if (Allocate == NULL) { 00465 Lookaside->L.Allocate = ExAllocatePoolWithTag; 00466 00467 } else { 00468 Lookaside->L.Allocate = Allocate; 00469 } 00470 00471 if (Free == NULL) { 00472 Lookaside->L.Free = ExFreePool; 00473 00474 } else { 00475 Lookaside->L.Free = Free; 00476 } 00477 00478 Lookaside->L.LastTotalAllocates = 0; 00479 Lookaside->L.LastAllocateMisses = 0; 00480 KeInitializeSpinLock(&Lookaside->Lock); 00481 00482 // 00483 // Insert the lookaside list structure is the system nonpaged lookaside 00484 // list. 00485 // 00486 00487 ExInterlockedInsertTailList(&ExNPagedLookasideListHead, 00488 &Lookaside->L.ListEntry, 00489 &ExNPagedLookasideLock); 00490 return; 00491 } 00492 00493 VOID 00494 ExDeleteNPagedLookasideList ( 00495 IN PNPAGED_LOOKASIDE_LIST Lookaside 00496 ) 00497 00498 /*++ 00499 00500 Routine Description: 00501 00502 This function removes a paged lookaside structure from the system paged 00503 lookaside list and frees any entries specified by the lookaside structure. 00504 00505 Arguments: 00506 00507 Lookaside - Supplies a pointer to a nonpaged lookaside list structure. 00508 00509 Return Value: 00510 00511 None. 00512 00513 --*/ 00514 00515 { 00516 00517 PVOID Entry; 00518 KIRQL OldIrql; 00519 00520 // 00521 // Acquire the nonpaged system lookaside list lock and remove the 00522 // specified lookaside list structure from the list. 00523 // 00524 00525 ExAcquireSpinLock(&ExNPagedLookasideLock, &OldIrql); 00526 RemoveEntryList(&Lookaside->L.ListEntry); 00527 ExReleaseSpinLock(&ExNPagedLookasideLock, OldIrql); 00528 00529 // 00530 // Remove all pool entries from the specified lookaside structure 00531 // and free them. 00532 // 00533 00534 Lookaside->L.Allocate = ExpDummyAllocate; 00535 while ((Entry = ExAllocateFromNPagedLookasideList(Lookaside)) != NULL) { 00536 (Lookaside->L.Free)(Entry); 00537 } 00538 00539 return; 00540 } 00541 00542 VOID 00543 ExInitializePagedLookasideList ( 00544 IN PPAGED_LOOKASIDE_LIST Lookaside, 00545 IN PALLOCATE_FUNCTION Allocate, 00546 IN PFREE_FUNCTION Free, 00547 IN ULONG Flags, 00548 IN SIZE_T Size, 00549 IN ULONG Tag, 00550 IN USHORT Depth 00551 ) 00552 00553 /*++ 00554 00555 Routine Description: 00556 00557 This function initializes a paged lookaside list structure and inserts 00558 the structure in the system paged lookaside list. 00559 00560 Arguments: 00561 00562 Lookaside - Supplies a pointer to a paged lookaside list structure. 00563 00564 Allocate - Supplies an optional pointer to an allocate function. 00565 00566 Free - Supplies an optional pointer to a free function. 00567 00568 Flags - Supplies the pool allocation flags which are merged with the 00569 pool allocation type (NonPagedPool) to control pool allocation. 00570 00571 Size - Supplies the size for the lookaside list entries. 00572 00573 Tag - Supplies the pool tag for the lookaside list entries. 00574 00575 Depth - Supplies the maximum depth of the lookaside list. 00576 00577 Return Value: 00578 00579 None. 00580 00581 --*/ 00582 00583 { 00584 00585 // 00586 // Initialize the lookaside list structure. 00587 // 00588 00589 ExInitializeSListHead(&Lookaside->L.ListHead); 00590 Lookaside->L.Depth = MINIMUM_LOOKASIDE_DEPTH; 00591 Lookaside->L.MaximumDepth = 256; //Depth; 00592 Lookaside->L.TotalAllocates = 0; 00593 Lookaside->L.AllocateMisses = 0; 00594 Lookaside->L.TotalFrees = 0; 00595 Lookaside->L.FreeMisses = 0; 00596 Lookaside->L.Type = PagedPool | Flags; 00597 Lookaside->L.Tag = Tag; 00598 Lookaside->L.Size = (ULONG)Size; 00599 if (Allocate == NULL) { 00600 Lookaside->L.Allocate = ExAllocatePoolWithTag; 00601 00602 } else { 00603 Lookaside->L.Allocate = Allocate; 00604 } 00605 00606 if (Free == NULL) { 00607 Lookaside->L.Free = ExFreePool; 00608 00609 } else { 00610 Lookaside->L.Free = Free; 00611 } 00612 00613 Lookaside->L.LastTotalAllocates = 0; 00614 Lookaside->L.LastAllocateMisses = 0; 00615 ExInitializeFastMutex(&Lookaside->Lock); 00616 00617 // 00618 // Insert the lookaside list structure in the system paged lookaside 00619 // list. 00620 // 00621 00622 ExInterlockedInsertTailList(&ExPagedLookasideListHead, 00623 &Lookaside->L.ListEntry, 00624 &ExPagedLookasideLock); 00625 return; 00626 } 00627 00628 VOID 00629 ExDeletePagedLookasideList ( 00630 IN PPAGED_LOOKASIDE_LIST Lookaside 00631 ) 00632 00633 /*++ 00634 00635 Routine Description: 00636 00637 This function removes a paged lookaside structure from the system paged 00638 lookaside list and frees any entries specified by the lookaside structure. 00639 00640 Arguments: 00641 00642 Lookaside - Supplies a pointer to a paged lookaside list structure. 00643 00644 Return Value: 00645 00646 None. 00647 00648 --*/ 00649 00650 { 00651 00652 PVOID Entry; 00653 KIRQL OldIrql; 00654 00655 // 00656 // Acquire the paged system lookaside list lock and remove the 00657 // specified lookaside list structure from the list. 00658 // 00659 00660 ExAcquireSpinLock(&ExPagedLookasideLock, &OldIrql); 00661 RemoveEntryList(&Lookaside->L.ListEntry); 00662 ExReleaseSpinLock(&ExPagedLookasideLock, OldIrql); 00663 00664 // 00665 // Remove all pool entries from the specified lookaside structure 00666 // and free them. 00667 // 00668 00669 Lookaside->L.Allocate = ExpDummyAllocate; 00670 while ((Entry = ExAllocateFromPagedLookasideList(Lookaside)) != NULL) { 00671 (Lookaside->L.Free)(Entry); 00672 } 00673 00674 return; 00675 } 00676 00677 #if !defined(_MIPS_) && !defined(_ALPHA_) && !defined(_IA64_) 00678 00679 00680 PVOID 00681 ExAllocateFromPagedLookasideList( 00682 IN PPAGED_LOOKASIDE_LIST Lookaside 00683 ) 00684 00685 /*++ 00686 00687 Routine Description: 00688 00689 This function removes (pops) the first entry from the specified 00690 paged lookaside list. 00691 00692 Arguments: 00693 00694 Lookaside - Supplies a pointer to a paged lookaside list structure. 00695 00696 Return Value: 00697 00698 If an entry is removed from the specified lookaside list, then the 00699 address of the entry is returned as the function value. Otherwise, 00700 NULL is returned. 00701 00702 --*/ 00703 00704 { 00705 00706 PVOID Entry; 00707 00708 Lookaside->L.TotalAllocates += 1; 00709 00710 if (Isx86FeaturePresent(KF_CMPXCHG8B)) { 00711 if ((Entry = ExInterlockedPopEntrySList(&Lookaside->L.ListHead, 00712 NULL)) == NULL) { 00713 00714 Lookaside->L.AllocateMisses += 1; 00715 Entry = (Lookaside->L.Allocate)(Lookaside->L.Type, 00716 Lookaside->L.Size, 00717 Lookaside->L.Tag); 00718 } 00719 00720 return Entry; 00721 } 00722 00723 ExAcquireFastMutex(&Lookaside->Lock); 00724 Entry = PopEntryList(&Lookaside->L.ListHead.Next); 00725 if (Entry == NULL) { 00726 ExReleaseFastMutex(&Lookaside->Lock); 00727 Lookaside->L.AllocateMisses += 1; 00728 Entry = (Lookaside->L.Allocate)(Lookaside->L.Type, 00729 Lookaside->L.Size, 00730 Lookaside->L.Tag); 00731 00732 } else { 00733 Lookaside->L.ListHead.Depth -= 1; 00734 ExReleaseFastMutex(&Lookaside->Lock); 00735 } 00736 00737 return Entry; 00738 } 00739 00740 VOID 00741 ExFreeToPagedLookasideList( 00742 IN PPAGED_LOOKASIDE_LIST Lookaside, 00743 IN PVOID Entry 00744 ) 00745 00746 /*++ 00747 00748 Routine Description: 00749 00750 This function inserts (pushes) the specified entry into the specified 00751 paged lookaside list. 00752 00753 Arguments: 00754 00755 Lookaside - Supplies a pointer to a paged lookaside list structure. 00756 00757 Entry - Supples a pointer to the entry that is inserted in the 00758 lookaside list. 00759 00760 Return Value: 00761 00762 None. 00763 00764 --*/ 00765 00766 { 00767 00768 Lookaside->L.TotalFrees += 1; 00769 00770 if (Isx86FeaturePresent(KF_CMPXCHG8B)) { 00771 if (ExQueryDepthSList(&Lookaside->L.ListHead) >= Lookaside->L.Depth) { 00772 Lookaside->L.FreeMisses += 1; 00773 (Lookaside->L.Free)(Entry); 00774 00775 } else { 00776 ExInterlockedPushEntrySList(&Lookaside->L.ListHead, 00777 (PSINGLE_LIST_ENTRY)Entry, 00778 NULL); 00779 } 00780 00781 return; 00782 } 00783 00784 ExAcquireFastMutex(&Lookaside->Lock); 00785 if (ExQueryDepthSList(&Lookaside->L.ListHead) >= Lookaside->L.Depth) { 00786 ExReleaseFastMutex(&Lookaside->Lock); 00787 Lookaside->L.FreeMisses += 1; 00788 (Lookaside->L.Free)(Entry); 00789 00790 } else { 00791 PushEntryList(&Lookaside->L.ListHead.Next, (PSINGLE_LIST_ENTRY)Entry); 00792 Lookaside->L.ListHead.Depth += 1; 00793 ExReleaseFastMutex(&Lookaside->Lock); 00794 } 00795 00796 return; 00797 } 00798 00799 #endif 00800 00801 PVOID 00802 ExpDummyAllocate ( 00803 IN POOL_TYPE PoolType, 00804 IN SIZE_T NumberOfBytes, 00805 IN ULONG Tag 00806 ) 00807 00808 /*++ 00809 00810 Routine Description: 00811 00812 This function is a dummy allocation routine which is used to empty 00813 a lookaside list. 00814 00815 Arguments: 00816 00817 PoolType - Supplies the type of pool to allocate. 00818 00819 NumberOfBytes - supplies the number of bytes to allocate. 00820 00821 Tag - supplies the pool tag. 00822 00823 Return Value: 00824 00825 NULL is returned as the function value. 00826 00827 --*/ 00828 00829 { 00830 00831 return NULL; 00832 }

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