What about bsr and bsl?

On 2009-12-07, at 8:02 PM, [email protected] wrote:

> Author: tkreuzer
> Date: Tue Dec  8 02:02:36 2009
> New Revision: 44464
> 
> URL: http://svn.reactos.org/svn/reactos?rev=44464&view=rev
> Log:
> [RTL]
> Rewrite the rtl bitmap implementation.
> The old one was a little .... suboptimal. The new one should outperform the 
> old one by several orders of magnitude, especially RtlFindClearBits that was 
> literally searching bit by bit.
> 
> Modified:
>    trunk/reactos/lib/rtl/bitmap.c
>    trunk/reactos/tools/mkhive/mkhive.h
>    trunk/reactos/tools/mkhive/rtl.c
> 
> Modified: trunk/reactos/lib/rtl/bitmap.c
> URL: 
> http://svn.reactos.org/svn/reactos/trunk/reactos/lib/rtl/bitmap.c?rev=44464&r1=44463&r2=44464&view=diff
> ==============================================================================
> --- trunk/reactos/lib/rtl/bitmap.c [iso-8859-1] (original)
> +++ trunk/reactos/lib/rtl/bitmap.c [iso-8859-1] Tue Dec  8 02:02:36 2009
> @@ -1,8 +1,9 @@
> -/* COPYRIGHT:       See COPYING in the top level directory
> +/*
> + * COPYRIGHT:       See COPYING in the top level directory
>  * PROJECT:         ReactOS system libraries
>  * FILE:            lib/rtl/bitmap.c
>  * PURPOSE:         Bitmap functions
> - * PROGRAMMER:      Eric Kohl
> + * PROGRAMMER:      Timo Kreuzer ([email protected])
>  */
> 
> /* INCLUDES *****************************************************************/
> @@ -12,965 +13,749 @@
> #define NDEBUG
> #include <debug.h>
> 
> -/* MACROS 
> *******************************************************************/
> -
> -/* Bits set from LSB to MSB; used as mask for runs < 8 bits */
> -static const BYTE NTDLL_maskBits[8] = { 0, 1, 3, 7, 15, 31, 63, 127 };
> -
> -/* Number of set bits for each value of a nibble; used for counting */
> -static const BYTE NTDLL_nibbleBitCount[16] = {
> -  0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4
> +
> +/* DATA 
> *********************************************************************/
> +
> +/* Number of set bits per byte value */
> +static const
> +UCHAR
> +BitCountTable[256] =
> +{
> +    /* x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE xF */
> +       0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, /* 0x */
> +       1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, /* 1x */
> +       1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, /* 2x */
> +       2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, /* 3x */
> +       1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, /* 4x */
> +       2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, /* 5x */
> +       2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, /* 6c */
> +       3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, /* 7x */
> +       1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, /* 8x */
> +       2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, /* 9x */
> +       2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, /* Ax */
> +       3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, /* Bx */
> +       2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, /* Cx */
> +       3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, /* Dx */
> +       3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, /* Ex */
> +       4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8  /* Fx */
> };
> 
> -/* First set bit in a nibble; used for determining least significant bit */
> -static const BYTE NTDLL_leastSignificant[16] = {
> -  0, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0
> -};
> -
> -/* Last set bit in a nibble; used for determining most significant bit */
> -static const signed char NTDLL_mostSignificant[16] = {
> -  -1, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3
> -};
> -
> -/* PRIVATE FUNCTIONS 
> *********************************************************/
> -
> -static
> -int
> -__cdecl
> -NTDLL_RunSortFn(const void *lhs,
> -                const void *rhs)
> -{
> -  if (((const RTL_BITMAP_RUN*)lhs)->NumberOfBits > ((const 
> RTL_BITMAP_RUN*)rhs)->NumberOfBits)
> +
> +/* PRIVATE FUNCTIONS 
> ********************************************************/
> +
> +static __inline__
> +ULONG
> +RtlpGetLengthOfRunClear(
> +    IN PRTL_BITMAP BitMapHeader,
> +    IN ULONG StartingIndex,
> +    IN ULONG MaxLength)
> +{
> +    ULONG Value, BitPos, Length;
> +    PULONG Buffer, MaxBuffer;
> +
> +    /* Calculate positions */
> +    Buffer = BitMapHeader->Buffer + StartingIndex / 32;
> +    BitPos = StartingIndex & 31;
> +
> +    /* Calculate the maximum length */
> +    MaxLength = min(MaxLength, BitMapHeader->SizeOfBitMap - StartingIndex);
> +    MaxBuffer = Buffer + (BitPos + MaxLength + 31) / 32;
> +
> +    /* Clear the bits that don't belong to this run */
> +    Value = *Buffer++ >> BitPos << BitPos;
> +
> +    /* Skip all clear ULONGs */
> +    while (Value == 0 && Buffer < MaxBuffer)
> +    {
> +        Value = *Buffer++;
> +    }
> +
> +    /* Did we reach the end? */
> +    if (Value == 0)
> +    {
> +        /* Return maximum length */
> +        return MaxLength;
> +    }
> +
> +    /* We hit a set bit, check how many clear bits are left */
> +    BitScanForward(&BitPos, Value);
> +
> +    /* Calculate length up to where we read */
> +    Length = (Buffer - BitMapHeader->Buffer) * 32 - StartingIndex;
> +    Length += BitPos - 32;
> +    
> +    if (Length > BitMapHeader->SizeOfBitMap - StartingIndex)
> +        Length = BitMapHeader->SizeOfBitMap - StartingIndex;
> +
> +    /* The result is guaranteed to be < BitMapHeader->SizeOfBitMap */
> +    return Length;
> +}
> +
> +static __inline__
> +ULONG
> +RtlpGetLengthOfRunSet(
> +    IN PRTL_BITMAP BitMapHeader,
> +    IN ULONG StartingIndex,
> +    IN ULONG MaxLength)
> +{
> +    ULONG InvValue, BitPos, Length;
> +    PULONG Buffer, MaxBuffer;
> +
> +    /* Calculate positions */
> +    Buffer = BitMapHeader->Buffer + StartingIndex / 32;
> +    BitPos = StartingIndex & 31;
> +
> +    /* Calculate the maximum length */
> +    MaxLength = min(MaxLength, BitMapHeader->SizeOfBitMap - StartingIndex);
> +    MaxBuffer = Buffer + (BitPos + MaxLength + 31) / 32;
> +
> +    /* Get the inversed value, clear bits that don't belong to the run */
> +    InvValue = ~(*Buffer++) >> BitPos << BitPos;
> +
> +    /* Skip all set ULONGs */
> +    while (InvValue == 0 && Buffer < MaxBuffer)
> +    {
> +        InvValue = ~(*Buffer++);
> +    }
> +
> +    /* Did we reach the end? */
> +    if (InvValue == 0)
> +    {
> +        /* Yes, return maximum */
> +        return MaxLength;
> +    }
> +
> +    /* We hit a clear bit, check how many set bits are left */
> +    BitScanForward(&BitPos, InvValue);
> +
> +    /* Calculate length up to where we read */
> +    Length = (Buffer - BitMapHeader->Buffer) * 32 - StartingIndex;
> +    Length += BitPos - 32;
> +
> +    if (Length > BitMapHeader->SizeOfBitMap - StartingIndex)
> +        Length = BitMapHeader->SizeOfBitMap - StartingIndex;
> +
> +    /* The result is guaranteed to be < BitMapHeader->SizeOfBitMap */
> +    return Length;
> +}
> +
> +
> +/* PUBLIC FUNCTIONS 
> **********************************************************/
> +
> +CCHAR
> +NTAPI
> +RtlFindMostSignificantBit(ULONGLONG Value)
> +{
> +    ULONG Position;
> +
> +    if (BitScanReverse(&Position, Value >> 32))
> +    {
> +        return Position + 32;
> +    }
> +    else if (BitScanReverse(&Position, (ULONG)Value))
> +    {
> +        return Position;
> +    }
> +
>     return -1;
> -  return 1;
> -}
> -
> -static
> -ULONG
> -WINAPI
> -NTDLL_FindRuns(PRTL_BITMAP lpBits,
> -               PRTL_BITMAP_RUN lpSeries,
> -               ULONG ulCount,
> -               BOOLEAN bLongest,
> -               ULONG (*fn)(PRTL_BITMAP,ULONG,PULONG))
> -{
> -  BOOL bNeedSort = ulCount > 1 ? TRUE : FALSE;
> -  ULONG ulPos = 0, ulRuns = 0;
> -
> -  if (!ulCount)
> -    return MAXULONG;
> -
> -  while (ulPos < lpBits->SizeOfBitMap)
> -  {
> -    /* Find next set/clear run */
> -    ULONG ulSize, ulNextPos = fn(lpBits, ulPos, &ulSize);
> -
> -    if (ulNextPos == MAXULONG)
> -      break;
> -
> -    if (bLongest && ulRuns == ulCount)
> -    {
> -      /* Sort runs with shortest at end, if they are out of order */
> -      if (bNeedSort)
> -        qsort(lpSeries, ulRuns, sizeof(RTL_BITMAP_RUN), NTDLL_RunSortFn);
> -
> -      /* Replace last run if this one is bigger */
> -      if (ulSize > lpSeries[ulRuns - 1].NumberOfBits)
> -      {
> -        lpSeries[ulRuns - 1].StartingIndex = ulNextPos;
> -        lpSeries[ulRuns - 1].NumberOfBits = ulSize;
> -
> -        /* We need to re-sort the array, _if_ we didn't leave it sorted */
> -        if (ulRuns > 1 && ulSize > lpSeries[ulRuns - 2].NumberOfBits)
> -          bNeedSort = TRUE;
> -      }
> -    }
> -    else
> -    {
> -      /* Append to found runs */
> -      lpSeries[ulRuns].StartingIndex = ulNextPos;
> -      lpSeries[ulRuns].NumberOfBits = ulSize;
> -      ulRuns++;
> -
> -      if (!bLongest && ulRuns == ulCount)
> -        break;
> -    }
> -    ulPos = ulNextPos + ulSize;
> -  }
> -  return ulRuns;
> -}
> -
> -static
> -ULONG
> -NTDLL_FindSetRun(PRTL_BITMAP lpBits,
> -                 ULONG ulStart,
> -                 PULONG lpSize)
> -{
> -  LPBYTE lpOut;
> -  ULONG ulFoundAt = 0, ulCount = 0;
> -
> -  /* FIXME: It might be more efficient/cleaner to manipulate four bytes
> -   * at a time. But beware of the pointer arithmetics...
> -   */
> -  lpOut = ((BYTE*)lpBits->Buffer) + (ulStart >> 3u);
> -
> -  while (1)
> -  {
> -    /* Check bits in first byte */
> -    const BYTE bMask = (0xff << (ulStart & 7)) & 0xff;
> -    const BYTE bFirst = *lpOut & bMask;
> -
> -    if (bFirst)
> -    {
> -      /* Have a set bit in first byte */
> -      if (bFirst != bMask)
> -      {
> -        /* Not every bit is set */
> -        ULONG ulOffset;
> -
> -        if (bFirst & 0x0f)
> -          ulOffset = NTDLL_leastSignificant[bFirst & 0x0f];
> -        else
> -          ulOffset = 4 + NTDLL_leastSignificant[bFirst >> 4];
> -        ulStart += ulOffset;
> -        ulFoundAt = ulStart;
> -        for (;ulOffset < 8; ulOffset++)
> -        {
> -          if (!(bFirst & (1 << ulOffset)))
> -          {
> -            *lpSize = ulCount;
> -            return ulFoundAt; /* Set from start, but not until the end */
> -          }
> -          ulCount++;
> -          ulStart++;
> -        }
> -        /* Set to the end - go on to count further bits */
> -        lpOut++;
> -        break;
> -      }
> -      /* every bit from start until the end of the byte is set */
> -      ulFoundAt = ulStart;
> -      ulCount = 8 - (ulStart & 7);
> -      ulStart = (ulStart & ~7u) + 8;
> -      lpOut++;
> -      break;
> -    }
> -    ulStart = (ulStart & ~7u) + 8;
> -    lpOut++;
> -    if (ulStart >= lpBits->SizeOfBitMap)
> -      return MAXULONG;
> -  }
> -
> -  /* Count blocks of 8 set bits */
> -  while (*lpOut == 0xff)
> -  {
> -    ulCount += 8;
> -    ulStart += 8;
> -    if (ulStart >= lpBits->SizeOfBitMap)
> -    {
> -      *lpSize = ulCount - (ulStart - lpBits->SizeOfBitMap);
> -      return ulFoundAt;
> -    }
> -    lpOut++;
> -  }
> -
> -  /* Count remaining contiguous bits, if any */
> -  if (*lpOut & 1)
> -  {
> -    ULONG ulOffset = 0;
> -
> -    for (;ulOffset < 7u; ulOffset++)
> -    {
> -      if (!(*lpOut & (1 << ulOffset)))
> -        break;
> -      ulCount++;
> -    }
> -  }
> -  *lpSize = ulCount;
> -  return ulFoundAt;
> -}
> -
> -static
> -ULONG
> -NTDLL_FindClearRun(PRTL_BITMAP lpBits,
> -                   ULONG ulStart,
> -                   PULONG lpSize)
> -{
> -  LPBYTE lpOut;
> -  ULONG ulFoundAt = 0, ulCount = 0;
> -
> -  /* FIXME: It might be more efficient/cleaner to manipulate four bytes
> -   * at a time. But beware of the pointer arithmetics...
> -   */
> -  lpOut = ((BYTE*)lpBits->Buffer) + (ulStart >> 3u);
> -
> -  while (1)
> -  {
> -    /* Check bits in first byte */
> -    const BYTE bMask = (0xff << (ulStart & 7)) & 0xff;
> -    const BYTE bFirst = (~*lpOut) & bMask;
> -
> -    if (bFirst)
> -    {
> -      /* Have a clear bit in first byte */
> -      if (bFirst != bMask)
> -      {
> -        /* Not every bit is clear */
> -        ULONG ulOffset;
> -
> -        if (bFirst & 0x0f)
> -          ulOffset = NTDLL_leastSignificant[bFirst & 0x0f];
> -        else
> -          ulOffset = 4 + NTDLL_leastSignificant[bFirst >> 4];
> -        ulStart += ulOffset;
> -        ulFoundAt = ulStart;
> -        for (;ulOffset < 8; ulOffset++)
> -        {
> -          if (!(bFirst & (1 << ulOffset)))
> -          {
> -            *lpSize = ulCount;
> -            return ulFoundAt; /* Clear from start, but not until the end */
> -          }
> -          ulCount++;
> -          ulStart++;
> -        }
> -        /* Clear to the end - go on to count further bits */
> -        lpOut++;
> -        break;
> -      }
> -      /* Every bit from start until the end of the byte is clear */
> -      ulFoundAt = ulStart;
> -      ulCount = 8 - (ulStart & 7);
> -      ulStart = (ulStart & ~7u) + 8;
> -      lpOut++;
> -      break;
> -    }
> -    ulStart = (ulStart & ~7u) + 8;
> -    lpOut++;
> -    if (ulStart >= lpBits->SizeOfBitMap)
> -      return MAXULONG;
> -  }
> -
> -  /* Count blocks of 8 clear bits */
> -  while (!*lpOut)
> -  {
> -    ulCount += 8;
> -    ulStart += 8;
> -    if (ulStart >= lpBits->SizeOfBitMap)
> -    {
> -      *lpSize = ulCount - (ulStart - lpBits->SizeOfBitMap);
> -      return ulFoundAt;
> -    }
> -    lpOut++;
> -  }
> -
> -  /* Count remaining contiguous bits, if any */
> -  if (!(*lpOut & 1))
> -  {
> -    ULONG ulOffset = 0;
> -
> -    for (;ulOffset < 7u; ulOffset++)
> -    {
> -      if (*lpOut & (1 << ulOffset))
> -        break;
> -      ulCount++;
> -    }
> -  }
> -  *lpSize = ulCount;
> -  return ulFoundAt;
> -}
> -
> -/* FUNCTIONS 
> ****************************************************************/
> -
> -/*
> - * @implemented
> - */
> +}
> +
> +CCHAR
> +NTAPI
> +RtlFindLeastSignificantBit(ULONGLONG Value)
> +{
> +    ULONG Position;
> +
> +    if (BitScanForward(&Position, (ULONG)Value))
> +    {
> +        return Position;
> +    }
> +    else if (BitScanForward(&Position, Value >> 32))
> +    {
> +        return Position + 32;
> +    }
> +
> +    return -1;
> +}
> +
> VOID
> NTAPI
> -RtlInitializeBitMap(IN PRTL_BITMAP BitMapHeader,
> -                    IN PULONG BitMapBuffer,
> -                    IN ULONG SizeOfBitMap)
> -{
> +RtlInitializeBitMap(
> +    IN PRTL_BITMAP BitMapHeader,
> +    IN PULONG BitMapBuffer,
> +    IN ULONG SizeOfBitMap)
> +{
> +    // FIXME: some bugger here!
> +    //ASSERT(SizeOfBitMap > 0);
> +
>     /* Setup the bitmap header */
>     BitMapHeader->SizeOfBitMap = SizeOfBitMap;
>     BitMapHeader->Buffer = BitMapBuffer;
> }
> 
> -/*
> - * @implemented
> - */
> +VOID
> +NTAPI
> +RtlClearAllBits(
> +    IN OUT PRTL_BITMAP BitMapHeader)
> +{
> +    ULONG LengthInUlongs;
> +
> +    LengthInUlongs = (BitMapHeader->SizeOfBitMap + 31) >> 5;
> +    RtlFillMemoryUlong(BitMapHeader->Buffer, LengthInUlongs << 2, 0);
> +}
> +
> +VOID
> +NTAPI
> +RtlSetAllBits(
> +    IN OUT PRTL_BITMAP BitMapHeader)
> +{
> +    ULONG LengthInUlongs;
> +    
> +    LengthInUlongs = (BitMapHeader->SizeOfBitMap + 31) >> 5;
> +    RtlFillMemoryUlong(BitMapHeader->Buffer, LengthInUlongs << 2, ~0);
> +}
> +
> +VOID
> +NTAPI
> +RtlClearBit(
> +    IN PRTL_BITMAP BitMapHeader,
> +    IN ULONG BitNumber)
> +{
> +    ASSERT(BitNumber <= BitMapHeader->SizeOfBitMap);
> +    BitMapHeader->Buffer[BitNumber >> 5] &= ~(1 << (BitNumber & 31));
> +}
> +
> +VOID
> +NTAPI
> +RtlSetBit(
> +    IN PRTL_BITMAP BitMapHeader,
> +    IN ULONG BitNumber)
> +{
> +    ASSERT(BitNumber <= BitMapHeader->SizeOfBitMap);
> +    BitMapHeader->Buffer[BitNumber >> 5] |= (1 << (BitNumber & 31));
> +}
> +
> +VOID
> +NTAPI
> +RtlClearBits(
> +    IN PRTL_BITMAP BitMapHeader,
> +    IN ULONG StartingIndex,
> +    IN ULONG NumberToClear)
> +{
> +    ULONG Bits, Mask;
> +    PULONG Buffer;
> +
> +    ASSERT(StartingIndex + NumberToClear <= BitMapHeader->SizeOfBitMap);
> +
> +    /* Calculate buffer start and first bit index */
> +    Buffer = &BitMapHeader->Buffer[StartingIndex >> 5];
> +    Bits = StartingIndex & 31;
> +
> +    /* Are we unaligned? */
> +    if (Bits)
> +    {
> +        /* Create an inverse mask by shifting MAXULONG */
> +        Mask = MAXULONG << Bits;
> +
> +        /* This is what's left in the first ULONG */
> +        Bits = 32 - Bits;
> +
> +        /* Even less bits to clear? */
> +        if (NumberToClear < Bits)
> +        {
> +            /* Calculate how many bits are left */
> +            Bits -= NumberToClear;
> +
> +            /* Fixup the mask on the high side */
> +            Mask = Mask << Bits >> Bits;
> +
> +            /* Clear bits and return */
> +            *Buffer &= ~Mask;
> +            return;
> +        }
> +
> +        /* Clear bits */
> +        *Buffer &= ~Mask;
> +
> +        /* Update buffer and left bits */
> +        Buffer++;
> +        NumberToClear -= Bits;
> +    }
> +
> +    /* Clear all full ULONGs */
> +    RtlFillMemoryUlong(Buffer, NumberToClear >> 3, 0);
> +    Buffer += NumberToClear >> 5;
> +
> +    /* Clear what's left */
> +    NumberToClear &= 31;
> +    Mask = MAXULONG << NumberToClear;
> +    *Buffer &= Mask;
> +}
> +
> +VOID
> +NTAPI
> +RtlSetBits(
> +    IN PRTL_BITMAP BitMapHeader,
> +    IN ULONG StartingIndex,
> +    IN ULONG NumberToSet)
> +{
> +    ULONG Bits, Mask;
> +    PULONG Buffer;
> +
> +    ASSERT(StartingIndex + NumberToSet <= BitMapHeader->SizeOfBitMap);
> +
> +    /* Calculate buffer start and first bit index */
> +    Buffer = &BitMapHeader->Buffer[StartingIndex >> 5];
> +    Bits = StartingIndex & 31;
> +
> +    /* Are we unaligned? */
> +    if (Bits)
> +    {
> +        /* Create a mask by shifting MAXULONG */
> +        Mask = MAXULONG << Bits;
> +
> +        /* This is what's left in the first ULONG */
> +        Bits = 32 - Bits;
> +
> +        /* Even less bits to clear? */
> +        if (NumberToSet < Bits)
> +        {
> +            /* Calculate how many bits are left */
> +            Bits -= NumberToSet;
> +
> +            /* Fixup the mask on the high side */
> +            Mask = Mask << Bits >> Bits;
> +
> +            /* Set bits and return */
> +            *Buffer |= Mask;
> +            return;
> +        }
> +
> +        /* Set bits */
> +        *Buffer |= Mask;
> +
> +        /* Update buffer and left bits */
> +        Buffer++;
> +        NumberToSet -= Bits;
> +    }
> +
> +    /* Set all full ULONGs */
> +    RtlFillMemoryUlong(Buffer, NumberToSet >> 3, MAXULONG);
> +    Buffer += NumberToSet >> 5;
> +
> +    /* Set what's left */
> +    NumberToSet &= 31;
> +    Mask = MAXULONG << NumberToSet;
> +    *Buffer |= ~Mask;
> +}
> +
> BOOLEAN
> NTAPI
> -RtlAreBitsClear(IN PRTL_BITMAP BitMapHeader,
> -                IN ULONG StartingIndex,
> -                IN ULONG Length)
> -{
> -  LPBYTE lpOut;
> -  ULONG ulRemainder;
> -
> -  if (!BitMapHeader || !Length ||
> -      StartingIndex >= BitMapHeader->SizeOfBitMap ||
> -      Length > BitMapHeader->SizeOfBitMap - StartingIndex)
> -    return FALSE;
> -
> -  /* FIXME: It might be more efficient/cleaner to manipulate four bytes
> -   * at a time. But beware of the pointer arithmetics...
> -   */
> -  lpOut = ((BYTE*)BitMapHeader->Buffer) + (StartingIndex >> 3u);
> -
> -  /* Check bits in first byte, if StartingIndex isn't a byte boundary */
> -  if (StartingIndex & 7)
> -  {
> -    if (Length > 7)
> -    {
> -      /* Check from start bit to the end of the byte */
> -      if (*lpOut & ((0xff << (StartingIndex & 7)) & 0xff))
> -        return FALSE;
> -      lpOut++;
> -      Length -= (8 - (StartingIndex & 7));
> -    }
> -    else
> -    {
> -      /* Check from the start bit, possibly into the next byte also */
> -      USHORT initialWord = NTDLL_maskBits[Length] << (StartingIndex & 7);
> -
> -      if (*lpOut & (initialWord & 0xff))
> -        return FALSE;
> -      if ((initialWord & 0xff00) && (lpOut[1] & (initialWord >> 8)))
> -        return FALSE;
> -      return TRUE;
> -    }
> -  }
> -
> -  /* Check bits in blocks of 8 bytes */
> -  ulRemainder = Length & 7;
> -  Length >>= 3;
> -  while (Length--)
> -  {
> -    if (*lpOut++)
> -      return FALSE;
> -  }
> -
> -  /* Check remaining bits, if any */
> -  if (ulRemainder && *lpOut & NTDLL_maskBits[ulRemainder])
> -    return FALSE;
> -  return TRUE;
> -}
> -
> -
> -/*
> - * @implemented
> - */
> -BOOLEAN NTAPI
> -RtlAreBitsSet(PRTL_BITMAP BitMapHeader,
> -           ULONG StartingIndex,
> -           ULONG Length)
> -{
> -  LPBYTE lpOut;
> -  ULONG ulRemainder;
> -
> -
> -  if (!BitMapHeader || !Length ||
> -      StartingIndex >= BitMapHeader->SizeOfBitMap ||
> -      Length > BitMapHeader->SizeOfBitMap - StartingIndex)
> -    return FALSE;
> -
> -  /* FIXME: It might be more efficient/cleaner to manipulate four bytes
> -   * at a time. But beware of the pointer arithmetics...
> -   */
> -  lpOut = ((BYTE*)BitMapHeader->Buffer) + (StartingIndex >> 3u);
> -
> -  /* Check bits in first byte, if StartingIndex isn't a byte boundary */
> -  if (StartingIndex & 7)
> -  {
> -    if (Length > 7)
> -    {
> -      /* Check from start bit to the end of the byte */
> -      if ((*lpOut &
> -          ((0xff << (StartingIndex & 7))) & 0xff) != ((0xff << 
> (StartingIndex & 7) & 0xff)))
> -        return FALSE;
> -      lpOut++;
> -      Length -= (8 - (StartingIndex & 7));
> -    }
> -    else
> -    {
> -      /* Check from the start bit, possibly into the next byte also */
> -      USHORT initialWord = NTDLL_maskBits[Length] << (StartingIndex & 7);
> -
> -      if ((*lpOut & (initialWord & 0xff)) != (initialWord & 0xff))
> -        return FALSE;
> -      if ((initialWord & 0xff00) &&
> -          ((lpOut[1] & (initialWord >> 8)) != (initialWord >> 8)))
> -        return FALSE;
> -      return TRUE;
> -    }
> -  }
> -
> -  /* Check bits in blocks of 8 bytes */
> -  ulRemainder = Length & 7;
> -  Length >>= 3;
> -  while (Length--)
> -  {
> -    if (*lpOut++ != 0xff)
> -      return FALSE;
> -  }
> -
> -  /* Check remaining bits, if any */
> -  if (ulRemainder &&
> -      (*lpOut & NTDLL_maskBits[ulRemainder]) != NTDLL_maskBits[ulRemainder])
> -    return FALSE;
> -  return TRUE;
> -}
> -
> -
> -/*
> - * @implemented
> - */
> -VOID NTAPI
> -RtlClearAllBits(IN OUT PRTL_BITMAP BitMapHeader)
> -{
> -    memset(BitMapHeader->Buffer, 0, ((BitMapHeader->SizeOfBitMap + 31) & 
> ~31) >> 3);
> -}
> -
> -/*
> - * @implemented
> - */
> -VOID
> -NTAPI
> -RtlClearBit(PRTL_BITMAP BitMapHeader,
> -            ULONG BitNumber)
> -{
> -    PUCHAR Ptr;
> -
> -    if (BitNumber >= BitMapHeader->SizeOfBitMap) return;
> -
> -    Ptr = (PUCHAR)BitMapHeader->Buffer + (BitNumber / 8);
> -    *Ptr &= ~(1 << (BitNumber % 8));
> -}
> -
> -/*
> - * @implemented
> - */
> -VOID
> -NTAPI
> -RtlClearBits(IN PRTL_BITMAP BitMapHeader,
> -             IN ULONG StartingIndex,
> -             IN ULONG NumberToClear)
> -{
> -  LPBYTE lpOut;
> -
> -  if (!BitMapHeader || !NumberToClear ||
> -      StartingIndex >= BitMapHeader->SizeOfBitMap ||
> -      NumberToClear > BitMapHeader->SizeOfBitMap - StartingIndex)
> -    return;
> -
> -  /* FIXME: It might be more efficient/cleaner to manipulate four bytes
> -   * at a time. But beware of the pointer arithmetics...
> -   */
> -  lpOut = ((BYTE*)BitMapHeader->Buffer) + (StartingIndex >> 3u);
> -
> -  /* Clear bits in first byte, if StartingIndex isn't a byte boundary */
> -  if (StartingIndex & 7)
> -  {
> -    if (NumberToClear > 7)
> -    {
> -      /* Clear from start bit to the end of the byte */
> -      *lpOut++ &= ~(0xff << (StartingIndex & 7));
> -      NumberToClear -= (8 - (StartingIndex & 7));
> -    }
> -    else
> -    {
> -      /* Clear from the start bit, possibly into the next byte also */
> -      USHORT initialWord = ~(NTDLL_maskBits[NumberToClear] << (StartingIndex 
> & 7));
> -
> -      *lpOut++ &= (initialWord & 0xff);
> -      *lpOut &= (initialWord >> 8);
> -      return;
> -    }
> -  }
> -
> -  /* Clear bits (in blocks of 8) on whole byte boundaries */
> -  if (NumberToClear >> 3)
> -  {
> -    memset(lpOut, 0, NumberToClear >> 3);
> -    lpOut = lpOut + (NumberToClear >> 3);
> -  }
> -
> -  /* Clear remaining bits, if any */
> -  if (NumberToClear & 0x7)
> -    *lpOut &= ~NTDLL_maskBits[NumberToClear & 0x7];
> -}
> -
> -
> -/*
> - * @implemented
> - */
> -ULONG NTAPI
> -RtlFindClearBits(PRTL_BITMAP BitMapHeader,
> -              ULONG NumberToFind,
> -              ULONG HintIndex)
> -{
> -  ULONG ulPos, ulEnd;
> -
> -  if (!BitMapHeader || !NumberToFind || NumberToFind > 
> BitMapHeader->SizeOfBitMap)
> +RtlTestBit(
> +    IN PRTL_BITMAP BitMapHeader,
> +    IN ULONG BitNumber)
> +{
> +    ASSERT(BitNumber < BitMapHeader->SizeOfBitMap);
> +    return (BitMapHeader->Buffer[BitNumber >> 5] >> (BitNumber & 31)) & 1;
> +}
> +
> +BOOLEAN
> +NTAPI
> +RtlAreBitsClear(
> +    IN PRTL_BITMAP BitMapHeader,
> +    IN ULONG StartingIndex,
> +    IN ULONG Length)
> +{
> +    return RtlpGetLengthOfRunClear(BitMapHeader, StartingIndex, Length) >= 
> Length;
> +}
> +
> +BOOLEAN
> +NTAPI
> +RtlAreBitsSet(
> +    IN PRTL_BITMAP BitMapHeader,
> +    IN ULONG StartingIndex,
> +    IN ULONG Length)
> +{
> +    return RtlpGetLengthOfRunSet(BitMapHeader, StartingIndex, Length) >= 
> Length;
> +}
> +
> +ULONG
> +NTAPI
> +RtlNumberOfSetBits(
> +    IN PRTL_BITMAP BitMapHeader)
> +{
> +    PUCHAR Byte, MaxByte;
> +    ULONG BitCount = 0;
> +
> +    Byte = (PUCHAR)BitMapHeader->Buffer;
> +    MaxByte = Byte + (BitMapHeader->SizeOfBitMap + 7) / 8;
> +
> +    do
> +    {
> +        BitCount += BitCountTable[*Byte++];
> +    }
> +    while (Byte <= MaxByte);
> +
> +    return BitCount;
> +}
> +
> +ULONG
> +NTAPI
> +RtlNumberOfClearBits(
> +    IN PRTL_BITMAP BitMapHeader)
> +{
> +    /* Do some math */
> +    return BitMapHeader->SizeOfBitMap - RtlNumberOfSetBits(BitMapHeader);
> +}
> +
> +ULONG
> +NTAPI
> +RtlFindClearBits(
> +    IN PRTL_BITMAP BitMapHeader,
> +    IN ULONG NumberToFind,
> +    IN ULONG HintIndex)
> +{
> +    ULONG CurrentBit, CurrentLength;
> +
> +    /* Check for valid parameters */
> +    if (!BitMapHeader || NumberToFind > BitMapHeader->SizeOfBitMap)
> +    {
> +        return MAXULONG;
> +    }
> +
> +    /* Check for trivial case */
> +    if (NumberToFind == 0)
> +    {
> +        return HintIndex;
> +    }
> +
> +    /* Start with hint index, length is 0 */
> +    CurrentBit = HintIndex;
> +    CurrentLength = 0;
> +
> +    /* Loop until something is found or the end is reached */
> +    while (CurrentBit + NumberToFind < BitMapHeader->SizeOfBitMap)
> +    {
> +        ULONG test;
> +        /* Search for the next clear run, by skipping a set run */
> +        test = RtlpGetLengthOfRunSet(BitMapHeader,
> +                                            CurrentBit,
> +                                            MAXULONG);
> +        CurrentBit += test;
> +
> +        /* Get length of the clear bit run */
> +        CurrentLength = RtlpGetLengthOfRunClear(BitMapHeader,
> +                                                CurrentBit,
> +                                                NumberToFind);
> +
> +        /* Is this long enough? */
> +        if (CurrentLength >= NumberToFind)
> +        {
> +            /* It is */
> +            return CurrentBit;
> +        }
> +
> +        CurrentBit += CurrentLength;
> +    }
> +
> +    /* Nothing found */
>     return MAXULONG;
> -
> -  ulEnd = BitMapHeader->SizeOfBitMap;
> -
> -  if (HintIndex + NumberToFind > BitMapHeader->SizeOfBitMap)
> -    HintIndex = 0;
> -
> -  ulPos = HintIndex;
> -
> -  while (ulPos < ulEnd)
> -  {
> -    /* FIXME: This could be made a _lot_ more efficient */
> -    if (RtlAreBitsClear(BitMapHeader, ulPos, NumberToFind))
> -      return ulPos;
> -
> -    /* Start from the beginning if we hit the end and started from HintIndex 
> */
> -    if (ulPos == ulEnd - 1 && HintIndex)
> -    {
> -      ulEnd = HintIndex;
> -      ulPos = HintIndex = 0;
> -    }
> -    else
> -      ulPos++;
> -  }
> -  return MAXULONG;
> -}
> -
> -/*
> - * @implemented
> - */
> -ULONG NTAPI
> -RtlFindClearRuns(PRTL_BITMAP BitMapHeader,
> -              PRTL_BITMAP_RUN RunArray,
> -              ULONG SizeOfRunArray,
> -              BOOLEAN LocateLongestRuns)
> -{
> -    return NTDLL_FindRuns(BitMapHeader, RunArray, SizeOfRunArray, 
> LocateLongestRuns, NTDLL_FindClearRun);
> -}
> -
> -/*
> - * @unimplemented
> - */
> -ULONG NTAPI
> -RtlFindLastBackwardRunClear(IN PRTL_BITMAP BitMapHeader,
> -                         IN ULONG FromIndex,
> -                         IN PULONG StartingRunIndex)
> -{
> -  UNIMPLEMENTED;
> -  return 0;
> -}
> -
> -/*
> - * @implemented
> - */
> -ULONG NTAPI
> -RtlFindNextForwardRunClear(IN PRTL_BITMAP BitMapHeader,
> -                        IN ULONG FromIndex,
> -                        IN PULONG StartingRunIndex)
> -{
> -  ULONG ulSize = 0;
> -
> -  if (BitMapHeader && FromIndex < BitMapHeader->SizeOfBitMap && 
> StartingRunIndex)
> -    *StartingRunIndex = NTDLL_FindClearRun(BitMapHeader, FromIndex, &ulSize);
> -
> -  return ulSize;
> -}
> -
> -/*
> - * @implemented
> - */
> -ULONG NTAPI
> -RtlFindFirstRunSet(IN PRTL_BITMAP BitMapHeader,
> -                IN PULONG StartingIndex)
> -{
> -  ULONG Size;
> -  ULONG Index;
> -  ULONG Count;
> -  PULONG Ptr;
> -  ULONG  Mask;
> -
> -  Size = BitMapHeader->SizeOfBitMap;
> -  if (*StartingIndex > Size)
> -  {
> -    *StartingIndex = MAXULONG;
> +}
> +
> +ULONG
> +NTAPI
> +RtlFindSetBits(
> +    IN PRTL_BITMAP BitMapHeader,
> +    IN ULONG NumberToFind,
> +    IN ULONG HintIndex)
> +{
> +    ULONG CurrentBit, CurrentLength;
> +
> +    /* Check for valid parameters */
> +    if (!BitMapHeader || NumberToFind > BitMapHeader->SizeOfBitMap)
> +    {
> +        return MAXULONG;
> +    }
> +
> +    /* Check for trivial case */
> +    if (NumberToFind == 0)
> +    {
> +        return HintIndex;
> +    }
> +
> +    /* Start with hint index, length is 0 */
> +    CurrentBit = HintIndex;
> +    CurrentLength = 0;
> +
> +    /* Loop until something is found or the end is reached */
> +    while (CurrentBit + NumberToFind <= BitMapHeader->SizeOfBitMap)
> +    {
> +        /* Search for the next set run, by skipping a clear run */
> +        CurrentBit += RtlpGetLengthOfRunClear(BitMapHeader,
> +                                              CurrentBit,
> +                                              MAXULONG);
> +
> +        /* Get length of the set bit run */
> +        CurrentLength = RtlpGetLengthOfRunSet(BitMapHeader,
> +                                              CurrentBit,
> +                                              NumberToFind);
> +
> +        /* Is this long enough? */
> +        if (CurrentLength >= NumberToFind)
> +        {
> +            /* It is */
> +            return CurrentBit;
> +        }
> +
> +        CurrentBit += CurrentLength;
> +    }
> +
> +    /* Nothing found */
> +    return MAXULONG;
> +}
> +
> +ULONG
> +NTAPI
> +RtlFindClearBitsAndSet(
> +    PRTL_BITMAP BitMapHeader,
> +    ULONG NumberToFind,
> +    ULONG HintIndex)
> +{
> +    ULONG Position;
> +
> +    /* Try to find clear bits */
> +    Position = RtlFindClearBits(BitMapHeader, NumberToFind, HintIndex);
> +
> +    /* Did we get something? */
> +    if (Position != MAXULONG)
> +    {
> +        /* Yes, set the bits */
> +        RtlSetBits(BitMapHeader, Position, NumberToFind);
> +    }
> +
> +    /* Return what we found */
> +    return Position;
> +}
> +
> +ULONG
> +NTAPI
> +RtlFindSetBitsAndClear(
> +    IN PRTL_BITMAP BitMapHeader,
> +    IN ULONG NumberToFind,
> +    IN ULONG HintIndex)
> +{
> +    ULONG Position;
> +
> +    /* Try to find set bits */
> +    Position = RtlFindSetBits(BitMapHeader, NumberToFind, HintIndex);
> +
> +    /* Did we get something? */
> +    if (Position != MAXULONG)
> +    {
> +        /* Yes, clear the bits */
> +        RtlClearBits(BitMapHeader, Position, NumberToFind);
> +    }
> +
> +    /* Return what we found */
> +    return Position;
> +}
> +
> +ULONG
> +NTAPI
> +RtlFindNextForwardRunClear(
> +    IN PRTL_BITMAP BitMapHeader,
> +    IN ULONG FromIndex,
> +    IN PULONG StartingRunIndex)
> +{
> +    ULONG Length;
> +
> +    /* Assume a set run first, count it's length */
> +    Length = RtlpGetLengthOfRunSet(BitMapHeader, FromIndex, MAXULONG);
> +    *StartingRunIndex = FromIndex;
> +
> +    /* Now return the length of the run */
> +    return RtlpGetLengthOfRunClear(BitMapHeader, FromIndex, MAXULONG);
> +}
> +
> +ULONG
> +NTAPI
> +RtlFindNextForwardRunSet(
> +    IN PRTL_BITMAP BitMapHeader,
> +    IN ULONG FromIndex,
> +    IN PULONG StartingRunIndex)
> +{
> +    ULONG Length;
> +
> +    /* Assume a clear run first, count it's length */
> +    Length = RtlpGetLengthOfRunClear(BitMapHeader, FromIndex, MAXULONG);
> +    *StartingRunIndex = FromIndex;
> +
> +    /* Now return the length of the run */
> +    return RtlpGetLengthOfRunSet(BitMapHeader, FromIndex, MAXULONG);
> +}
> +
> +ULONG
> +NTAPI
> +RtlFindFirstRunClear(
> +    IN PRTL_BITMAP BitMapHeader,
> +    IN PULONG StartingIndex)
> +{
> +    return RtlFindNextForwardRunClear(BitMapHeader, 0, StartingIndex);
> +}
> +
> +ULONG
> +NTAPI
> +RtlFindLastBackwardRunClear(
> +    IN PRTL_BITMAP BitMapHeader,
> +    IN ULONG FromIndex,
> +    IN PULONG StartingRunIndex)
> +{
> +    UNIMPLEMENTED;
>     return 0;
> -  }
> -
> -  Index = *StartingIndex;
> -  Ptr = (PULONG)BitMapHeader->Buffer + (Index / 32);
> -  Mask = 1 << (Index & 0x1F);
> -
> -  /* Skip clear bits */
> -  for (; Index < Size && ~*Ptr & Mask; Index++)
> -  {
> -    Mask <<= 1;
> -
> -    if (Mask == 0)
> -    {
> -      Mask = 1;
> -      Ptr++;
> -    }
> -  }
> -
> -  /* Return index of first set bit */
> -  if (Index >= Size)
> -  {
> -    *StartingIndex = MAXULONG;
> -    return 0;
> -  }
> -  else
> -  {
> -    *StartingIndex = Index;
> -  }
> -
> -  /* Count set bits */
> -  for (Count = 0; Index < Size && *Ptr & Mask; Index++)
> -  {
> -    Count++;
> -    Mask <<= 1;
> -
> -    if (Mask == 0)
> -    {
> -      Mask = 1;
> -      Ptr++;
> -    }
> -  }
> -
> -  return Count;
> -}
> -
> -
> -/*
> - * @implemented
> - */
> -ULONG NTAPI
> -RtlFindLongestRunClear(PRTL_BITMAP BitMapHeader,
> -                    PULONG StartingIndex)
> -{
> -  /* GCC complaints that it may be used uninitialized */
> -  RTL_BITMAP_RUN br = { 0, 0 };
> -
> -  if (RtlFindClearRuns(BitMapHeader, &br, 1, TRUE) == 1)
> -  {
> -    if (StartingIndex)
> -      *StartingIndex = br.StartingIndex;
> -    return br.NumberOfBits;
> -  }
> -  return 0;
> -}
> -
> -
> -/*
> - * @implemented
> - */
> -ULONG NTAPI
> -RtlFindLongestRunSet(PRTL_BITMAP BitMapHeader,
> -                  PULONG StartingIndex)
> -{
> -  /* GCC complaints that it may be used uninitialized */
> -  RTL_BITMAP_RUN br = { 0, 0 };
> -
> -  if (NTDLL_FindRuns(BitMapHeader, &br, 1, TRUE, NTDLL_FindSetRun) == 1)
> -  {
> -    if (StartingIndex)
> -      *StartingIndex = br.StartingIndex;
> -    return br.NumberOfBits;
> -  }
> -  return 0;
> -}
> -
> -
> -/*
> - * @implemented
> - */
> -ULONG NTAPI
> -RtlFindSetBits(PRTL_BITMAP BitMapHeader,
> -            ULONG NumberToFind,
> -            ULONG HintIndex)
> -{
> -  ULONG ulPos, ulEnd;
> -
> -  if (!BitMapHeader || !NumberToFind || NumberToFind > 
> BitMapHeader->SizeOfBitMap)
> -    return MAXULONG;
> -
> -  ulEnd = BitMapHeader->SizeOfBitMap;
> -
> -  if (HintIndex + NumberToFind > BitMapHeader->SizeOfBitMap)
> -    HintIndex = 0;
> -
> -  ulPos = HintIndex;
> -
> -  while (ulPos < ulEnd)
> -  {
> -    /* FIXME: This could be made a _lot_ more efficient */
> -    if (RtlAreBitsSet(BitMapHeader, ulPos, NumberToFind))
> -      return ulPos;
> -
> -    /* Start from the beginning if we hit the end and had a hint */
> -    if (ulPos == ulEnd - 1 && HintIndex)
> -    {
> -      ulEnd = HintIndex;
> -      ulPos = HintIndex = 0;
> -    }
> -    else
> -      ulPos++;
> -  }
> -  return MAXULONG;
> -}
> -
> -
> -/*
> - * @implemented
> - */
> -ULONG NTAPI
> -RtlFindSetBitsAndClear(PRTL_BITMAP BitMapHeader,
> -                    ULONG NumberToFind,
> -                    ULONG HintIndex)
> -{
> -  ULONG ulPos;
> -
> -  ulPos = RtlFindSetBits(BitMapHeader, NumberToFind, HintIndex);
> -  if (ulPos != MAXULONG)
> -    RtlClearBits(BitMapHeader, ulPos, NumberToFind);
> -  return ulPos;
> -}
> -
> -
> -/*
> - * @implemented
> - */
> -ULONG NTAPI
> -RtlNumberOfSetBits(PRTL_BITMAP BitMapHeader)
> -{
> -  ULONG ulSet = 0;
> -
> -  if (BitMapHeader)
> -  {
> -    LPBYTE lpOut = (BYTE *)BitMapHeader->Buffer;
> -    ULONG Length, ulRemainder;
> -    BYTE bMasked;
> -
> -    Length = BitMapHeader->SizeOfBitMap >> 3;
> -    ulRemainder = BitMapHeader->SizeOfBitMap & 0x7;
> -
> -    while (Length--)
> -    {
> -      ulSet += NTDLL_nibbleBitCount[*lpOut >> 4];
> -      ulSet += NTDLL_nibbleBitCount[*lpOut & 0xf];
> -      lpOut++;
> -    }
> -
> -    if (ulRemainder)
> -    {
> -      bMasked = *lpOut & NTDLL_maskBits[ulRemainder];
> -      ulSet += NTDLL_nibbleBitCount[bMasked >> 4];
> -      ulSet += NTDLL_nibbleBitCount[bMasked & 0xf];
> -    }
> -  }
> -  return ulSet;
> -}
> -
> -
> -/*
> - * @implemented
> - */
> -VOID NTAPI
> -RtlSetAllBits(IN OUT PRTL_BITMAP BitMapHeader)
> -{
> -  memset(BitMapHeader->Buffer, 0xff, ((BitMapHeader->SizeOfBitMap + 31) & 
> ~31) >> 3);
> -}
> -
> -
> -/*
> - * @implemented
> - */
> -VOID NTAPI
> -RtlSetBit(PRTL_BITMAP BitMapHeader,
> -       ULONG BitNumber)
> -{
> -  PUCHAR Ptr;
> -
> -  if (BitNumber >= BitMapHeader->SizeOfBitMap)
> -    return;
> -
> -  Ptr = (PUCHAR)BitMapHeader->Buffer + (BitNumber / 8);
> -
> -  *Ptr |= (1 << (BitNumber % 8));
> -}
> -
> -
> -/*
> - * @implemented
> - */
> -VOID NTAPI
> -RtlSetBits(PRTL_BITMAP BitMapHeader,
> -        ULONG StartingIndex,
> -        ULONG NumberToSet)
> -{
> -  LPBYTE lpOut;
> -
> -  if (!BitMapHeader || !NumberToSet ||
> -      StartingIndex >= BitMapHeader->SizeOfBitMap ||
> -      NumberToSet > BitMapHeader->SizeOfBitMap - StartingIndex)
> -    return;
> -
> -  /* FIXME: It might be more efficient/cleaner to manipulate four bytes
> -   * at a time. But beware of the pointer arithmetics...
> -   */
> -  lpOut = ((BYTE*)BitMapHeader->Buffer) + (StartingIndex >> 3u);
> -
> -  /* Set bits in first byte, if StartingIndex isn't a byte boundary */
> -  if (StartingIndex & 7)
> -  {
> -    if (NumberToSet > 7)
> -    {
> -      /* Set from start bit to the end of the byte */
> -      *lpOut++ |= 0xff << (StartingIndex & 7);
> -      NumberToSet -= (8 - (StartingIndex & 7));
> -    }
> -    else
> -    {
> -      /* Set from the start bit, possibly into the next byte also */
> -      USHORT initialWord = NTDLL_maskBits[NumberToSet] << (StartingIndex & 
> 7);
> -
> -      *lpOut++ |= (initialWord & 0xff);
> -      *lpOut |= (initialWord >> 8);
> -      return;
> -    }
> -  }
> -
> -  /* Set bits up to complete byte count */
> -  if (NumberToSet >> 3)
> -  {
> -    memset(lpOut, 0xff, NumberToSet >> 3);
> -    lpOut = lpOut + (NumberToSet >> 3);
> -  }
> -
> -  /* Set remaining bits, if any */
> -  if (NumberToSet & 0x7)
> -    *lpOut |= NTDLL_maskBits[NumberToSet & 0x7];
> -}
> -
> -
> -/*
> - * @implemented
> - */
> -BOOLEAN NTAPI
> -RtlTestBit(PRTL_BITMAP BitMapHeader,
> -        ULONG BitNumber)
> -{
> -  PUCHAR Ptr;
> -
> -  if (BitNumber >= BitMapHeader->SizeOfBitMap)
> -    return FALSE;
> -
> -  Ptr = (PUCHAR)BitMapHeader->Buffer + (BitNumber / 8);
> -
> -  return (BOOLEAN)(*Ptr & (1 << (BitNumber % 8)));
> -}
> -
> -/*
> - * @implemented
> - */
> -ULONG NTAPI
> -RtlFindFirstRunClear(PRTL_BITMAP BitMapHeader,
> -                  PULONG StartingIndex)
> -{
> -    return RtlFindNextForwardRunClear(BitMapHeader, 0, StartingIndex);
> -}
> -
> -/*
> - * @implemented
> - */
> -ULONG NTAPI
> -RtlNumberOfClearBits(PRTL_BITMAP BitMapHeader)
> -{
> -
> -  if (BitMapHeader)
> -    return BitMapHeader->SizeOfBitMap - RtlNumberOfSetBits(BitMapHeader);
> -  return 0;
> -}
> -
> -/*
> - * @implemented
> - */
> -ULONG NTAPI
> -RtlFindClearBitsAndSet(PRTL_BITMAP BitMapHeader,
> -                    ULONG NumberToFind,
> -                    ULONG HintIndex)
> -{
> -  ULONG ulPos;
> -
> -  ulPos = RtlFindClearBits(BitMapHeader, NumberToFind, HintIndex);
> -  if (ulPos != MAXULONG)
> -    RtlSetBits(BitMapHeader, ulPos, NumberToFind);
> -  return ulPos;
> -}
> -
> -/*
> - * @implemented
> - */
> -CCHAR WINAPI RtlFindMostSignificantBit(ULONGLONG ulLong)
> -{
> -    signed char ret = 32;
> -    DWORD dw;
> -
> -    if (!(dw = (DWORD)(ulLong >> 32)))
> -    {
> -        ret = 0;
> -        dw = (DWORD)ulLong;
> -    }
> -    if (dw & 0xffff0000)
> -    {
> -        dw >>= 16;
> -        ret += 16;
> -    }
> -    if (dw & 0xff00)
> -    {
> -        dw >>= 8;
> -        ret += 8;
> -    }
> -    if (dw & 0xf0)
> -    {
> -        dw >>= 4;
> -        ret += 4;
> -    }
> -    return ret + NTDLL_mostSignificant[dw];
> -}
> -
> -/*
> - * @implemented
> - */
> -CCHAR WINAPI RtlFindLeastSignificantBit(ULONGLONG ulLong)
> -{
> -    signed char ret = 0;
> -    DWORD dw;
> -
> -    if (!(dw = (DWORD)ulLong))
> -    {
> -        ret = 32;
> -        if (!(dw = (DWORD)(ulLong >> 32))) return -1;
> -    }
> -    if (!(dw & 0xffff))
> -    {
> -        dw >>= 16;
> -        ret += 16;
> -    }
> -    if (!(dw & 0xff))
> -    {
> -        dw >>= 8;
> -        ret += 8;
> -    }
> -    if (!(dw & 0x0f))
> -    {
> -        dw >>= 4;
> -        ret += 4;
> -    }
> -    return ret + NTDLL_leastSignificant[dw & 0x0f];
> -}
> -
> -/* EOF */
> +}
> +
> +
> +ULONG
> +NTAPI
> +RtlFindClearRuns(
> +    IN PRTL_BITMAP BitMapHeader,
> +    IN PRTL_BITMAP_RUN RunArray,
> +    IN ULONG SizeOfRunArray,
> +    IN BOOLEAN LocateLongestRuns)
> +{
> +    ULONG StartingIndex, NumberOfBits, Run, FromIndex = 0, SmallestRun = 0;
> +
> +    /* Loop the runs */
> +    for (Run = 0; Run < SizeOfRunArray; Run++)
> +    {
> +        /* Look for a run */
> +        NumberOfBits = RtlFindNextForwardRunClear(BitMapHeader, 
> +                                                  FromIndex,
> +                                                  &StartingIndex);
> +
> +        /* Nothing more found? Quit looping. */
> +        if (NumberOfBits == 0) break;
> +
> +        /* Add another run */
> +        RunArray[Run].StartingIndex = StartingIndex;
> +        RunArray[Run].NumberOfBits = NumberOfBits;
> +
> +        /* Update smallest run */
> +        if (NumberOfBits < RunArray[SmallestRun].NumberOfBits)
> +        {
> +            SmallestRun = Run;
> +        }
> +
> +        /* Advance bits */
> +        FromIndex += NumberOfBits;
> +    }
> +
> +    /* Check if we are finished */
> +    if (Run < SizeOfRunArray || !LocateLongestRuns)
> +    {
> +        /* Return the number of found runs */
> +        return Run;
> +    }
> +
> +    while (1)
> +    {
> +        /* Look for a run */
> +        NumberOfBits = RtlFindNextForwardRunClear(BitMapHeader, 
> +                                                  FromIndex,
> +                                                  &StartingIndex);
> +
> +        /* Nothing more found? Quit looping. */
> +        if (NumberOfBits == 0) break;
> +
> +        /* Check if we have something to update */
> +        if (NumberOfBits > RunArray[SmallestRun].NumberOfBits)
> +        {
> +            /* Update smallest run */
> +            RunArray[SmallestRun].StartingIndex = StartingIndex;
> +            RunArray[SmallestRun].NumberOfBits = NumberOfBits;
> +
> +            /* Loop all runs */
> +            for (Run = 0; Run < SizeOfRunArray; Run++)
> +            {
> +                /*Is this the new smallest run? */
> +                if (NumberOfBits < RunArray[SmallestRun].NumberOfBits)
> +                {
> +                    /* Set it as new smallest run */
> +                    SmallestRun = Run;
> +                }
> +            }
> +        }
> +
> +        /* Advance bits */
> +        FromIndex += NumberOfBits;
> +    }
> +
> +    return Run;
> +}
> +
> +ULONG
> +NTAPI
> +RtlFindLongestRunClear(
> +    IN PRTL_BITMAP BitMapHeader,
> +    IN PULONG StartingIndex)
> +{
> +    ULONG NumberOfBits, Index, MaxNumberOfBits = 0, FromIndex = 0;
> +
> +    while (1)
> +    {
> +        /* Look for a run */
> +        NumberOfBits = RtlFindNextForwardRunClear(BitMapHeader, 
> +                                                  FromIndex,
> +                                                  &Index);
> +
> +        /* Nothing more found? Quit looping. */
> +        if (NumberOfBits == 0) break;
> +
> +        /* Was that the longest run? */
> +        if (NumberOfBits > MaxNumberOfBits)
> +        {
> +            /* Update values */
> +            MaxNumberOfBits = NumberOfBits;
> +            *StartingIndex = Index;
> +        }
> +
> +        /* Advance bits */
> +        FromIndex += NumberOfBits;
> +    }
> +
> +    return MaxNumberOfBits;
> +}
> +
> +ULONG
> +NTAPI
> +RtlFindLongestRunSet(
> +    IN PRTL_BITMAP BitMapHeader,
> +    IN PULONG StartingIndex)
> +{
> +    ULONG NumberOfBits, Index, MaxNumberOfBits = 0, FromIndex = 0;
> +
> +    while (1)
> +    {
> +        /* Look for a run */
> +        NumberOfBits = RtlFindNextForwardRunSet(BitMapHeader, 
> +                                                FromIndex,
> +                                                &Index);
> +
> +        /* Nothing more found? Quit looping. */
> +        if (NumberOfBits == 0) break;
> +
> +        /* Was that the longest run? */
> +        if (NumberOfBits > MaxNumberOfBits)
> +        {
> +            /* Update values */
> +            MaxNumberOfBits = NumberOfBits;
> +            *StartingIndex = Index;
> +        }
> +
> +        /* Advance bits */
> +        FromIndex += NumberOfBits;
> +    }
> +
> +    return MaxNumberOfBits;
> +}
> +
> 
> Modified: trunk/reactos/tools/mkhive/mkhive.h
> URL: 
> http://svn.reactos.org/svn/reactos/trunk/reactos/tools/mkhive/mkhive.h?rev=44464&r1=44463&r2=44464&view=diff
> ==============================================================================
> --- trunk/reactos/tools/mkhive/mkhive.h [iso-8859-1] (original)
> +++ trunk/reactos/tools/mkhive/mkhive.h [iso-8859-1] Tue Dec  8 02:02:36 2009
> @@ -46,6 +46,10 @@
> #define STATUS_OBJECT_NAME_NOT_FOUND     ((NTSTATUS)0xC0000034)
> #define STATUS_INVALID_PARAMETER_2       ((NTSTATUS)0xC00000F0)
> #define STATUS_BUFFER_OVERFLOW           ((NTSTATUS)0x80000005)
> +
> +unsigned char BitScanForward(ULONG * Index, const unsigned long Mask);
> +unsigned char BitScanReverse(ULONG * const Index, const unsigned long Mask);
> +#define RtlFillMemoryUlong(dst, len, val) memset(dst, val, len)
> 
> NTSTATUS NTAPI
> RtlAnsiStringToUnicodeString(
> 
> Modified: trunk/reactos/tools/mkhive/rtl.c
> URL: 
> http://svn.reactos.org/svn/reactos/trunk/reactos/tools/mkhive/rtl.c?rev=44464&r1=44463&r2=44464&view=diff
> ==============================================================================
> --- trunk/reactos/tools/mkhive/rtl.c [iso-8859-1] (original)
> +++ trunk/reactos/tools/mkhive/rtl.c [iso-8859-1] Tue Dec  8 02:02:36 2009
> @@ -185,3 +185,25 @@
> 
>    //DbgBreakPoint();
> }
> +
> +unsigned char BitScanForward(ULONG * Index, unsigned long Mask)
> +{
> +    *Index = 0;
> +    while (Mask && ((Mask & 1) == 0))
> +    {
> +        Mask >>= 1;
> +        ++(*Index);
> +    }
> +    return Mask ? 1 : 0;
> +}
> +
> +unsigned char BitScanReverse(ULONG * const Index, unsigned long Mask)
> +{
> +    *Index = 0;
> +    while (Mask && ((Mask & (1 << 31)) == 0))
> +    {
> +        Mask <<= 1;
> +        ++(*Index);
> +    }
> +    return Mask ? 1 : 0;
> +}
> 
> 

Best regards,
Alex Ionescu


_______________________________________________
Ros-dev mailing list
[email protected]
http://www.reactos.org/mailman/listinfo/ros-dev

Reply via email to