VirtualBox

Changeset 87192 in vbox for trunk/src/VBox/Runtime/common


Ignore:
Timestamp:
Jan 7, 2021 8:43:08 PM (4 years ago)
Author:
vboxsync
Message:

iprt/asm.h: Added generic C version of ASMBitFirstClear. Officially specified that the iprt/asm.h bitmaps are little-endian and added missing conversions. bugref:9898

Location:
trunk/src/VBox/Runtime/common/asm
Files:
1 edited
1 copied

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/common/asm/ASMBitFirstClear-generic.cpp

    r87185 r87192  
    11/* $Id$ */
    22/** @file
    3  * IPRT - ASMMemZeroPage - generic C implementation.
     3 * IPRT - ASMBitFirstClear - generic C implementation.
    44 */
    55
     
    3232#include "internal/iprt.h"
    3333
     34#include <iprt/assert.h>
    3435
    35 DECLASM(void *) ASMMemFirstMismatchingU8(void const RT_FAR *pv, size_t cb, uint8_t u8) RT_NOTHROW_DEF
     36
     37DECLASM(int32_t) ASMBitFirstClear(const volatile void RT_FAR *pvBitmap, uint32_t cBits) RT_NOTHROW_DEF
    3638{
    37     uint8_t const *pb = (uint8_t const RT_FAR *)pv;
    38     for (; cb; cb--, pb++)
    39         if (RT_LIKELY(*pb == u8))
    40         { /* likely */ }
     39    const volatile size_t RT_FAR *pu = (const volatile size_t RT_FAR *)pvBitmap;
     40    Assert(!(cBits & 31));
     41
     42    while (cBits >= sizeof(size_t) * 8)
     43    {
     44        size_t u = *pu;
     45        if (u == ~(size_t)0)
     46        { }
    4147        else
    42             return (void *)pb;
    43     return NULL;
     48        {
     49            size_t const iBaseBit = ((uintptr_t)pu - (uintptr_t)pvBitmap) * 8;
     50#if ARCH_BITS == 32
     51            return iBaseBit + ASMBitFirstSetU32(~RT_LE2H_U32(u)) - 1;
     52#elif ARCH_BITS == 64
     53            return iBaseBit + ASMBitFirstSetU64(~RT_LE2H_U64(u)) - 1;
     54#else
     55# error "ARCH_BITS or RT_BIG_ENDIAN/RT_LITTLE_ENDIAN is not supported" /** @todo figure out bitmaps on bigendian systems! */
     56#endif
     57        }
     58
     59        pu++;
     60        cBits -= sizeof(size_t) * 8;
     61    }
     62
     63#if ARCH_BITS > 32
     64    if (cBits >= 32)
     65    {
     66        uint32_t u32 = *(const volatile uint32_t RT_FAR *)pu;
     67        if (u32 != UINT32_MAX)
     68        {
     69            size_t const iBaseBit = ((uintptr_t)pu - (uintptr_t)pvBitmap) * 8;
     70            return iBaseBit + ASMBitFirstSetU32(~RT_LE2H_U32(u32)) - 1;
     71        }
     72    }
     73#endif
     74
     75    return -1;
    4476}
    4577
  • trunk/src/VBox/Runtime/common/asm/asm-fake.cpp

    r87187 r87192  
    297297}
    298298
    299 RTDECL(int) ASMBitFirstClear(const volatile void *pvBitmap, uint32_t cBits)
    300 {
    301     uint32_t           iBit = 0;
    302     uint8_t volatile *pu8 = (uint8_t volatile *)pvBitmap;
    303 
    304     while (iBit < cBits)
    305     {
    306         uint8_t u8 = *pu8;
    307         if (u8 != UINT8_MAX)
    308         {
    309             while (u8 & 1)
    310             {
    311                 u8 >>= 1;
    312                 iBit++;
    313             }
    314             if (iBit >= cBits)
    315                 return -1;
    316             return iBit;
    317         }
    318 
    319         iBit += 8;
    320         pu8++;
    321     }
    322     return -1;
    323 }
    324 
    325299RTDECL(int) ASMBitNextClear(const volatile void *pvBitmap, uint32_t cBits, uint32_t iBitPrev)
    326300{
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette