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

bitmap.c File Reference

#include "ntrtlp.h"

Go to the source code of this file.

Defines

#define RightShiftUlong(E1, E2)   ((E2) < 32 ? (E1) >> (E2) : 0)
#define LeftShiftUlong(E1, E2)   ((E2) < 32 ? (E1) << (E2) : 0)
#define GET_BYTE_DECLARATIONS()   PUCHAR _CURRENT_POSITION;
#define GET_BYTE_INITIALIZATION(RTL_BITMAP, BYTE_INDEX)
#define GET_BYTE(THIS_BYTE)
#define BM_4567   0xFFFFFFFF00000000UI64
#define BM_67   0xFFFF000000000000UI64
#define BM_7   0xFF00000000000000UI64
#define BM_5   0x0000FF0000000000UI64
#define BM_23   0x00000000FFFF0000UI64
#define BM_3   0x00000000FF000000UI64
#define BM_1   0x000000000000FF00UI64
#define BM_0123   0x00000000FFFFFFFFUI64
#define BM_01   0x000000000000FFFFUI64
#define BM_0   0x00000000000000FFUI64
#define BM_2   0x0000000000FF0000UI64
#define BM_45   0x0000FFFF00000000UI64
#define BM_4   0x000000FF00000000UI64
#define BM_6   0x00FF000000000000UI64

Functions

VOID RtlInitializeBitMap (IN PRTL_BITMAP BitMapHeader, IN PULONG BitMapBuffer, IN ULONG SizeOfBitMap)
VOID RtlClearAllBits (IN PRTL_BITMAP BitMapHeader)
VOID RtlSetAllBits (IN PRTL_BITMAP BitMapHeader)
ULONG RtlFindClearBits (IN PRTL_BITMAP BitMapHeader, IN ULONG NumberToFind, IN ULONG HintIndex)
ULONG RtlFindSetBits (IN PRTL_BITMAP BitMapHeader, IN ULONG NumberToFind, IN ULONG HintIndex)
ULONG RtlFindClearBitsAndSet (IN PRTL_BITMAP BitMapHeader, IN ULONG NumberToFind, IN ULONG HintIndex)
ULONG RtlFindSetBitsAndClear (IN PRTL_BITMAP BitMapHeader, IN ULONG NumberToFind, IN ULONG HintIndex)
VOID RtlClearBits (IN PRTL_BITMAP BitMapHeader, IN ULONG StartingIndex, IN ULONG NumberToClear)
VOID RtlSetBits (IN PRTL_BITMAP BitMapHeader, IN ULONG StartingIndex, IN ULONG NumberToSet)
ULONG RtlFindClearRuns (IN PRTL_BITMAP BitMapHeader, PRTL_BITMAP_RUN RunArray, ULONG SizeOfRunArray, BOOLEAN LocateLongestRuns)
ULONG RtlFindLongestRunClear (IN PRTL_BITMAP BitMapHeader, OUT PULONG StartingIndex)
ULONG RtlFindFirstRunClear (IN PRTL_BITMAP BitMapHeader, OUT PULONG StartingIndex)
ULONG RtlNumberOfClearBits (IN PRTL_BITMAP BitMapHeader)
ULONG RtlNumberOfSetBits (IN PRTL_BITMAP BitMapHeader)
BOOLEAN RtlAreBitsClear (IN PRTL_BITMAP BitMapHeader, IN ULONG StartingIndex, IN ULONG Length)
BOOLEAN RtlAreBitsSet (IN PRTL_BITMAP BitMapHeader, IN ULONG StartingIndex, IN ULONG Length)
ULONG RtlFindNextForwardRunClear (IN PRTL_BITMAP BitMapHeader, IN ULONG FromIndex, IN PULONG StartingRunIndex)
ULONG RtlFindLastBackwardRunClear (IN PRTL_BITMAP BitMapHeader, IN ULONG FromIndex, IN PULONG StartingRunIndex)
CCHAR RtlFindMostSignificantBit (IN ULONGLONG Set)
CCHAR RtlFindLeastSignificantBit (IN ULONGLONG Set)

Variables

CONST CCHAR RtlpBitsClearAnywhere []
CONST CCHAR RtlpBitsClearLow []
CONST CCHAR RtlpBitsClearHigh []
CONST CCHAR RtlpBitsClearTotal []
CONST UCHAR FillMask [] = { 0x00, 0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x7F, 0xFF }
CONST UCHAR ZeroMask [] = { 0xFF, 0xFE, 0xFC, 0xF8, 0xf0, 0xe0, 0xc0, 0x80, 0x00 }
CONST ULONG FillMaskUlong []


Define Documentation

#define BM_0   0x00000000000000FFUI64
 

Definition at line 2916 of file rtl/bitmap.c.

Referenced by RtlFindLeastSignificantBit().

#define BM_01   0x000000000000FFFFUI64
 

Definition at line 2915 of file rtl/bitmap.c.

Referenced by RtlFindLeastSignificantBit().

#define BM_0123   0x00000000FFFFFFFFUI64
 

Definition at line 2914 of file rtl/bitmap.c.

Referenced by RtlFindLeastSignificantBit().

#define BM_1   0x000000000000FF00UI64
 

Definition at line 2912 of file rtl/bitmap.c.

Referenced by RtlFindMostSignificantBit().

#define BM_2   0x0000000000FF0000UI64
 

Definition at line 2917 of file rtl/bitmap.c.

Referenced by RtlFindLeastSignificantBit().

#define BM_23   0x00000000FFFF0000UI64
 

Definition at line 2910 of file rtl/bitmap.c.

Referenced by RtlFindMostSignificantBit().

#define BM_3   0x00000000FF000000UI64
 

Definition at line 2911 of file rtl/bitmap.c.

Referenced by RtlFindMostSignificantBit().

#define BM_4   0x000000FF00000000UI64
 

Definition at line 2919 of file rtl/bitmap.c.

Referenced by RtlFindLeastSignificantBit().

#define BM_45   0x0000FFFF00000000UI64
 

Definition at line 2918 of file rtl/bitmap.c.

Referenced by RtlFindLeastSignificantBit().

#define BM_4567   0xFFFFFFFF00000000UI64
 

Definition at line 2906 of file rtl/bitmap.c.

Referenced by RtlFindMostSignificantBit().

#define BM_5   0x0000FF0000000000UI64
 

Definition at line 2909 of file rtl/bitmap.c.

Referenced by RtlFindMostSignificantBit().

#define BM_6   0x00FF000000000000UI64
 

Definition at line 2920 of file rtl/bitmap.c.

Referenced by RtlFindLeastSignificantBit().

#define BM_67   0xFFFF000000000000UI64
 

Definition at line 2907 of file rtl/bitmap.c.

Referenced by RtlFindMostSignificantBit().

#define BM_7   0xFF00000000000000UI64
 

Definition at line 2908 of file rtl/bitmap.c.

Referenced by RtlFindMostSignificantBit().

#define GET_BYTE THIS_BYTE   ) 
 

Value:

( \ THIS_BYTE = *(_CURRENT_POSITION++) \ )

Definition at line 112 of file rtl/bitmap.c.

Referenced by RtlAreBitsClear(), RtlAreBitsSet(), RtlFindClearBits(), RtlFindClearRuns(), RtlFindSetBits(), RtlNumberOfClearBits(), and RtlNumberOfSetBits().

 
#define GET_BYTE_DECLARATIONS  )     PUCHAR _CURRENT_POSITION;
 

Definition at line 105 of file rtl/bitmap.c.

Referenced by RtlAreBitsClear(), RtlAreBitsSet(), RtlFindClearBits(), RtlFindClearRuns(), RtlFindSetBits(), RtlNumberOfClearBits(), and RtlNumberOfSetBits().

#define GET_BYTE_INITIALIZATION RTL_BITMAP,
BYTE_INDEX   ) 
 

Value:

{ \ _CURRENT_POSITION = &((PUCHAR)((RTL_BITMAP)->Buffer))[BYTE_INDEX]; \ }

Definition at line 108 of file rtl/bitmap.c.

Referenced by RtlAreBitsClear(), RtlAreBitsSet(), RtlFindClearBits(), RtlFindClearRuns(), RtlFindSetBits(), RtlNumberOfClearBits(), and RtlNumberOfSetBits().

#define LeftShiftUlong E1,
E2   )     ((E2) < 32 ? (E1) << (E2) : 0)
 

Definition at line 37 of file rtl/bitmap.c.

Referenced by RtlClearBits(), and RtlSetBits().

#define RightShiftUlong E1,
E2   )     ((E2) < 32 ? (E1) >> (E2) : 0)
 

Definition at line 36 of file rtl/bitmap.c.

Referenced by RtlClearBits(), and RtlSetBits().


Function Documentation

BOOLEAN RtlAreBitsClear IN PRTL_BITMAP  BitMapHeader,
IN ULONG  StartingIndex,
IN ULONG  Length
 

Definition at line 2305 of file rtl/bitmap.c.

References BitMapHeader, FALSE, FillMask, GET_BYTE, GET_BYTE_DECLARATIONS, GET_BYTE_INITIALIZATION, TRUE, and ZeroMask.

Referenced by CmpInitializeHiveList(), main(), and MiAttemptPageFileReduction().

02313 : 02314 02315 This procedure determines if the range of specified bits are all clear. 02316 02317 Arguments: 02318 02319 BitMapHeader - Supplies a pointer to the previously initialized bitmap. 02320 02321 StartingIndex - Supplies the starting bit index to examine 02322 02323 Length - Supplies the number of bits to examine 02324 02325 Return Value: 02326 02327 BOOLEAN - TRUE if the specified bits in the bitmap are all clear, and 02328 FALSE if any are set or if the range is outside the bitmap or if 02329 Length is zero. 02330 02331 --*/ 02332 02333 { 02334 ULONG SizeOfBitMap; 02335 ULONG SizeInBytes; 02336 02337 ULONG EndingIndex; 02338 02339 ULONG StartingByte; 02340 ULONG EndingByte; 02341 02342 ULONG StartingOffset; 02343 ULONG EndingOffset; 02344 02345 ULONG i; 02346 UCHAR Byte; 02347 02348 GET_BYTE_DECLARATIONS(); 02349 02350 // 02351 // To make the loops in our test run faster we'll extract the fields 02352 // from the bitmap header 02353 // 02354 02355 SizeOfBitMap = BitMapHeader->SizeOfBitMap; 02356 SizeInBytes = (SizeOfBitMap + 7) / 8; 02357 02358 // 02359 // First make sure that the specified range is contained within the 02360 // bitmap, and the length is not zero. 02361 // 02362 02363 if ((StartingIndex + Length > SizeOfBitMap) || (Length == 0)) { 02364 02365 return FALSE; 02366 } 02367 02368 // 02369 // Compute the ending index, starting and ending byte, and the starting 02370 // and ending offset within each byte 02371 // 02372 02373 EndingIndex = StartingIndex + Length - 1; 02374 02375 StartingByte = StartingIndex / 8; 02376 EndingByte = EndingIndex / 8; 02377 02378 StartingOffset = StartingIndex % 8; 02379 EndingOffset = EndingIndex % 8; 02380 02381 // 02382 // Set ourselves up to get the next byte 02383 // 02384 02385 GET_BYTE_INITIALIZATION( BitMapHeader, StartingByte ); 02386 02387 // 02388 // Special case the situation where the starting byte and ending 02389 // byte are one in the same 02390 // 02391 02392 if (StartingByte == EndingByte) { 02393 02394 // 02395 // Get the single byte we are to look at 02396 // 02397 02398 GET_BYTE( Byte ); 02399 02400 // 02401 // Now we compute the mask of bits we're after and then AND it with 02402 // the byte. If it is zero then the bits in question are all clear 02403 // otherwise at least one of them is set. 02404 // 02405 02406 if ((ZeroMask[StartingOffset] & FillMask[EndingOffset+1] & Byte) == 0) { 02407 02408 return TRUE; 02409 02410 } else { 02411 02412 return FALSE; 02413 } 02414 02415 } else { 02416 02417 // 02418 // Get the first byte that we're after, and then 02419 // compute the mask of bits we're after for the first byte then 02420 // AND it with the byte itself. 02421 // 02422 02423 GET_BYTE( Byte ); 02424 02425 if ((ZeroMask[StartingOffset] & Byte) != 0) { 02426 02427 return FALSE; 02428 } 02429 02430 // 02431 // Now for every whole byte inbetween read in the byte, 02432 // and make sure it is all zeros 02433 // 02434 02435 for (i = StartingByte+1; i < EndingByte; i += 1) { 02436 02437 GET_BYTE( Byte ); 02438 02439 if (Byte != 0) { 02440 02441 return FALSE; 02442 } 02443 } 02444 02445 // 02446 // Get the last byte we're after, and then 02447 // compute the mask of bits we're after for the last byte then 02448 // AND it with the byte itself. 02449 // 02450 02451 GET_BYTE( Byte ); 02452 02453 if ((FillMask[EndingOffset+1] & Byte) != 0) { 02454 02455 return FALSE; 02456 } 02457 } 02458 02459 return TRUE; 02460 }

BOOLEAN RtlAreBitsSet IN PRTL_BITMAP  BitMapHeader,
IN ULONG  StartingIndex,
IN ULONG  Length
 

Definition at line 2464 of file rtl/bitmap.c.

References BitMapHeader, FALSE, FillMask, GET_BYTE, GET_BYTE_DECLARATIONS, GET_BYTE_INITIALIZATION, TRUE, and ZeroMask.

Referenced by main().

02472 : 02473 02474 This procedure determines if the range of specified bits are all set. 02475 02476 Arguments: 02477 02478 BitMapHeader - Supplies a pointer to the previously initialized bitmap. 02479 02480 StartingIndex - Supplies the starting bit index to examine 02481 02482 Length - Supplies the number of bits to examine 02483 02484 Return Value: 02485 02486 BOOLEAN - TRUE if the specified bits in the bitmap are all set, and 02487 FALSE if any are clear or if the range is outside the bitmap or if 02488 Length is zero. 02489 02490 --*/ 02491 02492 { 02493 ULONG SizeOfBitMap; 02494 ULONG SizeInBytes; 02495 02496 ULONG EndingIndex; 02497 02498 ULONG StartingByte; 02499 ULONG EndingByte; 02500 02501 ULONG StartingOffset; 02502 ULONG EndingOffset; 02503 02504 ULONG i; 02505 UCHAR Byte; 02506 02507 GET_BYTE_DECLARATIONS(); 02508 02509 // 02510 // To make the loops in our test run faster we'll extract the fields 02511 // from the bitmap header 02512 // 02513 02514 SizeOfBitMap = BitMapHeader->SizeOfBitMap; 02515 SizeInBytes = (SizeOfBitMap + 7) / 8; 02516 02517 // 02518 // First make sure that the specified range is contained within the 02519 // bitmap, and the length is not zero. 02520 // 02521 02522 if ((StartingIndex + Length > SizeOfBitMap) || (Length == 0)) { 02523 02524 return FALSE; 02525 } 02526 02527 // 02528 // Compute the ending index, starting and ending byte, and the starting 02529 // and ending offset within each byte 02530 // 02531 02532 EndingIndex = StartingIndex + Length - 1; 02533 02534 StartingByte = StartingIndex / 8; 02535 EndingByte = EndingIndex / 8; 02536 02537 StartingOffset = StartingIndex % 8; 02538 EndingOffset = EndingIndex % 8; 02539 02540 // 02541 // Set ourselves up to get the next byte 02542 // 02543 02544 GET_BYTE_INITIALIZATION( BitMapHeader, StartingByte ); 02545 02546 // 02547 // Special case the situation where the starting byte and ending 02548 // byte are one in the same 02549 // 02550 02551 if (StartingByte == EndingByte) { 02552 02553 // 02554 // Get the single byte we are to look at 02555 // 02556 02557 GET_BYTE( Byte ); 02558 02559 // 02560 // Now we compute the mask of bits we're after and then AND it with 02561 // the complement of the byte If it is zero then the bits in question 02562 // are all clear otherwise at least one of them is clear. 02563 // 02564 02565 if ((ZeroMask[StartingOffset] & FillMask[EndingOffset+1] & ~Byte) == 0) { 02566 02567 return TRUE; 02568 02569 } else { 02570 02571 return FALSE; 02572 } 02573 02574 } else { 02575 02576 // 02577 // Get the first byte that we're after, and then 02578 // compute the mask of bits we're after for the first byte then 02579 // AND it with the complement of the byte itself. 02580 // 02581 02582 GET_BYTE( Byte ); 02583 02584 if ((ZeroMask[StartingOffset] & ~Byte) != 0) { 02585 02586 return FALSE; 02587 } 02588 02589 // 02590 // Now for every whole byte inbetween read in the byte, 02591 // and make sure it is all ones 02592 // 02593 02594 for (i = StartingByte+1; i < EndingByte; i += 1) { 02595 02596 GET_BYTE( Byte ); 02597 02598 if (Byte != 0xff) { 02599 02600 return FALSE; 02601 } 02602 } 02603 02604 // 02605 // Get the last byte we're after, and then 02606 // compute the mask of bits we're after for the last byte then 02607 // AND it with the complement of the byte itself. 02608 // 02609 02610 GET_BYTE( Byte ); 02611 02612 if ((FillMask[EndingOffset+1] & ~Byte) != 0) { 02613 02614 return FALSE; 02615 } 02616 } 02617 02618 return TRUE; 02619 }

VOID RtlClearAllBits IN PRTL_BITMAP  BitMapHeader  ) 
 

Definition at line 266 of file rtl/bitmap.c.

References BitMapHeader.

Referenced by DoBitMapTest(), HvInitializeHive(), HvRefreshHive(), HvSyncHive(), IopCreateSummaryDump(), main(), MiBuildPagedPool(), MiInitializeSessionIds(), MiInitializeSessionPool(), MiInitializeSystemSpaceMap(), MiInitMachineDependent(), NtAllocateUserPhysicalPages(), and NtAllocateVirtualMemory().

00272 : 00273 00274 This procedure clears all bits in the specified Bit Map. 00275 00276 Arguments: 00277 00278 BitMapHeader - Supplies a pointer to the previously initialized BitMap 00279 00280 Return Value: 00281 00282 None. 00283 00284 --*/ 00285 00286 { 00287 // 00288 // Clear all the bits 00289 // 00290 00291 RtlZeroMemory( BitMapHeader->Buffer, 00292 ((BitMapHeader->SizeOfBitMap + 31) / 32) * 4 00293 ); 00294 00295 // 00296 // And return to our caller 00297 // 00298 00299 //DbgPrint("ClearAllBits"); DumpBitMap(BitMapHeader); 00300 return; 00301 }

VOID RtlClearBits IN PRTL_BITMAP  BitMapHeader,
IN ULONG  StartingIndex,
IN ULONG  NumberToClear
 

Definition at line 1508 of file rtl/bitmap.c.

References ASSERT, BitMapHeader, LeftShiftUlong, and RightShiftUlong.

Referenced by DoBitMapTest(), HvFreeHivePartial(), HvMarkClean(), HvRefreshHive(), IopRemovePageFromPageMap(), main(), MiAllocatePoolPages(), MiAttemptPageFileExtension(), MiAttemptPageFileReduction(), MiBuildPagedPool(), MiDereferenceSession(), MiFreePoolPages(), MiGatherPagefilePages(), MiInitializeSessionPool(), MiMapViewInSystemSpace(), MiReleasePageFileSpace(), MiSessionCreateInternal(), MiUnmapViewInSystemSpace(), NtAllocateUserPhysicalPages(), NtCreatePagingFile(), NtFreeUserPhysicalPages(), RtlFindSetBitsAndClear(), and SetHandleFlag().

01516 : 01517 01518 This procedure clears the specified range of bits within the 01519 specified bit map. 01520 01521 Arguments: 01522 01523 BitMapHeader - Supplies a pointer to the previously initialized Bit Map. 01524 01525 StartingIndex - Supplies the index (zero based) of the first bit to clear. 01526 01527 NumberToClear - Supplies the number of bits to clear. 01528 01529 Return Value: 01530 01531 None. 01532 01533 --*/ 01534 01535 { 01536 ULONG BitOffset; 01537 PULONG CurrentLong; 01538 01539 //DbgPrint("ClearBits %08lx, ", NumberToClear); 01540 //DbgPrint("%08lx", StartingIndex); 01541 01542 ASSERT( StartingIndex + NumberToClear <= BitMapHeader->SizeOfBitMap ); 01543 01544 // 01545 // Special case the situation where the number of bits to clear is 01546 // zero. Turn this into a noop. 01547 // 01548 01549 if (NumberToClear == 0) { 01550 01551 return; 01552 } 01553 01554 BitOffset = StartingIndex % 32; 01555 01556 // 01557 // Get a pointer to the first longword that needs to be zeroed out 01558 // 01559 01560 CurrentLong = &BitMapHeader->Buffer[ StartingIndex / 32 ]; 01561 01562 // 01563 // Check if we can only need to clear out one longword. 01564 // 01565 01566 if ((BitOffset + NumberToClear) <= 32) { 01567 01568 // 01569 // To build a mask of bits to clear we shift left to get the number 01570 // of bits we're clearing and then shift right to put it in position. 01571 // We'll typecast the right shift to ULONG to make sure it doesn't 01572 // do a sign extend. 01573 // 01574 01575 *CurrentLong &= ~LeftShiftUlong(RightShiftUlong(((ULONG)0xFFFFFFFF),(32 - NumberToClear)), 01576 BitOffset); 01577 01578 // 01579 // And return to our caller 01580 // 01581 01582 //DumpBitMap(BitMapHeader); 01583 01584 return; 01585 } 01586 01587 // 01588 // We can clear out to the end of the first longword so we'll 01589 // do that right now. 01590 // 01591 01592 *CurrentLong &= ~LeftShiftUlong(0xFFFFFFFF, BitOffset); 01593 01594 // 01595 // And indicate what the next longword to clear is and how many 01596 // bits are left to clear 01597 // 01598 01599 CurrentLong += 1; 01600 NumberToClear -= 32 - BitOffset; 01601 01602 // 01603 // The bit position is now long aligned, so we can continue 01604 // clearing longwords until the number to clear is less than 32 01605 // 01606 01607 while (NumberToClear >= 32) { 01608 01609 *CurrentLong = 0; 01610 CurrentLong += 1; 01611 NumberToClear -= 32; 01612 } 01613 01614 // 01615 // And now we can clear the remaining bits, if there are any, in the 01616 // last longword 01617 // 01618 01619 if (NumberToClear > 0) { 01620 01621 *CurrentLong &= LeftShiftUlong(0xFFFFFFFF, NumberToClear); 01622 } 01623 01624 // 01625 // And return to our caller 01626 // 01627 01628 //DumpBitMap(BitMapHeader); 01629 01630 return; 01631 }

ULONG RtlFindClearBits IN PRTL_BITMAP  BitMapHeader,
IN ULONG  NumberToFind,
IN ULONG  HintIndex
 

Definition at line 345 of file rtl/bitmap.c.

References BitMapHeader, FillMask, GET_BYTE, GET_BYTE_DECLARATIONS, GET_BYTE_INITIALIZATION, RtlpBitsClearAnywhere, RtlpBitsClearHigh, RtlpBitsClearLow, TRUE, and ZeroMask.

Referenced by RtlFindClearBitsAndSet().

00353 : 00354 00355 This procedure searches the specified bit map for the specified 00356 contiguous region of clear bits. If a run is not found from the 00357 hint to the end of the bitmap, we will search again from the 00358 beginning of the bitmap. 00359 00360 Arguments: 00361 00362 BitMapHeader - Supplies a pointer to the previously initialized BitMap. 00363 00364 NumberToFind - Supplies the size of the contiguous region to find. 00365 00366 HintIndex - Supplies the index (zero based) of where we should start 00367 the search from within the bitmap. 00368 00369 Return Value: 00370 00371 ULONG - Receives the starting index (zero based) of the contiguous 00372 region of clear bits found. If not such a region cannot be found 00373 a -1 (i.e. 0xffffffff) is returned. 00374 00375 --*/ 00376 00377 { 00378 ULONG SizeOfBitMap; 00379 ULONG SizeInBytes; 00380 00381 ULONG HintBit; 00382 ULONG MainLoopIndex; 00383 00384 GET_BYTE_DECLARATIONS(); 00385 00386 // 00387 // To make the loops in our test run faster we'll extract the 00388 // fields from the bitmap header 00389 // 00390 00391 SizeOfBitMap = BitMapHeader->SizeOfBitMap; 00392 SizeInBytes = (SizeOfBitMap + 7) / 8; 00393 00394 // 00395 // Set any unused bits in the last byte so we won't count them. We do 00396 // this by first checking if there is any odd bits in the last byte. 00397 // 00398 00399 if ((SizeOfBitMap % 8) != 0) { 00400 00401 // 00402 // The last byte has some odd bits so we'll set the high unused 00403 // bits in the last byte to 1's 00404 // 00405 00406 ((PUCHAR)BitMapHeader->Buffer)[SizeInBytes - 1] |= 00407 ZeroMask[SizeOfBitMap % 8]; 00408 } 00409 00410 // 00411 // Calculate from the hint index where the hint byte is and set ourselves 00412 // up to read the hint on the next call to GET_BYTE. To make the 00413 // algorithm run fast we'll only honor hints down to the byte level of 00414 // granularity. There is a possibility that we'll need to execute 00415 // our main logic twice. Once to test from the hint byte to the end of 00416 // the bitmap and the other to test from the start of the bitmap. First 00417 // we need to make sure the Hint Index is within range. 00418 // 00419 00420 if (HintIndex >= SizeOfBitMap) { 00421 00422 HintIndex = 0; 00423 } 00424 00425 HintBit = HintIndex % 8; 00426 00427 for (MainLoopIndex = 0; MainLoopIndex < 2; MainLoopIndex += 1) { 00428 00429 ULONG StartByteIndex; 00430 ULONG EndByteIndex; 00431 00432 UCHAR CurrentByte; 00433 00434 // 00435 // Check for the first time through the main loop, which indicates 00436 // that we are going to start our search at our hint byte 00437 // 00438 00439 if (MainLoopIndex == 0) { 00440 00441 StartByteIndex = HintIndex / 8; 00442 EndByteIndex = SizeInBytes; 00443 00444 // 00445 // This is the second time through the loop, make sure there is 00446 // actually something to check before the hint byte 00447 // 00448 00449 } else if (HintIndex != 0) { 00450 00451 // 00452 // The end index for the second time around is based on the 00453 // number of bits we need to find. We need to use this inorder 00454 // to take the case where the preceding byte to the hint byte 00455 // is the start of our run, and the run includes the hint byte 00456 // and some following bytes, based on the number of bits needed 00457 // The computation is to take the number of bits needed minus 00458 // 2 divided by 8 and then add 2. This will take in to account 00459 // the worst possible case where we have one bit hanging off 00460 // of each end byte, and all intervening bytes are all zero. 00461 // 00462 00463 if (NumberToFind < 2) { 00464 00465 EndByteIndex = HintIndex / 8; 00466 00467 } else { 00468 00469 EndByteIndex = (HintIndex / 8) + ((NumberToFind - 2) / 8) + 2; 00470 00471 // 00472 // Make sure we don't overrun the end of the bitmap 00473 // 00474 00475 if (EndByteIndex > SizeInBytes) { 00476 00477 EndByteIndex = SizeInBytes; 00478 } 00479 } 00480 00481 HintIndex = 0; 00482 HintBit = 0; 00483 StartByteIndex = 0; 00484 00485 // 00486 // Otherwise we already did a complete loop through the bitmap 00487 // so we should simply return -1 to say nothing was found 00488 // 00489 00490 } else { 00491 00492 return 0xffffffff; 00493 } 00494 00495 // 00496 // Set ourselves up to get the next byte 00497 // 00498 00499 GET_BYTE_INITIALIZATION(BitMapHeader, StartByteIndex); 00500 00501 // 00502 // Get the first byte, and set any bits before the hint bit. 00503 // 00504 00505 GET_BYTE( CurrentByte ); 00506 00507 CurrentByte |= FillMask[HintBit]; 00508 00509 // 00510 // If the number of bits can only fit in 1 or 2 bytes (i.e., 9 bits or 00511 // less) we do the following test case. 00512 // 00513 00514 if (NumberToFind <= 9) { 00515 00516 ULONG CurrentBitIndex; 00517 UCHAR PreviousByte; 00518 00519 PreviousByte = 0xff; 00520 00521 // 00522 // Examine all the bytes within our test range searching 00523 // for a fit 00524 // 00525 00526 CurrentBitIndex = StartByteIndex * 8; 00527 00528 while (TRUE) { 00529 00530 // 00531 // If this is the first itteration of the loop, mask Current 00532 // byte with the real hint. 00533 // 00534 00535 // 00536 // Check to see if the current byte coupled with the previous 00537 // byte will satisfy the requirement. The check uses the high 00538 // part of the previous byte and low part of the current byte. 00539 // 00540 00541 if (((ULONG)RtlpBitsClearHigh[PreviousByte] + 00542 (ULONG)RtlpBitsClearLow[CurrentByte]) >= NumberToFind) { 00543 00544 ULONG StartingIndex; 00545 00546 // 00547 // It all fits in these two bytes, so we can compute 00548 // the starting index. This is done by taking the 00549 // index of the current byte (bit 0) and subtracting the 00550 // number of bits its takes to get to the first cleared 00551 // high bit. 00552 // 00553 00554 StartingIndex = CurrentBitIndex - 00555 (LONG)RtlpBitsClearHigh[PreviousByte]; 00556 00557 // 00558 // Now make sure the total size isn't beyond the bitmap 00559 // 00560 00561 if ((StartingIndex + NumberToFind) <= SizeOfBitMap) { 00562 00563 return StartingIndex; 00564 } 00565 } 00566 00567 // 00568 // The previous byte does not help, so check the current byte. 00569 // 00570 00571 if ((ULONG)RtlpBitsClearAnywhere[CurrentByte] >= NumberToFind) { 00572 00573 UCHAR BitMask; 00574 ULONG i; 00575 00576 // 00577 // It all fits in a single byte, so calculate the bit 00578 // number. We do this by taking a mask of the appropriate 00579 // size and shifting it over until it fits. It fits when 00580 // we can bitwise-and the current byte with the bitmask 00581 // and get a zero back. 00582 // 00583 00584 BitMask = FillMask[ NumberToFind ]; 00585 for (i = 0; (BitMask & CurrentByte) != 0; i += 1) { 00586 00587 BitMask <<= 1; 00588 } 00589 00590 // 00591 // return to our caller the located bit index, and the 00592 // number that we found. 00593 // 00594 00595 return CurrentBitIndex + i; 00596 } 00597 00598 // 00599 // For the next iteration through our loop we need to make 00600 // the current byte into the previous byte, and go to the 00601 // top of the loop again. 00602 // 00603 00604 PreviousByte = CurrentByte; 00605 00606 // 00607 // Increment our Bit Index, and either exit, or get the 00608 // next byte. 00609 // 00610 00611 CurrentBitIndex += 8; 00612 00613 if ( CurrentBitIndex < EndByteIndex * 8 ) { 00614 00615 GET_BYTE( CurrentByte ); 00616 00617 } else { 00618 00619 break; 00620 } 00621 00622 } // end loop CurrentBitIndex 00623 00624 // 00625 // The number to find is greater than 9 but if it is less than 15 00626 // then we know it can be satisfied with at most 2 bytes, or 3 bytes 00627 // if the middle byte (of the 3) is all zeros. 00628 // 00629 00630 } else if (NumberToFind < 15) { 00631 00632 ULONG CurrentBitIndex; 00633 00634 UCHAR PreviousPreviousByte; 00635 UCHAR PreviousByte; 00636 00637 PreviousByte = 0xff; 00638 00639 // 00640 // Examine all the bytes within our test range searching 00641 // for a fit 00642 // 00643 00644 CurrentBitIndex = StartByteIndex * 8; 00645 00646 while (TRUE) { 00647 00648 // 00649 // For the next iteration through our loop we need to make 00650 // the current byte into the previous byte, the previous 00651 // byte into the previous previous byte, and go forward. 00652 // 00653 00654 PreviousPreviousByte = PreviousByte; 00655 PreviousByte = CurrentByte; 00656 00657 // 00658 // Increment our Bit Index, and either exit, or get the 00659 // next byte. 00660 // 00661 00662 CurrentBitIndex += 8; 00663 00664 if ( CurrentBitIndex < EndByteIndex * 8 ) { 00665 00666 GET_BYTE( CurrentByte ); 00667 00668 } else { 00669 00670 break; 00671 } 00672 00673 // 00674 // if the previous byte is all zeros then maybe the 00675 // request can be satisfied using the Previous Previous Byte 00676 // Previous Byte, and the Current Byte. 00677 // 00678 00679 if ((PreviousByte == 0) 00680 00681 && 00682 00683 (((ULONG)RtlpBitsClearHigh[PreviousPreviousByte] + 8 + 00684 (ULONG)RtlpBitsClearLow[CurrentByte]) >= NumberToFind)) { 00685 00686 ULONG StartingIndex; 00687 00688 // 00689 // It all fits in these three bytes, so we can compute 00690 // the starting index. This is done by taking the 00691 // index of the previous byte (bit 0) and subtracting 00692 // the number of bits its takes to get to the first 00693 // cleared high bit. 00694 // 00695 00696 StartingIndex = (CurrentBitIndex - 8) - 00697 (LONG)RtlpBitsClearHigh[PreviousPreviousByte]; 00698 00699 // 00700 // Now make sure the total size isn't beyond the bitmap 00701 // 00702 00703 if ((StartingIndex + NumberToFind) <= SizeOfBitMap) { 00704 00705 return StartingIndex; 00706 } 00707 } 00708 00709 // 00710 // Check to see if the Previous byte and current byte 00711 // together satisfy the request. 00712 // 00713 00714 if (((ULONG)RtlpBitsClearHigh[PreviousByte] + 00715 (ULONG)RtlpBitsClearLow[CurrentByte]) >= NumberToFind) { 00716 00717 ULONG StartingIndex; 00718 00719 // 00720 // It all fits in these two bytes, so we can compute 00721 // the starting index. This is done by taking the 00722 // index of the current byte (bit 0) and subtracting the 00723 // number of bits its takes to get to the first cleared 00724 // high bit. 00725 // 00726 00727 StartingIndex = CurrentBitIndex - 00728 (LONG)RtlpBitsClearHigh[PreviousByte]; 00729 00730 // 00731 // Now make sure the total size isn't beyond the bitmap 00732 // 00733 00734 if ((StartingIndex + NumberToFind) <= SizeOfBitMap) { 00735 00736 return StartingIndex; 00737 } 00738 } 00739 00740 } // end loop CurrentBitIndex 00741 00742 // 00743 // The number to find is greater than or equal to 15. This request 00744 // has to have at least one byte of all zeros to be satisfied 00745 // 00746 00747 } else { 00748 00749 ULONG CurrentByteIndex; 00750 00751 ULONG ZeroBytesNeeded; 00752 ULONG ZeroBytesFound; 00753 00754 UCHAR StartOfRunByte; 00755 LONG StartOfRunIndex; 00756 00757 // 00758 // First precalculate how many zero bytes we're going to need 00759 // 00760 00761 ZeroBytesNeeded = (NumberToFind - 7) / 8; 00762 00763 // 00764 // Indicate for the first time through our loop that we haven't 00765 // found a zero byte yet, and indicate that the start of the 00766 // run is the byte just before the start byte index 00767 // 00768 00769 ZeroBytesFound = 0; 00770 StartOfRunByte = 0xff; 00771 StartOfRunIndex = StartByteIndex - 1; 00772 00773 // 00774 // Examine all the bytes in our test range searching for a fit 00775 // 00776 00777 CurrentByteIndex = StartByteIndex; 00778 00779 while (TRUE) { 00780 00781 // 00782 // If the number of zero bytes fits our minimum requirements 00783 // then we can do the additional test to see if we 00784 // actually found a fit 00785 // 00786 00787 if ((ZeroBytesFound >= ZeroBytesNeeded) 00788 00789 && 00790 00791 ((ULONG)RtlpBitsClearHigh[StartOfRunByte] + ZeroBytesFound*8 + 00792 (ULONG)RtlpBitsClearLow[CurrentByte]) >= NumberToFind) { 00793 00794 ULONG StartingIndex; 00795 00796 // 00797 // It all fits in these bytes, so we can compute 00798 // the starting index. This is done by taking the 00799 // StartOfRunIndex times 8 and adding the number of bits 00800 // it takes to get to the first cleared high bit. 00801 // 00802 00803 StartingIndex = (StartOfRunIndex * 8) + 00804 (8 - (LONG)RtlpBitsClearHigh[StartOfRunByte]); 00805 00806 // 00807 // Now make sure the total size isn't beyond the bitmap 00808 // 00809 00810 if ((StartingIndex + NumberToFind) <= SizeOfBitMap) { 00811 00812 return StartingIndex; 00813 } 00814 } 00815 00816 // 00817 // Check to see if the byte is zero and increment 00818 // the number of zero bytes found 00819 // 00820 00821 if (CurrentByte == 0) { 00822 00823 ZeroBytesFound += 1; 00824 00825 // 00826 // The byte isn't a zero so we need to start over again 00827 // looking for zero bytes. 00828 // 00829 00830 } else { 00831 00832 ZeroBytesFound = 0; 00833 StartOfRunByte = CurrentByte; 00834 StartOfRunIndex = CurrentByteIndex; 00835 } 00836 00837 // 00838 // Increment our Byte Index, and either exit, or get the 00839 // next byte. 00840 // 00841 00842 CurrentByteIndex += 1; 00843 00844 if ( CurrentByteIndex < EndByteIndex ) { 00845 00846 GET_BYTE( CurrentByte ); 00847 00848 } else { 00849 00850 break; 00851 } 00852 00853 } // end loop CurrentByteIndex 00854 } 00855 } 00856 00857 // 00858 // We never found a fit so we'll return -1 00859 // 00860 00861 return 0xffffffff; 00862 }

ULONG RtlFindClearBitsAndSet IN PRTL_BITMAP  BitMapHeader,
IN ULONG  NumberToFind,
IN ULONG  HintIndex
 

Definition at line 1382 of file rtl/bitmap.c.

References BitMapHeader, RtlFindClearBits(), and RtlSetBits().

Referenced by DoBitMapTest(), main(), MiAllocatePoolPages(), MiGatherPagefilePages(), MiInsertInSystemSpace(), and MiSessionCreateInternal().

01390 : 01391 01392 This procedure searches the specified bit map for the specified 01393 contiguous region of clear bits, sets the bits and returns the 01394 number of bits found, and the starting bit number which was clear 01395 then set. 01396 01397 Arguments: 01398 01399 BitMapHeader - Supplies a pointer to the previously initialized BitMap. 01400 01401 NumberToFind - Supplies the size of the contiguous region to find. 01402 01403 HintIndex - Supplies the index (zero based) of where we should start 01404 the search from within the bitmap. 01405 01406 Return Value: 01407 01408 ULONG - Receives the starting index (zero based) of the contiguous 01409 region found. If such a region cannot be located a -1 (i.e., 01410 0xffffffff) is returned. 01411 01412 --*/ 01413 01414 { 01415 ULONG StartingIndex; 01416 01417 // 01418 // First look for a run of clear bits that equals the size requested 01419 // 01420 01421 StartingIndex = RtlFindClearBits( BitMapHeader, 01422 NumberToFind, 01423 HintIndex ); 01424 01425 //DbgPrint("FindClearBits %08lx, ", NumberToFind); 01426 //DbgPrint("%08lx", StartingIndex); 01427 //DumpBitMap(BitMapHeader); 01428 01429 if (StartingIndex != 0xffffffff) { 01430 01431 // 01432 // We found a large enough run of clear bits so now set them 01433 // 01434 01435 RtlSetBits( BitMapHeader, StartingIndex, NumberToFind ); 01436 } 01437 01438 // 01439 // And return to our caller 01440 // 01441 01442 return StartingIndex; 01443 01444 }

ULONG RtlFindClearRuns IN PRTL_BITMAP  BitMapHeader,
PRTL_BITMAP_RUN  RunArray,
ULONG  SizeOfRunArray,
BOOLEAN  LocateLongestRuns
 

Definition at line 1764 of file rtl/bitmap.c.

References BitMapHeader, DbgPrint, FillMask, GET_BYTE, GET_BYTE_DECLARATIONS, GET_BYTE_INITIALIZATION, RtlpBitsClearAnywhere, RtlpBitsClearHigh, RtlpBitsClearLow, and ZeroMask.

Referenced by RtlFindLongestRunClear().

01773 : 01774 01775 This procedure finds N contiguous runs of clear bits 01776 within the specified bit map. 01777 01778 Arguments: 01779 01780 BitMapHeader - Supplies a pointer to the previously initialized BitMap. 01781 01782 RunArray - Receives the bit position, and length of each of the free runs 01783 that the procedure locates. The array will be sorted according to 01784 length. 01785 01786 SizeOfRunArray - Supplies the maximum number of entries the caller wants 01787 returned in RunArray 01788 01789 LocateLongestRuns - Indicates if this routine is to return the longest runs 01790 it can find or just the first N runs. 01791 01792 01793 Return Value: 01794 01795 ULONG - Receives the number of runs that the procedure has located and 01796 returned in RunArray 01797 01798 --*/ 01799 01800 { 01801 ULONG RunIndex; 01802 ULONG i; 01803 LONG j; 01804 01805 ULONG SizeOfBitMap; 01806 ULONG SizeInBytes; 01807 01808 ULONG CurrentRunSize; 01809 ULONG CurrentRunIndex; 01810 ULONG CurrentByteIndex; 01811 UCHAR CurrentByte; 01812 01813 UCHAR BitMask; 01814 UCHAR TempNumber; 01815 01816 GET_BYTE_DECLARATIONS(); 01817 01818 // 01819 // Reference the bitmap header to make the loop run faster 01820 // 01821 01822 SizeOfBitMap = BitMapHeader->SizeOfBitMap; 01823 SizeInBytes = (SizeOfBitMap + 7) / 8; 01824 01825 // 01826 // Set any unused bits in the last byte so we won't count them. We do 01827 // this by first checking if there is any odd bits in the last byte. 01828 // 01829 01830 if ((SizeOfBitMap % 8) != 0) { 01831 01832 // 01833 // The last byte has some odd bits so we'll set the high unused 01834 // bits in the last byte to 1's 01835 // 01836 01837 ((PUCHAR)BitMapHeader->Buffer)[SizeInBytes - 1] |= ZeroMask[SizeOfBitMap % 8]; 01838 } 01839 01840 // 01841 // Set it up so we can the use GET_BYTE macro 01842 // 01843 01844 GET_BYTE_INITIALIZATION( BitMapHeader, 0); 01845 01846 // 01847 // Set our RunIndex and current run variables. Run Index allays is the index 01848 // of the next location to fill in or it could be one beyond the end of the 01849 // array. 01850 // 01851 01852 RunIndex = 0; 01853 for (i = 0; i < SizeOfRunArray; i += 1) { RunArray[i].NumberOfBits = 0; } 01854 01855 CurrentRunSize = 0; 01856 CurrentRunIndex = 0; 01857 01858 // 01859 // Examine every byte in the BitMap 01860 // 01861 01862 for (CurrentByteIndex = 0; 01863 CurrentByteIndex < SizeInBytes; 01864 CurrentByteIndex += 1) { 01865 01866 GET_BYTE( CurrentByte ); 01867 01868 #if DBG 01869 if (NtfsDebugIt) { DbgPrint("%d: %08lx %08lx %08lx %08lx %08lx\n",__LINE__,RunIndex,CurrentRunSize,CurrentRunIndex,CurrentByteIndex,CurrentByte); } 01870 #endif 01871 01872 // 01873 // If the current byte is not all zeros we need to (1) check if 01874 // the current run is big enough to be inserted in the output 01875 // array, and (2) check if the current byte inside of itself can 01876 // be inserted, and (3) start a new current run 01877 // 01878 01879 if (CurrentByte != 0x00) { 01880 01881 // 01882 // Compute the final size of the current run 01883 // 01884 01885 CurrentRunSize += RtlpBitsClearLow[CurrentByte]; 01886 01887 // 01888 // Check if the current run be stored in the output array by either 01889 // there being room in the array or the last entry is smaller than 01890 // the current entry 01891 // 01892 01893 if (CurrentRunSize > 0) { 01894 01895 if ((RunIndex < SizeOfRunArray) || 01896 (RunArray[RunIndex-1].NumberOfBits < CurrentRunSize)) { 01897 01898 // 01899 // If necessary increment the RunIndex and shift over the output 01900 // array until we find the slot where the new run belongs. We only 01901 // do the shifting if we're returning longest runs. 01902 // 01903 01904 if (RunIndex < SizeOfRunArray) { RunIndex += 1; } 01905 01906 for (j = RunIndex-2; LocateLongestRuns && (j >= 0) && (RunArray[j].NumberOfBits < CurrentRunSize); j -= 1) { 01907 01908 RunArray[j+1] = RunArray[j]; 01909 } 01910 01911 RunArray[j+1].NumberOfBits = CurrentRunSize; 01912 RunArray[j+1].StartingIndex = CurrentRunIndex; 01913 01914 #if DBG 01915 if (NtfsDebugIt) { DbgPrint("%d: %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n", 01916 __LINE__,RunIndex,CurrentRunSize,CurrentRunIndex,CurrentByteIndex,CurrentByte,j,RunArray[j+1].NumberOfBits,RunArray[j+1].StartingIndex); } 01917 #endif 01918 01919 // 01920 // Now if the array is full and we are not doing longest runs return 01921 // to our caller 01922 // 01923 01924 if (!LocateLongestRuns && (RunIndex >= SizeOfRunArray)) { 01925 01926 return RunIndex; 01927 } 01928 } 01929 } 01930 01931 // 01932 // The next run starts with the remaining clear bits in the 01933 // current byte. We set this up before we check inside the 01934 // current byte for a longer run, because the latter test 01935 // might require extra work. 01936 // 01937 01938 CurrentRunSize = RtlpBitsClearHigh[ CurrentByte ]; 01939 CurrentRunIndex = (CurrentByteIndex * 8) + (8 - CurrentRunSize); 01940 01941 // 01942 // Set the low and high bits, otherwise we'll wind up thinking that we have a 01943 // small run that needs to get added to the array, but these bits have 01944 // just been accounting for 01945 // 01946 01947 CurrentByte |= FillMask[RtlpBitsClearLow[CurrentByte]] | 01948 ZeroMask[8-RtlpBitsClearHigh[CurrentByte]]; 01949 01950 // 01951 // Check if the current byte contains a run inside of it that 01952 // should go into the output array. There may be multiple 01953 // runs in the byte that we need to insert. 01954 // 01955 01956 while ((CurrentByte != 0xff) 01957 01958 && 01959 01960 ((RunIndex < SizeOfRunArray) || 01961 (RunArray[RunIndex-1].NumberOfBits < (ULONG)RtlpBitsClearAnywhere[CurrentByte]))) { 01962 01963 TempNumber = RtlpBitsClearAnywhere[CurrentByte]; 01964 01965 // 01966 // Somewhere in the current byte is a run to be inserted of 01967 // size TempNumber. All we need to do is find the index for this run. 01968 // 01969 01970 BitMask = FillMask[ TempNumber ]; 01971 01972 for (i = 0; (BitMask & CurrentByte) != 0; i += 1) { 01973 01974 BitMask <<= 1; 01975 } 01976 01977 // 01978 // If necessary increment the RunIndex and shift over the output 01979 // array until we find the slot where the new run belongs. We only 01980 // do the shifting if we're returning longest runs. 01981 // 01982 01983 if (RunIndex < SizeOfRunArray) { RunIndex += 1; } 01984 01985 for (j = RunIndex-2; LocateLongestRuns && (j >= 0) && (RunArray[j].NumberOfBits < TempNumber); j -= 1) { 01986 01987 RunArray[j+1] = RunArray[j]; 01988 } 01989 01990 RunArray[j+1].NumberOfBits = TempNumber; 01991 RunArray[j+1].StartingIndex = (CurrentByteIndex * 8) + i; 01992 01993 #if DBG 01994 if (NtfsDebugIt) { DbgPrint("%d: %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n", 01995 __LINE__,RunIndex,CurrentRunSize,CurrentRunIndex,CurrentByteIndex,CurrentByte,j,RunArray[j+1].NumberOfBits,RunArray[j+1].StartingIndex); } 01996 #endif 01997 01998 // 01999 // Now if the array is full and we are not doing longest runs return 02000 // to our caller 02001 // 02002 02003 if (!LocateLongestRuns && (RunIndex >= SizeOfRunArray)) { 02004 02005 return RunIndex; 02006 } 02007 02008 // 02009 // Mask out the bits and look for another run in the current byte 02010 // 02011 02012 CurrentByte |= BitMask; 02013 } 02014 02015 // 02016 // Otherwise the current byte is all zeros and 02017 // we simply continue with the current run 02018 // 02019 02020 } else { 02021 02022 CurrentRunSize += 8; 02023 } 02024 } 02025 02026 #if DBG 02027 if (NtfsDebugIt) { DbgPrint("%d: %08lx %08lx %08lx %08lx %08lx\n",__LINE__,RunIndex,CurrentRunSize,CurrentRunIndex,CurrentByteIndex,CurrentByte); } 02028 #endif 02029 02030 // 02031 // See if we finished looking over the bitmap with an open current 02032 // run that should be inserted in the output array 02033 // 02034 02035 if (CurrentRunSize > 0) { 02036 02037 if ((RunIndex < SizeOfRunArray) || 02038 (RunArray[RunIndex-1].NumberOfBits < CurrentRunSize)) { 02039 02040 // 02041 // If necessary increment the RunIndex and shift over the output 02042 // array until we find the slot where the new run belongs. 02043 // 02044 02045 if (RunIndex < SizeOfRunArray) { RunIndex += 1; } 02046 02047 for (j = RunIndex-2; LocateLongestRuns && (j >= 0) && (RunArray[j].NumberOfBits < CurrentRunSize); j -= 1) { 02048 02049 RunArray[j+1] = RunArray[j]; 02050 } 02051 02052 RunArray[j+1].NumberOfBits = CurrentRunSize; 02053 RunArray[j+1].StartingIndex = CurrentRunIndex; 02054 02055 #if DBG 02056 if (NtfsDebugIt) { DbgPrint("%d: %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n", 02057 __LINE__,RunIndex,CurrentRunSize,CurrentRunIndex,CurrentByteIndex,CurrentByte,j,RunArray[j+1].NumberOfBits,RunArray[j+1].StartingIndex); } 02058 #endif 02059 } 02060 } 02061 02062 // 02063 // Return to our caller 02064 // 02065 02066 return RunIndex; 02067 }

ULONG RtlFindFirstRunClear IN PRTL_BITMAP  BitMapHeader,
OUT PULONG  StartingIndex
 

Definition at line 2117 of file rtl/bitmap.c.

References BitMapHeader, and RtlFindNextForwardRunClear().

02124 : 02125 02126 This procedure finds the first contiguous range of clear bits 02127 within the specified bit map. 02128 02129 Arguments: 02130 02131 BitMapHeader - Supplies a pointer to the previously initialized BitMap. 02132 02133 StartingIndex - Receives the index (zero based) of the first run 02134 equal to the longest run of clear bits in the BitMap. 02135 02136 Return Value: 02137 02138 ULONG - Receives the number of bits contained in the first contiguous 02139 run of clear bits. 02140 02141 --*/ 02142 02143 { 02144 return RtlFindNextForwardRunClear(BitMapHeader, 0, StartingIndex); 02145 }

ULONG RtlFindLastBackwardRunClear IN PRTL_BITMAP  BitMapHeader,
IN ULONG  FromIndex,
IN PULONG  StartingRunIndex
 

Definition at line 2779 of file rtl/bitmap.c.

References BitMapHeader, End, FillMaskUlong, RTL_PAGED_CODE, and Start.

02784 { 02785 ULONG Start; 02786 ULONG End; 02787 PULONG PHunk; 02788 ULONG Hunk; 02789 02790 RTL_PAGED_CODE(); 02791 02792 // 02793 // Take care of the boundary case of the null bitmap 02794 // 02795 02796 if (BitMapHeader->SizeOfBitMap == 0) { 02797 02798 *StartingRunIndex = FromIndex; 02799 return 0; 02800 } 02801 02802 // 02803 // Scan backwards for the first clear bit 02804 // 02805 02806 End = FromIndex; 02807 02808 // 02809 // Build pointer to the ULONG word in the bitmap 02810 // containing the End bit, then read in the bitmap 02811 // hunk. Set the rest of the bits in this word, NOT 02812 // inclusive of the FromIndex bit. 02813 // 02814 02815 PHunk = BitMapHeader->Buffer + (End / 32); 02816 Hunk = *PHunk | ~FillMaskUlong[(End % 32) + 1]; 02817 02818 // 02819 // If the first subword is set then we can proceed to 02820 // take big steps in the bitmap since we are now ULONG 02821 // aligned in the search 02822 // 02823 02824 if (Hunk == (ULONG)~0) { 02825 02826 // 02827 // Adjust the pointers backwards 02828 // 02829 02830 End -= (End % 32) + 1; 02831 PHunk--; 02832 02833 while ( PHunk > BitMapHeader->Buffer ) { 02834 02835 // 02836 // Stop at first word with set bits 02837 // 02838 02839 if (*PHunk != (ULONG)~0) break; 02840 02841 PHunk--; 02842 End -= 32; 02843 } 02844 } 02845 02846 // 02847 // Bitwise search backward for the clear bit 02848 // 02849 02850 while ((End != MAXULONG) && (RtlCheckBit( BitMapHeader, End ) == 1)) { End -= 1; } 02851 02852 // 02853 // Scan backwards for the first set bit 02854 // 02855 02856 Start = End; 02857 02858 // 02859 // We know that the clear bit was in the last word we looked at, 02860 // so continue from there to find the next set bit, clearing the 02861 // previous bits in the word. 02862 // 02863 02864 Hunk = *PHunk & FillMaskUlong[Start % 32]; 02865 02866 // 02867 // If the subword is unset then we can proceed in big steps 02868 // 02869 02870 if (Hunk == (ULONG)0) { 02871 02872 // 02873 // Adjust the pointers backward 02874 // 02875 02876 Start -= (Start % 32) + 1; 02877 PHunk--; 02878 02879 while ( PHunk > BitMapHeader->Buffer ) { 02880 02881 // 02882 // Stop at first word with set bits 02883 // 02884 02885 if (*PHunk != (ULONG)0) break; 02886 02887 PHunk--; 02888 Start -= 32; 02889 } 02890 } 02891 02892 // 02893 // Bitwise search backward for the set bit 02894 // 02895 02896 while ((Start != MAXULONG) && (RtlCheckBit( BitMapHeader, Start ) == 0)) { Start -= 1; } 02897 02898 // 02899 // Compute the index and return the length 02900 // 02901 02902 *StartingRunIndex = Start + 1; 02903 return (End - Start); 02904 }

CCHAR RtlFindLeastSignificantBit IN ULONGLONG  Set  ) 
 

Definition at line 2999 of file rtl/bitmap.c.

References BM_0, BM_01, BM_0123, BM_2, BM_4, BM_45, BM_6, and RtlpBitsClearLow.

03004 : 03005 03006 This procedure finds the least significant non-zero bit in Set and 03007 returns it's zero-based position. 03008 03009 Arguments: 03010 03011 Set - Supplies the 64-bit bitmap. 03012 03013 Return Value: 03014 03015 Set != 0: 03016 Bit position of the least significant non-zero bit in Set. 03017 03018 Set == 0: 03019 -1. 03020 03021 --*/ 03022 { 03023 UCHAR index; 03024 UCHAR bitOffset; 03025 UCHAR lookup; 03026 03027 if ((Set & BM_0123) != 0) { 03028 if ((Set & BM_01) != 0) { 03029 if ((Set & BM_0) != 0) { 03030 bitOffset = 0 * 8; 03031 } else { 03032 bitOffset = 1 * 8; 03033 } 03034 } else { 03035 if ((Set & BM_2) != 0) { 03036 bitOffset = 2 * 8; 03037 } else { 03038 bitOffset = 3 * 8; 03039 } 03040 } 03041 } else { 03042 if ((Set & BM_45) != 0) { 03043 if ((Set & BM_4) != 0) { 03044 bitOffset = 4 * 8; 03045 } else { 03046 bitOffset = 5 * 8; 03047 } 03048 } else { 03049 if ((Set & BM_6) != 0) { 03050 bitOffset = 6 * 8; 03051 } else { 03052 03053 // 03054 // The test for Set == 0 is postponed to here, it is expected 03055 // to be rare. Note that if we had our own version of 03056 // RtlpBitsClearHigh[] we could eliminate this test entirely, 03057 // reducing the average number of tests from 3.125 to 3. 03058 // 03059 03060 if (Set == 0) { 03061 return -1; 03062 } 03063 03064 bitOffset = 7 * 8; 03065 } 03066 } 03067 } 03068 03069 lookup = (UCHAR)(Set >> bitOffset); 03070 index = RtlpBitsClearLow[lookup] + bitOffset; 03071 return index; 03072 }

ULONG RtlFindLongestRunClear IN PRTL_BITMAP  BitMapHeader,
OUT PULONG  StartingIndex
 

Definition at line 2071 of file rtl/bitmap.c.

References BitMapHeader, RtlFindClearRuns(), and TRUE.

02078 : 02079 02080 This procedure finds the largest contiguous range of clear bits 02081 within the specified bit map. 02082 02083 Arguments: 02084 02085 BitMapHeader - Supplies a pointer to the previously initialized BitMap. 02086 02087 StartingIndex - Receives the index (zero based) of the first run 02088 equal to the longest run of clear bits in the BitMap. 02089 02090 Return Value: 02091 02092 ULONG - Receives the number of bits contained in the largest contiguous 02093 run of clear bits. 02094 02095 --*/ 02096 02097 { 02098 RTL_BITMAP_RUN RunArray[1]; 02099 02100 // 02101 // Locate the longest run in the bitmap. If there is one then 02102 // return that run otherwise return the error condition. 02103 // 02104 02105 if (RtlFindClearRuns( BitMapHeader, RunArray, 1, TRUE ) == 1) { 02106 02107 *StartingIndex = RunArray[0].StartingIndex; 02108 return RunArray[0].NumberOfBits; 02109 } 02110 02111 *StartingIndex = 0; 02112 return 0; 02113 }

CCHAR RtlFindMostSignificantBit IN ULONGLONG  Set  ) 
 

Definition at line 2923 of file rtl/bitmap.c.

References BM_1, BM_23, BM_3, BM_4567, BM_5, BM_67, BM_7, and RtlpBitsClearHigh.

Referenced by NtAllocateVirtualMemory(), and NtMapViewOfSection().

02928 : 02929 02930 This procedure finds the most significant non-zero bit in Set and 02931 returns it's zero-based position. 02932 02933 Arguments: 02934 02935 Set - Supplies the 64-bit bitmap. 02936 02937 Return Value: 02938 02939 Set != 0: 02940 Bit position of the most significant set bit in Set. 02941 02942 Set == 0: 02943 -1. 02944 02945 --*/ 02946 { 02947 UCHAR index; 02948 UCHAR bitOffset; 02949 UCHAR lookup; 02950 02951 if ((Set & BM_4567) != 0) { 02952 if ((Set & BM_67) != 0) { 02953 if ((Set & BM_7) != 0) { 02954 bitOffset = 7 * 8; 02955 } else { 02956 bitOffset = 6 * 8; 02957 } 02958 } else { 02959 if ((Set & BM_5) != 0) { 02960 bitOffset = 5 * 8; 02961 } else { 02962 bitOffset = 4 * 8; 02963 } 02964 } 02965 } else { 02966 if ((Set & BM_23) != 0) { 02967 if ((Set & BM_3) != 0) { 02968 bitOffset = 3 * 8; 02969 } else { 02970 bitOffset = 2 * 8; 02971 } 02972 } else { 02973 if ((Set & BM_1) != 0) { 02974 bitOffset = 1 * 8; 02975 } else { 02976 02977 // 02978 // The test for Set == 0 is postponed to here, it is expected 02979 // to be rare. Note that if we had our own version of 02980 // RtlpBitsClearHigh[] we could eliminate this test entirely, 02981 // reducing the average number of tests from 3.125 to 3. 02982 // 02983 02984 if (Set == 0) { 02985 return -1; 02986 } 02987 02988 bitOffset = 0 * 8; 02989 } 02990 } 02991 } 02992 02993 lookup = (UCHAR)(Set >> bitOffset); 02994 index = (7 - RtlpBitsClearHigh[lookup]) + bitOffset; 02995 return index; 02996 }

ULONG RtlFindNextForwardRunClear IN PRTL_BITMAP  BitMapHeader,
IN ULONG  FromIndex,
IN PULONG  StartingRunIndex
 

Definition at line 2635 of file rtl/bitmap.c.

References BitMapHeader, End, FillMaskUlong, and Start.

Referenced by RtlFindFirstRunClear().

02640 { 02641 ULONG Start; 02642 ULONG End; 02643 PULONG PHunk, BitMapEnd; 02644 ULONG Hunk; 02645 02646 // 02647 // Take care of the boundary case of the null bitmap 02648 // 02649 02650 if (BitMapHeader->SizeOfBitMap == 0) { 02651 02652 *StartingRunIndex = FromIndex; 02653 return 0; 02654 } 02655 02656 // 02657 // Compute the last word address in the bitmap 02658 // 02659 02660 BitMapEnd = BitMapHeader->Buffer + ((BitMapHeader->SizeOfBitMap - 1) / 32); 02661 02662 // 02663 // Scan forward for the first clear bit 02664 // 02665 02666 Start = FromIndex; 02667 02668 // 02669 // Build pointer to the ULONG word in the bitmap 02670 // containing the Start bit 02671 // 02672 02673 PHunk = BitMapHeader->Buffer + (Start / 32); 02674 02675 // 02676 // If the first subword is set then we can proceed to 02677 // take big steps in the bitmap since we are now ULONG 02678 // aligned in the search. Make sure we aren't improperly 02679 // looking at the last word in the bitmap. 02680 // 02681 02682 if (PHunk != BitMapEnd) { 02683 02684 // 02685 // Read in the bitmap hunk. Set the previous bits in this word. 02686 // 02687 02688 Hunk = *PHunk | FillMaskUlong[Start % 32]; 02689 02690 if (Hunk == (ULONG)~0) { 02691 02692 // 02693 // Adjust the pointers forward 02694 // 02695 02696 Start += 32 - (Start % 32); 02697 PHunk++; 02698 02699 while ( PHunk < BitMapEnd ) { 02700 02701 // 02702 // Stop at first word with unset bits 02703 // 02704 02705 if (*PHunk != (ULONG)~0) break; 02706 02707 PHunk++; 02708 Start += 32; 02709 } 02710 } 02711 } 02712 02713 // 02714 // Bitwise search forward for the clear bit 02715 // 02716 02717 while ((Start < BitMapHeader->SizeOfBitMap) && (RtlCheckBit( BitMapHeader, Start ) == 1)) { Start += 1; } 02718 02719 // 02720 // Scan forward for the first set bit 02721 // 02722 02723 End = Start; 02724 02725 // 02726 // If we aren't in the last word of the bitmap we may be 02727 // able to keep taking big steps 02728 // 02729 02730 if (PHunk != BitMapEnd) { 02731 02732 // 02733 // We know that the clear bit was in the last word we looked at, 02734 // so continue from there to find the next set bit, clearing the 02735 // previous bits in the word 02736 // 02737 02738 Hunk = *PHunk & ~FillMaskUlong[End % 32]; 02739 02740 if (Hunk == (ULONG)0) { 02741 02742 // 02743 // Adjust the pointers forward 02744 // 02745 02746 End += 32 - (End % 32); 02747 PHunk++; 02748 02749 while ( PHunk < BitMapEnd ) { 02750 02751 // 02752 // Stop at first word with set bits 02753 // 02754 02755 if (*PHunk != (ULONG)0) break; 02756 02757 PHunk++; 02758 End += 32; 02759 } 02760 } 02761 } 02762 02763 // 02764 // Bitwise search forward for the set bit 02765 // 02766 02767 while ((End < BitMapHeader->SizeOfBitMap) && (RtlCheckBit( BitMapHeader, End ) == 0)) { End += 1; } 02768 02769 // 02770 // Compute the index and return the length 02771 // 02772 02773 *StartingRunIndex = Start; 02774 return (End - Start); 02775 }

ULONG RtlFindSetBits IN PRTL_BITMAP  BitMapHeader,
IN ULONG  NumberToFind,
IN ULONG  HintIndex
 

Definition at line 866 of file rtl/bitmap.c.

References BitMapHeader, FillMask, GET_BYTE, GET_BYTE_DECLARATIONS, GET_BYTE_INITIALIZATION, RtlpBitSetAnywhere, RtlpBitsSetHigh, RtlpBitsSetLow, TRUE, and ZeroMask.

Referenced by MiCleanPhysicalProcessPages(), NtAllocateUserPhysicalPages(), and RtlFindSetBitsAndClear().

00874 : 00875 00876 This procedure searches the specified bit map for the specified 00877 contiguous region of set bits. 00878 00879 Arguments: 00880 00881 BitMapHeader - Supplies a pointer to the previously initialized BitMap. 00882 00883 NumberToFind - Supplies the size of the contiguous region to find. 00884 00885 HintIndex - Supplies the index (zero based) of where we should start 00886 the search from within the bitmap. 00887 00888 Return Value: 00889 00890 ULONG - Receives the starting index (zero based) of the contiguous 00891 region of set bits found. If such a region cannot be found then 00892 a -1 (i.e., 0xffffffff) is returned. 00893 00894 --*/ 00895 00896 { 00897 ULONG SizeOfBitMap; 00898 ULONG SizeInBytes; 00899 00900 ULONG HintBit; 00901 ULONG MainLoopIndex; 00902 00903 GET_BYTE_DECLARATIONS(); 00904 00905 // 00906 // To make the loops in our test run faster we'll extract the 00907 // fields from the bitmap header 00908 // 00909 00910 SizeOfBitMap = BitMapHeader->SizeOfBitMap; 00911 SizeInBytes = (SizeOfBitMap + 7) / 8; 00912 00913 // 00914 // Set any unused bits in the last byte so we won't count them. We do 00915 // this by first checking if there is any odd bits in the last byte. 00916 // 00917 00918 if ((SizeOfBitMap % 8) != 0) { 00919 00920 // 00921 // The last byte has some odd bits so we'll set the high unused 00922 // bits in the last byte to 0's 00923 // 00924 00925 ((PUCHAR)BitMapHeader->Buffer)[SizeInBytes - 1] &= 00926 FillMask[SizeOfBitMap % 8]; 00927 } 00928 00929 // 00930 // Calculate from the hint index where the hint byte is and set ourselves 00931 // up to read the hint on the next call to GET_BYTE. To make the 00932 // algorithm run fast we'll only honor hints down to the byte level of 00933 // granularity. There is a possibility that we'll need to execute 00934 // our main logic twice. Once to test from the hint byte to the end of 00935 // the bitmap and the other to test from the start of the bitmap. First 00936 // we need to make sure the Hint Index is within range. 00937 // 00938 00939 if (HintIndex >= SizeOfBitMap) { 00940 00941 HintIndex = 0; 00942 } 00943 00944 HintBit = HintIndex % 8; 00945 00946 for (MainLoopIndex = 0; MainLoopIndex < 2; MainLoopIndex += 1) { 00947 00948 ULONG StartByteIndex; 00949 ULONG EndByteIndex; 00950 00951 UCHAR CurrentByte; 00952 00953 // 00954 // Check for the first time through the main loop, which indicates 00955 // that we are going to start our search at our hint byte 00956 // 00957 00958 if (MainLoopIndex == 0) { 00959 00960 StartByteIndex = HintIndex / 8; 00961 EndByteIndex = SizeInBytes; 00962 00963 // 00964 // This is the second time through the loop, make sure there is 00965 // actually something to check before the hint byte 00966 // 00967 00968 } else if (HintIndex != 0) { 00969 00970 // 00971 // The end index for the second time around is based on the 00972 // number of bits we need to find. We need to use this inorder 00973 // to take the case where the preceding byte to the hint byte 00974 // is the start of our run, and the run includes the hint byte 00975 // and some following bytes, based on the number of bits needed 00976 // The computation is to take the number of bits needed minus 00977 // 2 divided by 8 and then add 2. This will take in to account 00978 // the worst possible case where we have one bit hanging off 00979 // of each end byte, and all intervening bytes are all zero. 00980 // We only need to add one in the following equation because 00981 // HintByte is already counted. 00982 // 00983 00984 if (NumberToFind < 2) { 00985 00986 EndByteIndex = HintIndex / 8; 00987 00988 } else { 00989 00990 EndByteIndex = HintIndex / 8 + ((NumberToFind - 2) / 8) + 1; 00991 00992 // 00993 // Make sure we don't overrun the end of the bitmap 00994 // 00995 00996 if (EndByteIndex > SizeInBytes) { 00997 00998 EndByteIndex = SizeInBytes; 00999 } 01000 } 01001 01002 StartByteIndex = 0; 01003 HintIndex = 0; 01004 HintBit = 0; 01005 01006 // 01007 // Otherwise we already did a complete loop through the bitmap 01008 // so we should simply return -1 to say nothing was found 01009 // 01010 01011 } else { 01012 01013 return 0xffffffff; 01014 } 01015 01016 // 01017 // Set ourselves up to get the next byte 01018 // 01019 01020 GET_BYTE_INITIALIZATION(BitMapHeader, StartByteIndex); 01021 01022 // 01023 // Get the first byte, and clear any bits before the hint bit. 01024 // 01025 01026 GET_BYTE( CurrentByte ); 01027 01028 CurrentByte &= ZeroMask[HintBit]; 01029 01030 // 01031 // If the number of bits can only fit in 1 or 2 bytes (i.e., 9 bits or 01032 // less) we do the following test case. 01033 // 01034 01035 if (NumberToFind <= 9) { 01036 01037 ULONG CurrentBitIndex; 01038 01039 UCHAR PreviousByte; 01040 01041 PreviousByte = 0x00; 01042 01043 // 01044 // Examine all the bytes within our test range searching 01045 // for a fit 01046 // 01047 01048 CurrentBitIndex = StartByteIndex * 8; 01049 01050 while (TRUE) { 01051 01052 // 01053 // Check to see if the current byte coupled with the previous 01054 // byte will satisfy the requirement. The check uses the high 01055 // part of the previous byte and low part of the current byte. 01056 // 01057 01058 if (((ULONG)RtlpBitsSetHigh(PreviousByte) + 01059 (ULONG)RtlpBitsSetLow(CurrentByte)) >= NumberToFind) { 01060 01061 ULONG StartingIndex; 01062 01063 // 01064 // It all fits in these two bytes, so we can compute 01065 // the starting index. This is done by taking the 01066 // index of the current byte (bit 0) and subtracting the 01067 // number of bits its takes to get to the first set 01068 // high bit. 01069 // 01070 01071 StartingIndex = CurrentBitIndex - 01072 (LONG)RtlpBitsSetHigh(PreviousByte); 01073 01074 // 01075 // Now make sure the total size isn't beyond the bitmap 01076 // 01077 01078 if ((StartingIndex + NumberToFind) <= SizeOfBitMap) { 01079 01080 return StartingIndex; 01081 } 01082 } 01083 01084 // 01085 // The previous byte does not help, so check the current byte. 01086 // 01087 01088 if ((ULONG)RtlpBitSetAnywhere(CurrentByte) >= NumberToFind) { 01089 01090 UCHAR BitMask; 01091 ULONG i; 01092 01093 // 01094 // It all fits in a single byte, so calculate the bit 01095 // number. We do this by taking a mask of the appropriate 01096 // size and shifting it over until it fits. It fits when 01097 // we can bitwise-and the current byte with the bit mask 01098 // and get back the bit mask. 01099 // 01100 01101 BitMask = FillMask[ NumberToFind ]; 01102 for (i = 0; (BitMask & CurrentByte) != BitMask; i += 1) { 01103 01104 BitMask <<= 1; 01105 } 01106 01107 // 01108 // return to our caller the located bit index, and the 01109 // number that we found. 01110 // 01111 01112 return CurrentBitIndex + i; 01113 } 01114 01115 // 01116 // For the next iteration through our loop we need to make 01117 // the current byte into the previous byte, and go to the 01118 // top of the loop again. 01119 // 01120 01121 PreviousByte = CurrentByte; 01122 01123 // 01124 // Increment our Bit Index, and either exit, or get the 01125 // next byte. 01126 // 01127 01128 CurrentBitIndex += 8; 01129 01130 if ( CurrentBitIndex < EndByteIndex * 8 ) { 01131 01132 GET_BYTE( CurrentByte ); 01133 01134 } else { 01135 01136 break; 01137 } 01138 01139 } // end loop CurrentBitIndex 01140 01141 // 01142 // The number to find is greater than 9 but if it is less than 15 01143 // then we know it can be satisfied with at most 2 bytes, or 3 bytes 01144 // if the middle byte (of the 3) is all ones. 01145 // 01146 01147 } else if (NumberToFind < 15) { 01148 01149 ULONG CurrentBitIndex; 01150 01151 UCHAR PreviousPreviousByte; 01152 UCHAR PreviousByte; 01153 01154 PreviousByte = 0x00; 01155 01156 // 01157 // Examine all the bytes within our test range searching 01158 // for a fit 01159 // 01160 01161 CurrentBitIndex = StartByteIndex * 8; 01162 01163 while (TRUE) { 01164 01165 // 01166 // For the next iteration through our loop we need to make 01167 // the current byte into the previous byte, the previous 01168 // byte into the previous previous byte, and go to the 01169 // top of the loop again. 01170 // 01171 01172 PreviousPreviousByte = PreviousByte; 01173 PreviousByte = CurrentByte; 01174 01175 // 01176 // Increment our Bit Index, and either exit, or get the 01177 // next byte. 01178 // 01179 01180 CurrentBitIndex += 8; 01181 01182 if ( CurrentBitIndex < EndByteIndex * 8 ) { 01183 01184 GET_BYTE( CurrentByte ); 01185 01186 } else { 01187 01188 break; 01189 } 01190 01191 // 01192 // if the previous byte is all ones then maybe the 01193 // request can be satisfied using the Previous Previous Byte 01194 // Previous Byte, and the Current Byte. 01195 // 01196 01197 if ((PreviousByte == 0xff) 01198 01199 && 01200 01201 (((ULONG)RtlpBitsSetHigh(PreviousPreviousByte) + 8 + 01202 (ULONG)RtlpBitsSetLow(CurrentByte)) >= NumberToFind)) { 01203 01204 ULONG StartingIndex; 01205 01206 // 01207 // It all fits in these three bytes, so we can compute 01208 // the starting index. This is done by taking the 01209 // index of the previous byte (bit 0) and subtracting 01210 // the number of bits its takes to get to the first 01211 // set high bit. 01212 // 01213 01214 StartingIndex = (CurrentBitIndex - 8) - 01215 (LONG)RtlpBitsSetHigh(PreviousPreviousByte); 01216 01217 // 01218 // Now make sure the total size isn't beyond the bitmap 01219 // 01220 01221 if ((StartingIndex + NumberToFind) <= SizeOfBitMap) { 01222 01223 return StartingIndex; 01224 } 01225 } 01226 01227 // 01228 // Check to see if the Previous byte and current byte 01229 // together satisfy the request. 01230 // 01231 01232 if (((ULONG)RtlpBitsSetHigh(PreviousByte) + 01233 (ULONG)RtlpBitsSetLow(CurrentByte)) >= NumberToFind) { 01234 01235 ULONG StartingIndex; 01236 01237 // 01238 // It all fits in these two bytes, so we can compute 01239 // the starting index. This is done by taking the 01240 // index of the current byte (bit 0) and subtracting the 01241 // number of bits its takes to get to the first set 01242 // high bit. 01243 // 01244 01245 StartingIndex = CurrentBitIndex - 01246 (LONG)RtlpBitsSetHigh(PreviousByte); 01247 01248 // 01249 // Now make sure the total size isn't beyond the bitmap 01250 // 01251 01252 if ((StartingIndex + NumberToFind) <= SizeOfBitMap) { 01253 01254 return StartingIndex; 01255 } 01256 } 01257 } // end loop CurrentBitIndex 01258 01259 // 01260 // The number to find is greater than or equal to 15. This request 01261 // has to have at least one byte of all ones to be satisfied 01262 // 01263 01264 } else { 01265 01266 ULONG CurrentByteIndex; 01267 01268 ULONG OneBytesNeeded; 01269 ULONG OneBytesFound; 01270 01271 UCHAR StartOfRunByte; 01272 LONG StartOfRunIndex; 01273 01274 // 01275 // First precalculate how many one bytes we're going to need 01276 // 01277 01278 OneBytesNeeded = (NumberToFind - 7) / 8; 01279 01280 // 01281 // Indicate for the first time through our loop that we haven't 01282 // found a one byte yet, and indicate that the start of the 01283 // run is the byte just before the start byte index 01284 // 01285 01286 OneBytesFound = 0; 01287 StartOfRunByte = 0x00; 01288 StartOfRunIndex = StartByteIndex - 1; 01289 01290 // 01291 // Examine all the bytes in our test range searching for a fit 01292 // 01293 01294 CurrentByteIndex = StartByteIndex; 01295 01296 while (TRUE) { 01297 01298 // 01299 // If the number of zero bytes fits our minimum requirements 01300 // then we can do the additional test to see if we 01301 // actually found a fit 01302 // 01303 01304 if ((OneBytesFound >= OneBytesNeeded) 01305 01306 && 01307 01308 ((ULONG)RtlpBitsSetHigh(StartOfRunByte) + OneBytesFound*8 + 01309 (ULONG)RtlpBitsSetLow(CurrentByte)) >= NumberToFind) { 01310 01311 ULONG StartingIndex; 01312 01313 // 01314 // It all fits in these bytes, so we can compute 01315 // the starting index. This is done by taking the 01316 // StartOfRunIndex times 8 and adding the number of bits 01317 // it takes to get to the first set high bit. 01318 // 01319 01320 StartingIndex = (StartOfRunIndex * 8) + 01321 (8 - (LONG)RtlpBitsSetHigh(StartOfRunByte)); 01322 01323 // 01324 // Now make sure the total size isn't beyond the bitmap 01325 // 01326 01327 if ((StartingIndex + NumberToFind) <= SizeOfBitMap) { 01328 01329 return StartingIndex; 01330 } 01331 } 01332 01333 // 01334 // Check to see if the byte is all ones and increment 01335 // the number of one bytes found 01336 // 01337 01338 if (CurrentByte == 0xff) { 01339 01340 OneBytesFound += 1; 01341 01342 // 01343 // The byte isn't all ones so we need to start over again 01344 // looking for one bytes. 01345 // 01346 01347 } else { 01348 01349 OneBytesFound = 0; 01350 StartOfRunByte = CurrentByte; 01351 StartOfRunIndex = CurrentByteIndex; 01352 } 01353 01354 // 01355 // Increment our Byte Index, and either exit, or get the 01356 // next byte. 01357 // 01358 01359 CurrentByteIndex += 1; 01360 01361 if ( CurrentByteIndex < EndByteIndex ) { 01362 01363 GET_BYTE( CurrentByte ); 01364 01365 } else { 01366 01367 break; 01368 } 01369 } // end loop CurrentByteIndex 01370 } 01371 } 01372 01373 // 01374 // We never found a fit so we'll return -1 01375 // 01376 01377 return 0xffffffff; 01378 }

ULONG RtlFindSetBitsAndClear IN PRTL_BITMAP  BitMapHeader,
IN ULONG  NumberToFind,
IN ULONG  HintIndex
 

Definition at line 1448 of file rtl/bitmap.c.

References BitMapHeader, RtlClearBits(), and RtlFindSetBits().

Referenced by DoBitMapTest().

01456 : 01457 01458 This procedure searches the specified bit map for the specified 01459 contiguous region of set bits, clears the bits and returns the 01460 number of bits found and the starting bit number which was set then 01461 clear. 01462 01463 Arguments: 01464 01465 BitMapHeader - Supplies a pointer to the previously initialized BitMap. 01466 01467 NumberToFind - Supplies the size of the contiguous region to find. 01468 01469 HintIndex - Supplies the index (zero based) of where we should start 01470 the search from within the bitmap. 01471 01472 Return Value: 01473 01474 ULONG - Receives the starting index (zero based) of the contiguous 01475 region found. If such a region cannot be located a -1 (i.e., 01476 0xffffffff) is returned. 01477 01478 01479 --*/ 01480 01481 { 01482 ULONG StartingIndex; 01483 01484 // 01485 // First look for a run of set bits that equals the size requested 01486 // 01487 01488 if ((StartingIndex = RtlFindSetBits( BitMapHeader, 01489 NumberToFind, 01490 HintIndex )) != 0xffffffff) { 01491 01492 // 01493 // We found a large enough run of set bits so now clear them 01494 // 01495 01496 RtlClearBits( BitMapHeader, StartingIndex, NumberToFind ); 01497 } 01498 01499 // 01500 // And return to our caller 01501 // 01502 01503 return StartingIndex; 01504 }

VOID RtlInitializeBitMap IN PRTL_BITMAP  BitMapHeader,
IN PULONG  BitMapBuffer,
IN ULONG  SizeOfBitMap
 

Definition at line 219 of file rtl/bitmap.c.

References BitMapHeader, and RTL_PAGED_CODE.

Referenced by DoBitMapTest(), HvInitializeHive(), HvpAddBin(), HvpBuildMapAndCopy(), HvpInitMap(), HvpRecoverData(), LdrpInitializeProcess(), main(), NtAllocateUserPhysicalPages(), NtAllocateVirtualMemory(), SetHandleFlag(), and UserDeleteW32Process().

00227 : 00228 00229 This procedure initializes a bit map. 00230 00231 Arguments: 00232 00233 BitMapHeader - Supplies a pointer to the BitMap Header to initialize 00234 00235 BitMapBuffer - Supplies a pointer to the buffer that is to serve as the 00236 BitMap. This must be an a multiple number of longwords in size. 00237 00238 SizeOfBitMap - Supplies the number of bits required in the Bit Map. 00239 00240 Return Value: 00241 00242 None. 00243 00244 --*/ 00245 00246 { 00247 RTL_PAGED_CODE(); 00248 00249 // 00250 // Initialize the BitMap header. 00251 // 00252 00253 BitMapHeader->SizeOfBitMap = SizeOfBitMap; 00254 BitMapHeader->Buffer = BitMapBuffer; 00255 00256 // 00257 // And return to our caller 00258 // 00259 00260 //DbgPrint("InitializeBitMap"); DumpBitMap(BitMapHeader); 00261 return; 00262 }

ULONG RtlNumberOfClearBits IN PRTL_BITMAP  BitMapHeader  ) 
 

Definition at line 2149 of file rtl/bitmap.c.

References BitMapHeader, GET_BYTE, GET_BYTE_DECLARATIONS, GET_BYTE_INITIALIZATION, RtlpBitsClearTotal, and ZeroMask.

Referenced by main().

02155 : 02156 02157 This procedure counts and returns the number of clears bits within 02158 the specified bitmap. 02159 02160 Arguments: 02161 02162 BitMapHeader - Supplies a pointer to the previously initialized bitmap. 02163 02164 Return Value: 02165 02166 ULONG - The total number of clear bits in the bitmap 02167 02168 --*/ 02169 02170 { 02171 ULONG SizeOfBitMap; 02172 ULONG SizeInBytes; 02173 02174 ULONG i; 02175 UCHAR CurrentByte; 02176 02177 ULONG TotalClear; 02178 02179 GET_BYTE_DECLARATIONS(); 02180 02181 // 02182 // Reference the bitmap header to make the loop run faster 02183 // 02184 02185 SizeOfBitMap = BitMapHeader->SizeOfBitMap; 02186 SizeInBytes = (SizeOfBitMap + 7) / 8; 02187 02188 // 02189 // Set any unused bits in the last byte so we don't count them. We 02190 // do this by first checking if there are any odd bits in the last byte 02191 // 02192 02193 if ((SizeOfBitMap % 8) != 0) { 02194 02195 // 02196 // The last byte has some odd bits so we'll set the high unused 02197 // bits in the last byte to 1's 02198 // 02199 02200 ((PUCHAR)BitMapHeader->Buffer)[SizeInBytes - 1] |= 02201 ZeroMask[SizeOfBitMap % 8]; 02202 } 02203 02204 // 02205 // Set if up so we can use the GET_BYTE macro 02206 // 02207 02208 GET_BYTE_INITIALIZATION( BitMapHeader, 0 ); 02209 02210 // 02211 // Examine every byte in the bitmap 02212 // 02213 02214 TotalClear = 0; 02215 for (i = 0; i < SizeInBytes; i += 1) { 02216 02217 GET_BYTE( CurrentByte ); 02218 02219 TotalClear += RtlpBitsClearTotal[CurrentByte]; 02220 } 02221 02222 return TotalClear; 02223 }

ULONG RtlNumberOfSetBits IN PRTL_BITMAP  BitMapHeader  ) 
 

Definition at line 2227 of file rtl/bitmap.c.

References BitMapHeader, FillMask, GET_BYTE, GET_BYTE_DECLARATIONS, GET_BYTE_INITIALIZATION, and RtlpBitsSetTotal.

Referenced by CmpInitializeHiveList(), HvFreeHivePartial(), HvMarkCellDirty(), HvMarkClean(), HvMarkDirty(), HvpAddBin(), HvpDoWriteHive(), HvpGrowLog1(), HvpGrowLog2(), HvpRecoverData(), HvpWriteLog(), IopCreateSummaryDump(), IopWriteSummaryDump(), and main().

02233 : 02234 02235 This procedure counts and returns the number of set bits within 02236 the specified bitmap. 02237 02238 Arguments: 02239 02240 BitMapHeader - Supplies a pointer to the previously initialized bitmap. 02241 02242 Return Value: 02243 02244 ULONG - The total number of set bits in the bitmap 02245 02246 --*/ 02247 02248 { 02249 ULONG SizeOfBitMap; 02250 ULONG SizeInBytes; 02251 02252 ULONG i; 02253 UCHAR CurrentByte; 02254 02255 ULONG TotalSet; 02256 02257 GET_BYTE_DECLARATIONS(); 02258 02259 // 02260 // Reference the bitmap header to make the loop run faster 02261 // 02262 02263 SizeOfBitMap = BitMapHeader->SizeOfBitMap; 02264 SizeInBytes = (SizeOfBitMap + 7) / 8; 02265 02266 // 02267 // Clear any unused bits in the last byte so we don't count them. We 02268 // do this by first checking if there are any odd bits in the last byte 02269 // 02270 02271 if ((SizeOfBitMap % 8) != 0) { 02272 02273 // 02274 // The last byte has some odd bits so we'll set the high unused 02275 // bits in the last byte to 0's 02276 // 02277 02278 ((PUCHAR)BitMapHeader->Buffer)[SizeInBytes - 1] &= 02279 FillMask[SizeOfBitMap % 8]; 02280 } 02281 02282 // 02283 // Set if up so we can use the GET_BYTE macro 02284 // 02285 02286 GET_BYTE_INITIALIZATION( BitMapHeader, 0 ); 02287 02288 // 02289 // Examine every byte in the bitmap 02290 // 02291 02292 TotalSet = 0; 02293 for (i = 0; i < SizeInBytes; i += 1) { 02294 02295 GET_BYTE( CurrentByte ); 02296 02297 TotalSet += RtlpBitsSetTotal(CurrentByte); 02298 } 02299 02300 return TotalSet; 02301 }

VOID RtlSetAllBits IN PRTL_BITMAP  BitMapHeader  ) 
 

Definition at line 305 of file rtl/bitmap.c.

References BitMapHeader.

Referenced by DoBitMapTest(), HvInitializeHive(), HvWriteHive(), main(), MiBuildPagedPool(), MiExtendPagingFileMaximum(), MiInitializeSessionPool(), and NtCreatePagingFile().

00311 : 00312 00313 This procedure sets all bits in the specified Bit Map. 00314 00315 Arguments: 00316 00317 BitMapHeader - Supplies a pointer to the previously initialized BitMap 00318 00319 Return Value: 00320 00321 None. 00322 00323 --*/ 00324 00325 { 00326 // 00327 // Set all the bits 00328 // 00329 00330 RtlFillMemoryUlong( BitMapHeader->Buffer, 00331 ((BitMapHeader->SizeOfBitMap + 31) / 32) * 4, 00332 0xffffffff 00333 ); 00334 00335 // 00336 // And return to our caller 00337 // 00338 00339 //DbgPrint("SetAllBits"); DumpBitMap(BitMapHeader); 00340 return; 00341 }

VOID RtlSetBits IN PRTL_BITMAP  BitMapHeader,
IN ULONG  StartingIndex,
IN ULONG  NumberToSet
 

Definition at line 1634 of file rtl/bitmap.c.

References ASSERT, BitMapHeader, LeftShiftUlong, and RightShiftUlong.

Referenced by CmpInitializeHiveList(), DoBitMapTest(), HvMarkDirty(), IopAddPageToPageMap(), main(), MiAllocatePoolPages(), MiAttemptPageFileReduction(), MiCheckForCrashDump(), NtAllocateUserPhysicalPages(), RtlFindClearBitsAndSet(), and SetHandleFlag().

01642 : 01643 01644 This procedure sets the specified range of bits within the 01645 specified bit map. 01646 01647 Arguments: 01648 01649 BitMapHeader - Supplies a pointer to the previously initialied BitMap. 01650 01651 StartingIndex - Supplies the index (zero based) of the first bit to set. 01652 01653 NumberToSet - Supplies the number of bits to set. 01654 01655 Return Value: 01656 01657 None. 01658 01659 --*/ 01660 { 01661 ULONG BitOffset; 01662 PULONG CurrentLong; 01663 01664 //DbgPrint("SetBits %08lx, ", NumberToSet); 01665 //DbgPrint("%08lx", StartingIndex); 01666 01667 ASSERT( StartingIndex + NumberToSet <= BitMapHeader->SizeOfBitMap ); 01668 01669 // 01670 // Special case the situation where the number of bits to set is 01671 // zero. Turn this into a noop. 01672 // 01673 01674 if (NumberToSet == 0) { 01675 01676 return; 01677 } 01678 01679 BitOffset = StartingIndex % 32; 01680 01681 // 01682 // Get a pointer to the first longword that needs to be set 01683 // 01684 01685 CurrentLong = &BitMapHeader->Buffer[ StartingIndex / 32 ]; 01686 01687 // 01688 // Check if we can only need to set one longword. 01689 // 01690 01691 if ((BitOffset + NumberToSet) <= 32) { 01692 01693 // 01694 // To build a mask of bits to set we shift left to get the number 01695 // of bits we're setting and then shift right to put it in position. 01696 // We'll typecast the right shift to ULONG to make sure it doesn't 01697 // do a sign extend. 01698 // 01699 01700 *CurrentLong |= LeftShiftUlong(RightShiftUlong(((ULONG)0xFFFFFFFF),(32 - NumberToSet)), 01701 BitOffset); 01702 01703 // 01704 // And return to our caller 01705 // 01706 01707 //DumpBitMap(BitMapHeader); 01708 01709 return; 01710 } 01711 01712 // 01713 // We can set bits out to the end of the first longword so we'll 01714 // do that right now. 01715 // 01716 01717 *CurrentLong |= LeftShiftUlong(0xFFFFFFFF, BitOffset); 01718 01719 // 01720 // And indicate what the next longword to set is and how many 01721 // bits are left to set 01722 // 01723 01724 CurrentLong += 1; 01725 NumberToSet -= 32 - BitOffset; 01726 01727 // 01728 // The bit position is now long aligned, so we can continue 01729 // setting longwords until the number to set is less than 32 01730 // 01731 01732 while (NumberToSet >= 32) { 01733 01734 *CurrentLong = 0xffffffff; 01735 CurrentLong += 1; 01736 NumberToSet -= 32; 01737 } 01738 01739 // 01740 // And now we can set the remaining bits, if there are any, in the 01741 // last longword 01742 // 01743 01744 if (NumberToSet > 0) { 01745 01746 *CurrentLong |= ~LeftShiftUlong(0xFFFFFFFF, NumberToSet); 01747 } 01748 01749 // 01750 // And return to our caller 01751 // 01752 01753 //DumpBitMap(BitMapHeader); 01754 01755 return; 01756 }


Variable Documentation

CONST UCHAR FillMask[] = { 0x00, 0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x7F, 0xFF } [static]
 

Definition at line 213 of file rtl/bitmap.c.

Referenced by RtlAreBitsClear(), RtlAreBitsSet(), RtlFindClearBits(), RtlFindClearRuns(), RtlFindSetBits(), and RtlNumberOfSetBits().

CONST ULONG FillMaskUlong[] [static]
 

Initial value:

{ 0x00000000, 0x00000001, 0x00000003, 0x00000007, 0x0000000f, 0x0000001f, 0x0000003f, 0x0000007f, 0x000000ff, 0x000001ff, 0x000003ff, 0x000007ff, 0x00000fff, 0x00001fff, 0x00003fff, 0x00007fff, 0x0000ffff, 0x0001ffff, 0x0003ffff, 0x0007ffff, 0x000fffff, 0x001fffff, 0x003fffff, 0x007fffff, 0x00ffffff, 0x01ffffff, 0x03ffffff, 0x07ffffff, 0x0fffffff, 0x1fffffff, 0x3fffffff, 0x7fffffff, 0xffffffff }

Definition at line 2621 of file rtl/bitmap.c.

Referenced by RtlFindLastBackwardRunClear(), and RtlFindNextForwardRunClear().

CONST CCHAR RtlpBitsClearAnywhere[]
 

Initial value:

{ 8,7,6,6,5,5,5,5,4,4,4,4,4,4,4,4, 4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, 5,4,3,3,2,2,2,2,3,2,2,2,2,2,2,2, 4,3,2,2,2,2,2,2,3,2,2,2,2,2,2,2, 6,5,4,4,3,3,3,3,3,2,2,2,2,2,2,2, 4,3,2,2,2,1,1,1,3,2,1,1,2,1,1,1, 5,4,3,3,2,2,2,2,3,2,1,1,2,1,1,1, 4,3,2,2,2,1,1,1,3,2,1,1,2,1,1,1, 7,6,5,5,4,4,4,4,3,3,3,3,3,3,3,3, 4,3,2,2,2,2,2,2,3,2,2,2,2,2,2,2, 5,4,3,3,2,2,2,2,3,2,1,1,2,1,1,1, 4,3,2,2,2,1,1,1,3,2,1,1,2,1,1,1, 6,5,4,4,3,3,3,3,3,2,2,2,2,2,2,2, 4,3,2,2,2,1,1,1,3,2,1,1,2,1,1,1, 5,4,3,3,2,2,2,2,3,2,1,1,2,1,1,1, 4,3,2,2,2,1,1,1,3,2,1,1,2,1,1,0 }

Definition at line 122 of file rtl/bitmap.c.

Referenced by RtlFindClearBits(), and RtlFindClearRuns().

CONST CCHAR RtlpBitsClearHigh[]
 

Initial value:

{ 8,7,6,6,5,5,5,5,4,4,4,4,4,4,4,4, 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }

Definition at line 168 of file rtl/bitmap.c.

Referenced by RtlFindClearBits(), RtlFindClearRuns(), and RtlFindMostSignificantBit().

CONST CCHAR RtlpBitsClearLow[]
 

Initial value:

{ 8,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0, 4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0, 5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0, 4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0, 6,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0, 4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0, 5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0, 4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0, 7,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0, 4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0, 5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0, 4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0, 6,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0, 4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0, 5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0, 4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0 }

Definition at line 145 of file rtl/bitmap.c.

Referenced by RtlFindClearBits(), RtlFindClearRuns(), and RtlFindLeastSignificantBit().

CONST CCHAR RtlpBitsClearTotal[]
 

Initial value:

{ 8,7,7,6,7,6,6,5,7,6,6,5,6,5,5,4, 7,6,6,5,6,5,5,4,6,5,5,4,5,4,4,3, 7,6,6,5,6,5,5,4,6,5,5,4,5,4,4,3, 6,5,5,4,5,4,4,3,5,4,4,3,4,3,3,2, 7,6,6,5,6,5,5,4,6,5,5,4,5,4,4,3, 6,5,5,4,5,4,4,3,5,4,4,3,4,3,3,2, 6,5,5,4,5,4,4,3,5,4,4,3,4,3,3,2, 5,4,4,3,4,3,3,2,4,3,3,2,3,2,2,1, 7,6,6,5,6,5,5,4,6,5,5,4,5,4,4,3, 6,5,5,4,5,4,4,3,5,4,4,3,4,3,3,2, 6,5,5,4,5,4,4,3,5,4,4,3,4,3,3,2, 5,4,4,3,4,3,3,2,4,3,3,2,3,2,2,1, 6,5,5,4,5,4,4,3,5,4,4,3,4,3,3,2, 5,4,4,3,4,3,3,2,4,3,3,2,3,2,2,1, 5,4,4,3,4,3,3,2,4,3,3,2,3,2,2,1, 4,3,3,2,3,2,2,1,3,2,2,1,2,1,1,0 }

Definition at line 190 of file rtl/bitmap.c.

Referenced by RtlNumberOfClearBits().

CONST UCHAR ZeroMask[] = { 0xFF, 0xFE, 0xFC, 0xF8, 0xf0, 0xe0, 0xc0, 0x80, 0x00 } [static]
 

Definition at line 215 of file rtl/bitmap.c.

Referenced by RtlAreBitsClear(), RtlAreBitsSet(), RtlFindClearBits(), RtlFindClearRuns(), RtlFindSetBits(), and RtlNumberOfClearBits().


Generated on Sat May 15 19:42:57 2004 for test by doxygen 1.3.7