VirtualBox

Changeset 87192 in vbox


Ignore:
Timestamp:
Jan 7, 2021 8:43:08 PM (4 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
142145
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
Files:
3 edited
1 copied

Legend:

Unmodified
Added
Removed
  • trunk/include/iprt/asm.h

    r87191 r87192  
    54575457 * Sets a bit in a bitmap.
    54585458 *
    5459  * @param   pvBitmap    Pointer to the bitmap. This should be 32-bit aligned.
     5459 * @param   pvBitmap    Pointer to the bitmap (little endian).  This should be
     5460 *                      32-bit aligned.
    54605461 * @param   iBit        The bit to set.
    54615462 *
     
    54985499    int32_t offBitmap = iBit / 32;
    54995500    AssertStmt(!((uintptr_t)pvBitmap & 3), offBitmap += (uintptr_t)pvBitmap & 3; iBit += ((uintptr_t)pvBitmap & 3) * 8);
    5500     ASMAtomicUoOrU32(&((uint32_t volatile *)pvBitmap)[offBitmap], RT_BIT_32(iBit & 31));
     5501    ASMAtomicUoOrU32(&((uint32_t volatile *)pvBitmap)[offBitmap], RT_H2LE_U32(RT_BIT_32(iBit & 31)));
    55015502# endif
    55025503}
     
    55075508 * Atomically sets a bit in a bitmap, ordered.
    55085509 *
    5509  * @param   pvBitmap    Pointer to the bitmap. Must be 32-bit aligned, otherwise
    5510  *                      the memory access isn't atomic!
     5510 * @param   pvBitmap    Pointer to the bitmap (little endian).  Must be 32-bit
     5511 *                      aligned, otherwise the memory access isn't atomic!
    55115512 * @param   iBit        The bit to set.
    55125513 *
     
    55455546
    55465547# else
    5547     ASMAtomicOrU32(&((uint32_t volatile *)pvBitmap)[iBit / 32], RT_BIT_32(iBit & 31));
     5548    ASMAtomicOrU32(&((uint32_t volatile *)pvBitmap)[iBit / 32], RT_H2LE_U32(RT_BIT_32(iBit & 31)));
    55485549# endif
    55495550}
     
    55545555 * Clears a bit in a bitmap.
    55555556 *
    5556  * @param   pvBitmap    Pointer to the bitmap.
     5557 * @param   pvBitmap    Pointer to the bitmap (little endian).
    55575558 * @param   iBit        The bit to clear.
    55585559 *
     
    55955596    int32_t offBitmap = iBit / 32;
    55965597    AssertStmt(!((uintptr_t)pvBitmap & 3), offBitmap += (uintptr_t)pvBitmap & 3; iBit += ((uintptr_t)pvBitmap & 3) * 8);
    5597     ASMAtomicUoAndU32(&((uint32_t volatile *)pvBitmap)[offBitmap], ~RT_BIT_32(iBit & 31));
     5598    ASMAtomicUoAndU32(&((uint32_t volatile *)pvBitmap)[offBitmap], RT_H2LE_U32(~RT_BIT_32(iBit & 31)));
    55985599# endif
    55995600}
     
    56045605 * Atomically clears a bit in a bitmap, ordered.
    56055606 *
    5606  * @param   pvBitmap    Pointer to the bitmap. Must be 32-bit aligned, otherwise
    5607  *                      the memory access isn't atomic!
     5607 * @param   pvBitmap    Pointer to the bitmap (little endian).  Must be 32-bit
     5608 *                      aligned, otherwise the memory access isn't atomic!
    56085609 * @param   iBit        The bit to toggle set.
    56095610 *
     
    56405641#  endif
    56415642# else
    5642     ASMAtomicAndU32(&((uint32_t volatile *)pvBitmap)[iBit / 32], ~RT_BIT_32(iBit & 31));
     5643    ASMAtomicAndU32(&((uint32_t volatile *)pvBitmap)[iBit / 32], RT_H2LE_U32(~RT_BIT_32(iBit & 31)));
    56435644# endif
    56445645}
     
    56495650 * Toggles a bit in a bitmap.
    56505651 *
    5651  * @param   pvBitmap    Pointer to the bitmap.
     5652 * @param   pvBitmap    Pointer to the bitmap (little endian).
    56525653 * @param   iBit        The bit to toggle.
    56535654 *
     
    56885689    int32_t offBitmap = iBit / 32;
    56895690    AssertStmt(!((uintptr_t)pvBitmap & 3), offBitmap += (uintptr_t)pvBitmap & 3; iBit += ((uintptr_t)pvBitmap & 3) * 8);
    5690     ASMAtomicUoXorU32(&((uint32_t volatile *)pvBitmap)[offBitmap], RT_BIT_32(iBit & 31));
     5691    ASMAtomicUoXorU32(&((uint32_t volatile *)pvBitmap)[offBitmap], RT_H2LE_U32(RT_BIT_32(iBit & 31)));
    56915692# endif
    56925693}
     
    56975698 * Atomically toggles a bit in a bitmap, ordered.
    56985699 *
    5699  * @param   pvBitmap    Pointer to the bitmap. Must be 32-bit aligned, otherwise
    5700  *                      the memory access isn't atomic!
     5700 * @param   pvBitmap    Pointer to the bitmap (little endian).  Must be 32-bit
     5701 *                      aligned, otherwise the memory access isn't atomic!
    57015702 * @param   iBit        The bit to test and set.
    57025703 *
     
    57325733#  endif
    57335734# else
    5734     ASMAtomicXorU32(&((uint32_t volatile *)pvBitmap)[iBit / 32], RT_BIT_32(iBit & 31));
     5735    ASMAtomicXorU32(&((uint32_t volatile *)pvBitmap)[iBit / 32], RT_H2LE_U32(RT_BIT_32(iBit & 31)));
    57355736# endif
    57365737}
     
    57445745 * @returns false if the bit was clear.
    57455746 *
    5746  * @param   pvBitmap    Pointer to the bitmap.
     5747 * @param   pvBitmap    Pointer to the bitmap (little endian).
    57475748 * @param   iBit        The bit to test and set.
    57485749 *
     
    57915792    int32_t offBitmap = iBit / 32;
    57925793    AssertStmt(!((uintptr_t)pvBitmap & 3), offBitmap += (uintptr_t)pvBitmap & 3; iBit += ((uintptr_t)pvBitmap & 3) * 8);
    5793     rc.u32 = ASMAtomicUoOrExU32(&((uint32_t volatile *)pvBitmap)[offBitmap], RT_BIT_32(iBit & 31)) >> (iBit & 31);
     5794    rc.u32 = RT_LE2H_U32(ASMAtomicUoOrExU32(&((uint32_t volatile *)pvBitmap)[offBitmap], RT_H2LE_U32(RT_BIT_32(iBit & 31))))
     5795          >> (iBit & 31);
     5796    rc.u32 &= 1;
    57945797# endif
    57955798    return rc.f;
     
    58045807 * @returns false if the bit was clear.
    58055808 *
    5806  * @param   pvBitmap    Pointer to the bitmap. Must be 32-bit aligned, otherwise
    5807  *                      the memory access isn't atomic!
     5809 * @param   pvBitmap    Pointer to the bitmap (little endian).  Must be 32-bit
     5810 *                      aligned, otherwise the memory access isn't atomic!
    58085811 * @param   iBit        The bit to set.
    58095812 *
     
    58485851
    58495852# else
    5850     rc.u32 = ASMAtomicOrExU32(&((uint32_t volatile *)pvBitmap)[iBit / 32], RT_BIT_32(iBit & 31)) >> (iBit & 31);
     5853    rc.u32 = RT_LE2H_U32(ASMAtomicOrExU32(&((uint32_t volatile *)pvBitmap)[iBit / 32], RT_H2LE_U32(RT_BIT_32(iBit & 31))))
     5854          >> (iBit & 31);
     5855    rc.u32 &= 1;
    58515856# endif
    58525857    return rc.f;
     
    58615866 * @returns false if the bit was clear.
    58625867 *
    5863  * @param   pvBitmap    Pointer to the bitmap.
     5868 * @param   pvBitmap    Pointer to the bitmap (little endian).
    58645869 * @param   iBit        The bit to test and clear.
    58655870 *
     
    59085913    int32_t offBitmap = iBit / 32;
    59095914    AssertStmt(!((uintptr_t)pvBitmap & 3), offBitmap += (uintptr_t)pvBitmap & 3; iBit += ((uintptr_t)pvBitmap & 3) * 8);
    5910     rc.u32 = ASMAtomicUoAndExU32(&((uint32_t volatile *)pvBitmap)[offBitmap], ~RT_BIT_32(iBit & 31)) >> (iBit & 31);
     5915    rc.u32 = RT_LE2H_U32(ASMAtomicUoAndExU32(&((uint32_t volatile *)pvBitmap)[offBitmap], RT_H2LE_U32(~RT_BIT_32(iBit & 31))))
     5916          >> (iBit & 31);
     5917    rc.u32 &= 1;
    59115918# endif
    59125919    return rc.f;
     
    59215928 * @returns false if the bit was clear.
    59225929 *
    5923  * @param   pvBitmap    Pointer to the bitmap. Must be 32-bit aligned, otherwise
    5924  *                      the memory access isn't atomic!
     5930 * @param   pvBitmap    Pointer to the bitmap (little endian).  Must be 32-bit
     5931 *                      aligned, otherwise the memory access isn't atomic!
    59255932 * @param   iBit        The bit to test and clear.
    59265933 *
     
    59675974
    59685975# else
    5969     rc.u32 = ASMAtomicAndExU32(&((uint32_t volatile *)pvBitmap)[iBit / 32], ~RT_BIT_32(iBit & 31)) >> (iBit & 31);
     5976    rc.u32 = RT_LE2H_U32(ASMAtomicAndExU32(&((uint32_t volatile *)pvBitmap)[iBit / 32], RT_H2LE_U32(~RT_BIT_32(iBit & 31))))
     5977          >> (iBit & 31);
     5978    rc.u32 &= 1;
    59705979# endif
    59715980    return rc.f;
     
    59805989 * @returns false if the bit was clear.
    59815990 *
    5982  * @param   pvBitmap    Pointer to the bitmap.
     5991 * @param   pvBitmap    Pointer to the bitmap (little endian).
    59835992 * @param   iBit        The bit to test and toggle.
    59845993 *
     
    60276036    int32_t offBitmap = iBit / 32;
    60286037    AssertStmt(!((uintptr_t)pvBitmap & 3), offBitmap += (uintptr_t)pvBitmap & 3; iBit += ((uintptr_t)pvBitmap & 3) * 8);
    6029     rc.u32 = ASMAtomicUoXorExU32(&((uint32_t volatile *)pvBitmap)[offBitmap], RT_BIT_32(iBit & 31)) >> (iBit & 31);
     6038    rc.u32 = RT_LE2H_U32(ASMAtomicUoXorExU32(&((uint32_t volatile *)pvBitmap)[offBitmap], RT_H2LE_U32(RT_BIT_32(iBit & 31))))
     6039          >> (iBit & 31);
     6040    rc.u32 &= 1;
    60306041# endif
    60316042    return rc.f;
     
    60406051 * @returns false if the bit was clear.
    60416052 *
    6042  * @param   pvBitmap    Pointer to the bitmap. Must be 32-bit aligned, otherwise
    6043  *                      the memory access isn't atomic!
     6053 * @param   pvBitmap    Pointer to the bitmap (little endian).  Must be 32-bit
     6054 *                      aligned, otherwise the memory access isn't atomic!
    60446055 * @param   iBit        The bit to test and toggle.
    60456056 *
     
    60826093
    60836094# else
    6084     rc.u32 = ASMAtomicXorExU32(&((uint32_t volatile *)pvBitmap)[iBit / 32], RT_BIT_32(iBit & 31)) >> (iBit & 31);
     6095    rc.u32 = RT_H2LE_U32(ASMAtomicXorExU32(&((uint32_t volatile *)pvBitmap)[iBit / 32], RT_LE2H_U32(RT_BIT_32(iBit & 31))))
     6096          >> (iBit & 31);
     6097    rc.u32 &= 1;
    60856098# endif
    60866099    return rc.f;
     
    60956108 * @returns false if the bit is clear.
    60966109 *
    6097  * @param   pvBitmap    Pointer to the bitmap.
     6110 * @param   pvBitmap    Pointer to the bitmap (little endian).
    60986111 * @param   iBit        The bit to test.
    60996112 *
     
    61426155    int32_t offBitmap = iBit / 32;
    61436156    AssertStmt(!((uintptr_t)pvBitmap & 3), offBitmap += (uintptr_t)pvBitmap & 3; iBit += ((uintptr_t)pvBitmap & 3) * 8);
    6144     rc.u32 = ASMAtomicUoReadU32(&((uint32_t volatile *)pvBitmap)[offBitmap]) >> (iBit & 31);
     6157    rc.u32 = RT_LE2H_U32(ASMAtomicUoReadU32(&((uint32_t volatile *)pvBitmap)[offBitmap])) >> (iBit & 31);
     6158    rc.u32 &= 1;
    61456159# endif
    61466160    return rc.f;
     
    61526166 * Clears a bit range within a bitmap.
    61536167 *
    6154  * @param   pvBitmap    Pointer to the bitmap.
     6168 * @param   pvBitmap    Pointer to the bitmap (little endian).
    61556169 * @param   iBitStart   The First bit to clear.
    61566170 * @param   iBitEnd     The first bit not to clear.
     
    61646178        int32_t iEnd   = iBitEnd & ~31;
    61656179        if (iStart == iEnd)
    6166             *pu32 &= ((UINT32_C(1) << (iBitStart & 31)) - 1) | ~((UINT32_C(1) << (iBitEnd & 31)) - 1);
     6180            *pu32 &= RT_H2LE_U32(((UINT32_C(1) << (iBitStart & 31)) - 1) | ~((UINT32_C(1) << (iBitEnd & 31)) - 1));
    61676181        else
    61686182        {
     
    61706184            if (iBitStart & 31)
    61716185            {
    6172                 *pu32 &= (UINT32_C(1) << (iBitStart & 31)) - 1;
     6186                *pu32 &= RT_H2LE_U32((UINT32_C(1) << (iBitStart & 31)) - 1);
    61736187                pu32++;
    61746188                iBitStart = iStart + 32;
     
    61836197            {
    61846198                pu32 = (volatile uint32_t *)pvBitmap + (iBitEnd >> 5);
    6185                 *pu32 &= ~((UINT32_C(1) << (iBitEnd & 31)) - 1);
     6199                *pu32 &= RT_H2LE_U32(~((UINT32_C(1) << (iBitEnd & 31)) - 1));
    61866200            }
    61876201        }
     
    61936207 * Sets a bit range within a bitmap.
    61946208 *
    6195  * @param   pvBitmap    Pointer to the bitmap.
     6209 * @param   pvBitmap    Pointer to the bitmap (little endian).
    61966210 * @param   iBitStart   The First bit to set.
    61976211 * @param   iBitEnd     The first bit not to set.
     
    62056219        int32_t iEnd   = iBitEnd & ~31;
    62066220        if (iStart == iEnd)
    6207             *pu32 |= ((UINT32_C(1) << (iBitEnd - iBitStart)) - 1) << (iBitStart & 31);
     6221            *pu32 |= RT_H2LE_U32(((UINT32_C(1) << (iBitEnd - iBitStart)) - 1) << (iBitStart & 31));
    62086222        else
    62096223        {
     
    62116225            if (iBitStart & 31)
    62126226            {
    6213                 *pu32 |= ~((UINT32_C(1) << (iBitStart & 31)) - 1);
     6227                *pu32 |= RT_H2LE_U32(~((UINT32_C(1) << (iBitStart & 31)) - 1));
    62146228                pu32++;
    62156229                iBitStart = iStart + 32;
     
    62236237            if (iBitEnd & 31)
    62246238            {
    6225                 pu32 = (volatile uint32_t RT_FAR *)pvBitmap + (iBitEnd >> 5);
     6239                pu32 = RT_H2LE_U32((volatile uint32_t RT_FAR *)pvBitmap + (iBitEnd >> 5));
    62266240                *pu32 |= (UINT32_C(1) << (iBitEnd & 31)) - 1;
    62276241            }
     
    62366250 * @returns Index of the first zero bit.
    62376251 * @returns -1 if no clear bit was found.
    6238  * @param   pvBitmap    Pointer to the bitmap.
     6252 * @param   pvBitmap    Pointer to the bitmap (little endian).
    62396253 * @param   cBits       The number of bits in the bitmap. Multiple of 32.
    62406254 */
    6241 #if RT_INLINE_ASM_EXTERNAL
     6255#if RT_INLINE_ASM_EXTERNAL || (!defined(RT_ARCH_AMD64) && !defined(RT_ARCH_X86))
    62426256DECLASM(int32_t) ASMBitFirstClear(const volatile void RT_FAR *pvBitmap, uint32_t cBits) RT_NOTHROW_PROTO;
    62436257#else
     
    63216335 * @returns Index of the first zero bit.
    63226336 * @returns -1 if no clear bit was found.
    6323  * @param   pvBitmap    Pointer to the bitmap.
     6337 * @param   pvBitmap    Pointer to the bitmap (little endian).
    63246338 * @param   cBits       The number of bits in the bitmap. Multiple of 32.
    63256339 * @param   iBitPrev    The bit returned from the last search.
    63266340 *                      The search will start at iBitPrev + 1.
    63276341 */
    6328 #if RT_INLINE_ASM_EXTERNAL
     6342#if RT_INLINE_ASM_EXTERNAL || (!defined(RT_ARCH_AMD64) && !defined(RT_ARCH_X86))
    63296343DECLASM(int) ASMBitNextClear(const volatile void RT_FAR *pvBitmap, uint32_t cBits, uint32_t iBitPrev) RT_NOTHROW_PROTO;
    63306344#else
     
    63936407 * @returns Index of the first set bit.
    63946408 * @returns -1 if no clear bit was found.
    6395  * @param   pvBitmap    Pointer to the bitmap.
     6409 * @param   pvBitmap    Pointer to the bitmap (little endian).
    63966410 * @param   cBits       The number of bits in the bitmap. Multiple of 32.
    63976411 */
    6398 #if RT_INLINE_ASM_EXTERNAL
     6412#if RT_INLINE_ASM_EXTERNAL || (!defined(RT_ARCH_AMD64) && !defined(RT_ARCH_X86))
    63996413DECLASM(int32_t) ASMBitFirstSet(const volatile void RT_FAR *pvBitmap, uint32_t cBits) RT_NOTHROW_PROTO;
    64006414#else
     
    64776491 * @returns Index of the next set bit.
    64786492 * @returns -1 if no set bit was found.
    6479  * @param   pvBitmap    Pointer to the bitmap.
     6493 * @param   pvBitmap    Pointer to the bitmap (little endian).
    64806494 * @param   cBits       The number of bits in the bitmap. Multiple of 32.
    64816495 * @param   iBitPrev    The bit returned from the last search.
    64826496 *                      The search will start at iBitPrev + 1.
    64836497 */
    6484 #if RT_INLINE_ASM_EXTERNAL
     6498#if RT_INLINE_ASM_EXTERNAL || (!defined(RT_ARCH_AMD64) && !defined(RT_ARCH_X86))
    64856499DECLASM(int) ASMBitNextSet(const volatile void RT_FAR *pvBitmap, uint32_t cBits, uint32_t iBitPrev) RT_NOTHROW_PROTO;
    64866500#else
  • trunk/src/VBox/Runtime/Makefile.kmk

    r87187 r87192  
    768768        common/string/RTStrMemFind32.asm
    769769RuntimeR3_SOURCES.arm32 := \
     770        common/asm/ASMBitFirstClear-generic.cpp \
    770771        common/asm/ASMMemZeroPage-generic.cpp \
    771772        common/asm/ASMMemZero32-generic.cpp \
     
    775776        common/misc/zero-alt.S
    776777RuntimeR3_SOURCES.arm64 := \
     778        common/asm/ASMBitFirstClear-generic.cpp \
    777779        common/asm/ASMMemZeroPage-generic.cpp \
    778780        common/asm/ASMMemZero32-generic.cpp \
     
    784786        generic/RTMpGetDescription-generic-stub.cpp \
    785787        generic/RTSystemIsInsideVM-generic.cpp \
     788        common/asm/ASMBitFirstClear-generic.cpp \
    786789        common/asm/ASMMemZeroPage-generic.cpp \
    787790        common/asm/ASMMemZero32-generic.cpp \
     
    795798        generic/RTMpGetDescription-generic-stub.cpp \
    796799        generic/RTSystemIsInsideVM-generic.cpp \
     800        common/asm/ASMBitFirstClear-generic.cpp \
     801        common/asm/ASMMemZeroPage-generic.cpp \
     802        common/asm/ASMMemZero32-generic.cpp \
     803        common/asm/ASMMemFill32-generic.cpp \
     804        common/asm/ASMMemFirstMismatchingU8-generic.cpp \
     805        common/asm/ASMMemFirstNonZero-generic.cpp \
    797806        common/asm/asm-fake.cpp \
    798807        common/misc/zero-alt.S \
  • 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.

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