Module: wine Branch: master Commit: 504f9d3cb8680e6c8f4a6bb44eb5bd9e197859eb URL: https://gitlab.winehq.org/wine/wine/-/commit/504f9d3cb8680e6c8f4a6bb44eb5bd9...
Author: Alexandre Julliard julliard@winehq.org Date: Sat Apr 22 17:33:32 2023 +0200
ntdll: Reimplement RtlAreBitsClear() to check 32 bits at a time.
---
dlls/ntdll/rtlbitmap.c | 70 ++++++++------------------------------------------ 1 file changed, 11 insertions(+), 59 deletions(-)
diff --git a/dlls/ntdll/rtlbitmap.c b/dlls/ntdll/rtlbitmap.c index 17a8f8b3134..b6225165840 100644 --- a/dlls/ntdll/rtlbitmap.c +++ b/dlls/ntdll/rtlbitmap.c @@ -186,72 +186,24 @@ BOOLEAN WINAPI RtlAreBitsSet( const RTL_BITMAP *bitmap, ULONG start, ULONG count
/************************************************************************* * RtlAreBitsClear [NTDLL.@] - * - * Determine if part of a bitmap is clear. - * - * PARAMS - * lpBits [I] Bitmap pointer - * ulStart [I] First bit to check from - * ulCount [I] Number of consecutive bits to check - * - * RETURNS - * TRUE, If ulCount bits from ulStart are clear. - * FALSE, Otherwise. */ -BOOLEAN WINAPI RtlAreBitsClear(PCRTL_BITMAP lpBits, ULONG ulStart, ULONG ulCount) +BOOLEAN WINAPI RtlAreBitsClear( const RTL_BITMAP *bitmap, ULONG start, ULONG count ) { - LPBYTE lpOut; - ULONG ulRemainder; - - TRACE("(%p,%lu,%lu)\n", lpBits, ulStart, ulCount); - - if (!lpBits || !ulCount || - ulStart >= lpBits->SizeOfBitMap || - ulCount > lpBits->SizeOfBitMap - ulStart) - return FALSE; - - /* 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); + ULONG end = start + count; + ULONG pos = start / 32; + ULONG end_pos = end / 32;
- /* Check bits in first byte, if ulStart isn't a byte boundary */ - if (ulStart & 7) - { - if (ulCount > 7) - { - /* Check from start bit to the end of the byte */ - if (*lpOut & ((0xff << (ulStart & 7)) & 0xff)) - return FALSE; - lpOut++; - ulCount -= (8 - (ulStart & 7)); - } - else - { - /* Check from the start bit, possibly into the next byte also */ - USHORT initialWord = NTDLL_maskBits[ulCount] << (ulStart & 7); + TRACE( "(%p,%lu,%lu)\n", bitmap, start, count );
- if (*lpOut & (initialWord & 0xff)) - return FALSE; - if ((initialWord & 0xff00) && (lpOut[1] & (initialWord >> 8))) + if (!count || start >= bitmap->SizeOfBitMap || count > bitmap->SizeOfBitMap - start) return FALSE; - return TRUE; - } - }
- /* Check bits in blocks of 8 bytes */ - ulRemainder = ulCount & 7; - ulCount >>= 3; - while (ulCount--) - { - if (*lpOut++) - return FALSE; - } + if (end_pos == pos) return !(bitmap->Buffer[pos] & maskbits( start ) & ~maskbits( end ));
- /* Check remaining bits, if any */ - if (ulRemainder && *lpOut & NTDLL_maskBits[ulRemainder]) - return FALSE; - return TRUE; + if (bitmap->Buffer[pos++] & maskbits( start )) return FALSE; + while (pos < end_pos) if (bitmap->Buffer[pos++]) return FALSE; + if (!(end & 31)) return TRUE; + return !(bitmap->Buffer[pos] & ~maskbits( end )); }
/*************************************************************************