VirtualBox

Changeset 10939 in vbox for trunk/include


Ignore:
Timestamp:
Jul 29, 2008 4:31:29 PM (17 years ago)
Author:
vboxsync
Message:

iprt/asm.h: Added a bunch of atomic operations for IPRT handles (finally). ASMAtomicXchgSize is busted, added a temporary ASMAtomicXchgSizeCorrect.

File:
1 edited

Legend:

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

    r9581 r10939  
    22752275
    22762276/**
     2277 * Atomically Exchange a pointer value, ordered.
     2278 *
     2279 * @returns Current *ppv value
     2280 * @param   ppv    Pointer to the pointer variable to update.
     2281 * @param   pv     The pointer value to assign to *ppv.
     2282 */
     2283DECLINLINE(void *) ASMAtomicXchgPtr(void * volatile *ppv, void *pv)
     2284{
     2285#if ARCH_BITS == 32
     2286    return (void *)ASMAtomicXchgU32((volatile uint32_t *)(void *)ppv, (uint32_t)pv);
     2287#elif ARCH_BITS == 64
     2288    return (void *)ASMAtomicXchgU64((volatile uint64_t *)(void *)ppv, (uint64_t)pv);
     2289#else
     2290# error "ARCH_BITS is bogus"
     2291#endif
     2292}
     2293
     2294
     2295/** @def ASMAtomicXchgHandle
     2296 * Atomically Exchange a typical IPRT handle value, ordered.
     2297 *
     2298 * @param   ph          Pointer to the value to update.
     2299 * @param   hNew        The new value to assigned to *pu.
     2300 * @param   phRes       Where to store the current *ph value.
     2301 *
     2302 * @remarks This doesn't currently work for all handles (like RTFILE).
     2303 */
     2304#define ASMAtomicXchgHandle(ph, hNew, phRes) \
     2305    do { \
     2306        *(void **)(phRes) = ASMAtomicXchgPtr((void * volatile *)(ph), (void *)(hNew)); \
     2307        AssertCompile(sizeof(*ph) == sizeof(void *)); \
     2308        AssertCompile(sizeof(*phRes) == sizeof(void *)); \
     2309    } while (0)
     2310
     2311
     2312/**
    22772313 * Atomically Exchange a value which size might differ
    22782314 * between platforms or compilers, ordered.
     
    22802316 * @param   pu      Pointer to the variable to update.
    22812317 * @param   uNew    The value to assign to *pu.
     2318 * @todo This is busted as its missing the result argument.
    22822319 */
    22832320#define ASMAtomicXchgSize(pu, uNew) \
     
    22922329    } while (0)
    22932330
    2294 
    2295 /**
    2296  * Atomically Exchange a pointer value, ordered.
    2297  *
    2298  * @returns Current *ppv value
    2299  * @param   ppv    Pointer to the pointer variable to update.
    2300  * @param   pv     The pointer value to assign to *ppv.
    2301  */
    2302 DECLINLINE(void *) ASMAtomicXchgPtr(void * volatile *ppv, void *pv)
    2303 {
    2304 #if ARCH_BITS == 32
    2305     return (void *)ASMAtomicXchgU32((volatile uint32_t *)(void *)ppv, (uint32_t)pv);
    2306 #elif ARCH_BITS == 64
    2307     return (void *)ASMAtomicXchgU64((volatile uint64_t *)(void *)ppv, (uint64_t)pv);
    2308 #else
    2309 # error "ARCH_BITS is bogus"
    2310 #endif
    2311 }
     2331/**
     2332 * Atomically Exchange a value which size might differ
     2333 * between platforms or compilers, ordered.
     2334 *
     2335 * @param   pu      Pointer to the variable to update.
     2336 * @param   uNew    The value to assign to *pu.
     2337 * @param   puRes   Where to store the current *pu value.
     2338 */
     2339#define ASMAtomicXchgSizeCorrect(pu, uNew, puRes) \
     2340    do { \
     2341        switch (sizeof(*(pu))) { \
     2342            case 1: *(uint8_t  *)(puRes) = ASMAtomicXchgU8((volatile uint8_t *)(void *)(pu), (uint8_t)(uNew)); break; \
     2343            case 2: *(uint16_t *)(puRes) = ASMAtomicXchgU16((volatile uint16_t *)(void *)(pu), (uint16_t)(uNew)); break; \
     2344            case 4: *(uint32_t *)(puRes) = ASMAtomicXchgU32((volatile uint32_t *)(void *)(pu), (uint32_t)(uNew)); break; \
     2345            case 8: *(uint64_t *)(puRes) = ASMAtomicXchgU64((volatile uint64_t *)(void *)(pu), (uint64_t)(uNew)); break; \
     2346            default: AssertMsgFailed(("ASMAtomicXchgSize: size %d is not supported\n", sizeof(*(pu)))); \
     2347        } \
     2348    } while (0)
    23122349
    23132350
     
    24922529
    24932530
     2531/**
     2532 * Atomically Compare and Exchange a pointer value, ordered.
     2533 *
     2534 * @returns true if xchg was done.
     2535 * @returns false if xchg wasn't done.
     2536 *
     2537 * @param   ppv         Pointer to the value to update.
     2538 * @param   pvNew       The new value to assigned to *ppv.
     2539 * @param   pvOld       The old value to *ppv compare with.
     2540 */
     2541DECLINLINE(bool) ASMAtomicCmpXchgPtr(void * volatile *ppv, void *pvNew, void *pvOld)
     2542{
     2543#if ARCH_BITS == 32
     2544    return ASMAtomicCmpXchgU32((volatile uint32_t *)(void *)ppv, (uint32_t)pvNew, (uint32_t)pvOld);
     2545#elif ARCH_BITS == 64
     2546    return ASMAtomicCmpXchgU64((volatile uint64_t *)(void *)ppv, (uint64_t)pvNew, (uint64_t)pvOld);
     2547#else
     2548# error "ARCH_BITS is bogus"
     2549#endif
     2550}
     2551
     2552
     2553/** @def ASMAtomicCmpXchgHandle
     2554 * Atomically Compare and Exchange a typical IPRT handle value, ordered.
     2555 *
     2556 * @param   ph          Pointer to the value to update.
     2557 * @param   hNew        The new value to assigned to *pu.
     2558 * @param   hOld        The old value to *pu compare with.
     2559 * @param   fRc         Where to store the result.
     2560 *
     2561 * @remarks This doesn't currently work for all handles (like RTFILE).
     2562 */
     2563#define ASMAtomicCmpXchgHandle(ph, hNew, hOld, fRc) \
     2564    do { \
     2565        (fRc) = ASMAtomicCmpXchgPtr((void * volatile *)(ph), (void *)(hNew), (void *)(hOld)); \
     2566        AssertCompile(sizeof(*ph) == sizeof(void *)); \
     2567    } while (0)
     2568
     2569
    24942570/** @def ASMAtomicCmpXchgSize
    24952571 * Atomically Compare and Exchange a value which size might differ
     
    25132589        } \
    25142590    } while (0)
    2515 
    2516 
    2517 /**
    2518  * Atomically Compare and Exchange a pointer value, ordered.
    2519  *
    2520  * @returns true if xchg was done.
    2521  * @returns false if xchg wasn't done.
    2522  *
    2523  * @param   ppv         Pointer to the value to update.
    2524  * @param   pvNew       The new value to assigned to *ppv.
    2525  * @param   pvOld       The old value to *ppv compare with.
    2526  */
    2527 DECLINLINE(bool) ASMAtomicCmpXchgPtr(void * volatile *ppv, void *pvNew, void *pvOld)
    2528 {
    2529 #if ARCH_BITS == 32
    2530     return ASMAtomicCmpXchgU32((volatile uint32_t *)(void *)ppv, (uint32_t)pvNew, (uint32_t)pvOld);
    2531 #elif ARCH_BITS == 64
    2532     return ASMAtomicCmpXchgU64((volatile uint64_t *)(void *)ppv, (uint64_t)pvNew, (uint64_t)pvOld);
    2533 #else
    2534 # error "ARCH_BITS is bogus"
    2535 #endif
    2536 }
    25372591
    25382592
     
    27322786}
    27332787
     2788/** @def ASMAtomicCmpXchgExHandle
     2789 * Atomically Compare and Exchange a typical IPRT handle value, ordered.
     2790 *
     2791 * @param   ph          Pointer to the value to update.
     2792 * @param   hNew        The new value to assigned to *pu.
     2793 * @param   hOld        The old value to *pu compare with.
     2794 * @param   fRc         Where to store the result.
     2795 * @param   phOldVal    Pointer to where to store the old value.
     2796 *
     2797 * @remarks This doesn't currently work for all handles (like RTFILE).
     2798 */
     2799#if ARCH_BITS == 32
     2800# define ASMAtomicCmpXchgExHandle(ph, hNew, hOld, fRc, phOldVal) \
     2801    do { \
     2802        (fRc) = ASMAtomicCmpXchgExU32((volatile uint32_t *)(void *)(pu), (uint32_t)(uNew), (uint32_t)(uOld), (uint32_t *)(puOldVal)); \
     2803        AssertCompile(sizeof(*ph) == sizeof(void *)); \
     2804        AssertCompile(sizeof(*phOldVal) == sizeof(void *)); \
     2805    } while (0)
     2806#elif ARCH_BITS == 64
     2807# define ASMAtomicCmpXchgExHandle(ph, hNew, hOld, fRc, phOldVal) \
     2808    do { \
     2809        (fRc) = ASMAtomicCmpXchgExU64((volatile uint64_t *)(void *)(pu), (uint64_t)(uNew), (uint64_t)(uOld), (uint64_t *)(puOldVal)); \
     2810        AssertCompile(sizeof(*ph) == sizeof(void *)); \
     2811        AssertCompile(sizeof(*phOldVal) == sizeof(void *)); \
     2812    } while (0)
     2813#endif
     2814
    27342815
    27352816/** @def ASMAtomicCmpXchgExSize
     
    27412822 * @param   uOld        The old value to *pu compare with.
    27422823 * @param   fRc         Where to store the result.
    2743  * @param   uOldVal     Where to store the old value.
    2744  */
    2745 #define ASMAtomicCmpXchgExSize(pu, uNew, uOld, fRc, uOldVal) \
     2824 * @param   puOldVal    Pointer to where to store the old value.
     2825 */
     2826#define ASMAtomicCmpXchgExSize(pu, uNew, uOld, fRc, puOldVal) \
    27462827    do { \
    27472828        switch (sizeof(*(pu))) { \
    2748             case 4: (fRc) = ASMAtomicCmpXchgExU32((volatile uint32_t *)(void *)(pu), (uint32_t)(uNew), (uint32_t)(uOld), (uint32_t *)&(uOldVal)); \
     2829            case 4: (fRc) = ASMAtomicCmpXchgExU32((volatile uint32_t *)(void *)(pu), (uint32_t)(uNew), (uint32_t)(uOld), (uint32_t *)(uOldVal)); \
    27492830                break; \
    2750             case 8: (fRc) = ASMAtomicCmpXchgExU64((volatile uint64_t *)(void *)(pu), (uint64_t)(uNew), (uint64_t)(uOld), (uint64_t *)&(uOldVal)); \
     2831            case 8: (fRc) = ASMAtomicCmpXchgExU64((volatile uint64_t *)(void *)(pu), (uint64_t)(uNew), (uint64_t)(uOld), (uint64_t *)(uOldVal)); \
    27512832                break; \
    27522833            default: AssertMsgFailed(("ASMAtomicCmpXchgSize: size %d is not supported\n", sizeof(*(pu)))); \
     
    34603541
    34613542/**
     3543 * Atomically read a typical IPRT handle value, ordered.
     3544 *
     3545 * @param   ph      Pointer to the handle variable to read.
     3546 * @param   phRes   Where to store the result.
     3547 *
     3548 * @remarks This doesn't currently work for all handles (like RTFILE).
     3549 */
     3550#define ASMAtomicReadHandle(ph, phRes) \
     3551    do { \
     3552        *(void **)(phRes) = ASMAtomicReadPtr((void * volatile *)(ph)); \
     3553        AssertCompile(sizeof(*ph) == sizeof(void *)); \
     3554        AssertCompile(sizeof(*phRes) == sizeof(void *)); \
     3555    } while (0)
     3556
     3557
     3558/**
     3559 * Atomically read a typical IPRT handle value, unordered.
     3560 *
     3561 * @param   ph      Pointer to the handle variable to read.
     3562 * @param   phRes   Where to store the result.
     3563 *
     3564 * @remarks This doesn't currently work for all handles (like RTFILE).
     3565 */
     3566#define ASMAtomicUoReadHandle(ph, phRes) \
     3567    do { \
     3568        *(void **)(phRes) = ASMAtomicUoReadPtr((void * volatile *)(ph)); \
     3569        AssertCompile(sizeof(*ph) == sizeof(void *)); \
     3570        AssertCompile(sizeof(*phRes) == sizeof(void *)); \
     3571    } while (0)
     3572
     3573
     3574/**
    34623575 * Atomically read a value which size might differ
    34633576 * between platforms or compilers, ordered.
     
    37633876#endif
    37643877}
     3878
     3879
     3880/**
     3881 * Atomically write a typical IPRT handle value, ordered.
     3882 *
     3883 * @param   ph      Pointer to the variable to update.
     3884 * @param   hNew    The value to assign to *ph.
     3885 *
     3886 * @remarks This doesn't currently work for all handles (like RTFILE).
     3887 */
     3888#define ASMAtomicWriteHandle(ph, hNew) \
     3889    do { \
     3890        ASMAtomicWritePtr((void * volatile *)(ph), (void *)hNew); \
     3891        AssertCompile(sizeof(*ph) == sizeof(void*)); \
     3892    } while (0)
     3893
     3894
     3895/**
     3896 * Atomically write a typical IPRT handle value, unordered.
     3897 *
     3898 * @param   ph      Pointer to the variable to update.
     3899 * @param   hNew    The value to assign to *ph.
     3900 *
     3901 * @remarks This doesn't currently work for all handles (like RTFILE).
     3902 */
     3903#define ASMAtomicUoWriteHandle(ph, hNew) \
     3904    do { \
     3905        ASMAtomicUoWritePtr((void * volatile *)(ph), (void *)hNew); \
     3906        AssertCompile(sizeof(*ph) == sizeof(void*)); \
     3907    } while (0)
    37653908
    37663909
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