⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 atomicbase.h

📁 linux下的一款播放器
💻 H
📖 第 1 页 / 共 4 页
字号:
        : "=c" (ulRet)        : "a" (pNum), "b" (ulNum), "c" (0)        : "cc", "memory"        );    return ulRet;}static __inline__ void HXAtomicIncINT32(INT32* p)              { HXAtomicIncUINT32((UINT32*)p); }static __inline__ void HXAtomicDecINT32(INT32* p)              { HXAtomicDecUINT32((UINT32*)p); }static __inline__ void HXAtomicAddINT32(INT32* p, INT32 n)     { HXAtomicAddUINT32((UINT32*)p, (UINT32)n); }static __inline__ void HXAtomicSubINT32(INT32* p, INT32 n)     { HXAtomicSubUINT32((UINT32*)p, (UINT32)n); }static __inline__ INT32 HXAtomicIncRetINT32(INT32* p)          { return HXAtomicIncRetUINT32((UINT32*)p); }static __inline__ INT32 HXAtomicDecRetINT32(INT32* p)          { return HXAtomicDecRetUINT32((UINT32*)p); }static __inline__ INT32 HXAtomicAddRetINT32(INT32* p, INT32 n) { return HXAtomicAddRetUINT32((UINT32*)p, (UINT32)n); }static __inline__ INT32 HXAtomicSubRetINT32(INT32* p, INT32 n) { return HXAtomicSubRetUINT32((UINT32*)p, (UINT32)n); }/*********************************************************************** * HP-UX / IA64 (Native compiler) * * Implementation Notes: *      A work-in-progress... */#elif defined(_HPUX) && defined(_IA64)#if defined(__cplusplus)extern "C" {#endif    UINT32 _HXAtomicIncRetUINT32 (UINT32* pNum);    UINT32 _HXAtomicDecRetUINT32 (UINT32* pNum);    UINT32 _HXAtomicAddRetUINT32 (UINT32* pNum, UINT32 ulNum);    UINT32 _HXAtomicSubRetUINT32 (UINT32* pNum, UINT32 ulNum);#if defined(__cplusplus)}#endif#define HXAtomicIncINT32(p)       _HXAtomicIncRetUINT32((UINT32*)(p))#define HXAtomicDecINT32(p)       _HXAtomicDecRetUINT32((UINT32*)(p))#define HXAtomicIncRetINT32(p)    _HXAtomicIncRetUINT32((UINT32*)(p))#define HXAtomicDecRetINT32(p)    _HXAtomicDecRetUINT32((UINT32*)(p))#define HXAtomicAddINT32(p,n)     _HXAtomicAddRetUINT32((UINT32*)(p),(INT32)(n))#define HXAtomicSubINT32(p,n)     _HXAtomicSubRetUINT32((UINT32*)(p),(INT32)(n))#define HXAtomicAddRetINT32(p,n)  _HXAtomicAddRetUINT32((UINT32*)(p),(INT32)(n))#define HXAtomicSubRetINT32(p,n)  _HXAtomicSubRetUINT32((UINT32*)(p),(INT32)(n))#define HXAtomicIncUINT32(p)      _HXAtomicIncRetUINT32((p))#define HXAtomicDecUINT32(p)      _HXAtomicDecRetUINT32((p))#define HXAtomicIncRetUINT32(p)   _HXAtomicIncRetUINT32((p))#define HXAtomicDecRetUINT32(p)   _HXAtomicDecRetUINT32((p))#define HXAtomicAddUINT32(p,n)    _HXAtomicAddRetUINT32((p),(n))#define HXAtomicSubUINT32(p,n)    _HXAtomicSubRetUINT32((p),(n))#define HXAtomicAddRetUINT32(p,n) _HXAtomicAddRetUINT32((p),(n))#define HXAtomicSubRetUINT32(p,n) _HXAtomicSubRetUINT32((p),(n))/*********************************************************************** * Tru64 (OSF1) / Alpha (Native compiler) * * Implementation Notes: * * The Alpha CPU provides instructions to load-lock a value, * modify it, and attempt to write it back.  If the value has * been modified by someone else since the load-lock occured, * the write will fail and you can check the status code to * know whether you need to retry or not. * */#elif defined (__alpha)#include <c_asm.h>/* Increment by 1 and return new value */inline INT32HXAtomicIncRetINT32(INT32* pNum){    return asm (        "10:     ldl_l   %t0, (%a0);"       // Load-lock value into a register        "        addl    %t0, 1, %t0;"      // Increment value        "        or      %t0, %zero, %v0;"  // set new value for return.        "        stl_c   %t0, (%a0);"       // Save new value into *pNum        "        beq     %t0, 10b;"         // Retry if sequence failed        , pNum);}/* Decrement by 1 and return new value */inline INT32HXAtomicDecRetINT32(INT32* pNum){    return asm (        "10:     ldl_l   %t0, (%a0);"       // Load-lock value into a register        "        subl    %t0, 1, %t0;"      // Decrement value        "        or      %t0, %zero, %v0;"  // set new value for return.        "        stl_c   %t0, (%a0);"       // Save new value into *pNum        "        beq     %t0, 10b;"         // Retry if sequence failed        , pNum);}/* Add n and return new value */inline INT32HXAtomicAddRetINT32(INT32* pNum, INT32 n){    return asm (        "10:     ldl_l   %t0, (%a0);"       // Load-lock value into a register        "        addl    %t0, %a1, %t0;"    // Add n to value        "        or      %t0, %zero, %v0;"  // set new value for return.        "        stl_c   %t0, (%a0);"       // Save new value into *pNum        "        beq     %t0, 10b;"         // Retry if sequence failed        , pNum, n);}/* Subtract n and return new value */inline INT32HXAtomicSubRetINT32(INT32* pNum, INT32 n){    return asm (        "10:     ldl_l   %t0, (%a0);"       // Load-lock value into a register        "        subl    %t0, %a1, %t0;"    // Subtract n from value        "        or      %t0, %zero, %v0;"  // set new value for return.        "        stl_c   %t0, (%a0);"       // Save new value into *pNum        "        beq     %t0, 10b;"         // Retry if sequence failed        , pNum, n);}/* Increment by 1 and return new value */inline UINT32HXAtomicIncRetUINT32(UINT32* pNum){    return asm (        "10:     ldl_l   %t0, (%a0);"       // Load-lock value into a register        "        addl    %t0, 1, %t0;"      // Increment value        "        or      %t0, %zero, %v0;"  // set new value for return.        "        stl_c   %t0, (%a0);"       // Save new value into *pNum        "        beq     %t0, 10b;"         // Retry if sequence failed        , pNum);}/* Decrement by 1 and return new value */inline UINT32HXAtomicDecRetUINT32(UINT32* pNum){    return asm (        "10:     ldl_l   %t0, (%a0);"       // Load-lock value into a register        "        subl    %t0, 1, %t0;"      // Decrement value        "        or      %t0, %zero, %v0;"  // set new value for return.        "        stl_c   %t0, (%a0);"       // Save new value into *pNum        "        beq     %t0, 10b;"         // Retry if sequence failed        , pNum);}/* Add n and return new value */inline UINT32HXAtomicAddRetUINT32(UINT32* pNum, UINT32 n){    return asm (        "10:     ldl_l   %t0, (%a0);"       // Load-lock value into a register        "        addl    %t0, %a1, %t0;"    // Add n to value        "        or      %t0, %zero, %v0;"  // set new value for return.        "        stl_c   %t0, (%a0);"       // Save new value into *pNum        "        beq     %t0, 10b;"         // Retry if sequence failed        , pNum, n);}/* Subtract n and return new value */inline UINT32HXAtomicSubRetUINT32(UINT32* pNum, UINT32 n){    return asm (        "10:     ldl_l   %t0, (%a0);"       // Load-lock value into a register        "        subl    %t0, %a1, %t0;"    // Subtract n from value        "        or      %t0, %zero, %v0;"  // set new value for return.        "        stl_c   %t0, (%a0);"       // Save new value into *pNum        "        beq     %t0, 10b;"         // Retry if sequence failed        , pNum, n);}#define HXAtomicIncINT32(p)    HXAtomicIncRetINT32((p))#define HXAtomicDecINT32(p)    HXAtomicDecRetINT32((p))#define HXAtomicAddINT32(p,n)  HXAtomicAddRetINT32((p),(n))#define HXAtomicSubINT32(p,n)  HXAtomicSubRetINT32((p),(n))#define HXAtomicIncUINT32(p)   HXAtomicIncRetUINT32((p))#define HXAtomicDecUINT32(p)   HXAtomicDecRetUINT32((p))#define HXAtomicAddUINT32(p,n) HXAtomicAddRetUINT32((p),(n))#define HXAtomicSubUINT32(p,n) HXAtomicSubRetUINT32((p),(n))/*********************************************************************** * AIX / PowerPC (Native compiler) * * Implementation Notes: * * XXXDC: The xlc compiler is able to do inline asm for C but when I do * it for C++ it crashes, so for now I have resorted to putting * the asm in a seperate assembler routine.  The way you inline with * xlc/xlC is difficult to use, requiring the use of "#pragma mc_func". */#elif defined (_AIX)//defined in common/util/platform/aix/atomicops.s#if defined(__cplusplus)extern "C" {#endif    INT32 _HXAtomicAddRetINT32   (INT32*  pNum, INT32  lNum);    INT32 _HXAtomicSubRetINT32   (INT32*  pNum, INT32  lNum);    UINT32 _HXAtomicAddRetUINT32 (UINT32* pNum, UINT32 ulNum);    UINT32 _HXAtomicSubRetUINT32 (UINT32* pNum, UINT32 ulNum);#if defined(__cplusplus)}#endif#define HXAtomicIncINT32(p)       _HXAtomicAddRetINT32((p),(INT32)1)#define HXAtomicDecINT32(p)       _HXAtomicSubRetINT32((p),(INT32)1)#define HXAtomicIncRetINT32(p)    _HXAtomicAddRetINT32((p),(INT32)1)#define HXAtomicDecRetINT32(p)    _HXAtomicSubRetINT32((p),(INT32)1)#define HXAtomicAddINT32(p,n)     _HXAtomicAddRetINT32((p),(n))#define HXAtomicSubINT32(p,n)     _HXAtomicSubRetINT32((p),(n))#define HXAtomicAddRetINT32(p,n)  _HXAtomicAddRetINT32((p),(n))#define HXAtomicSubRetINT32(p,n)  _HXAtomicSubRetINT32((p),(n))#define HXAtomicIncUINT32(p)      _HXAtomicAddRetUINT32((p),(UINT32)1)#define HXAtomicDecUINT32(p)      _HXAtomicSubRetUINT32((p),(UINT32)1)#define HXAtomicIncRetUINT32(p)   _HXAtomicAddRetUINT32((p),(UINT32)1)#define HXAtomicDecRetUINT32(p)   _HXAtomicSubRetUINT32((p),(UINT32)1)#define HXAtomicAddUINT32(p,n)    _HXAtomicAddRetUINT32((p),(n))#define HXAtomicSubUINT32(p,n)    _HXAtomicSubRetUINT32((p),(n))#define HXAtomicAddRetUINT32(p,n) _HXAtomicAddRetUINT32((p),(n))#define HXAtomicSubRetUINT32(p,n) _HXAtomicSubRetUINT32((p),(n))/*********************************************************************** * MAC / PowerPC (CW) * * Implementation Notes: * * This will need to be rewritten, probably, once we move away from CW to PB. * * Note: This is an imcompletely-defined platform, be aware that * not all standard HXAtomic operators are defined! * */#elif defined(_MACINTOSH) && defined(__MWERKS__)inline UINT32HXAtomicIncRetUINT32(register UINT32* pNum){    register UINT32 zeroOffset = 0;    register UINT32 temp;    asm    {	again:	    lwarx temp, zeroOffset, pNum	    addi temp, temp, 1	    stwcx. temp, zeroOffset, pNum	    bne- again    }    return temp;}inline UINT32HXAtomicDecRetUINT32(register UINT32* pNum){    register UINT32 zeroOffset = 0;    register UINT32 temp;    asm    {	again:	    lwarx temp, zeroOffset, pNum	    subi temp, temp, 1	    stwcx. temp, zeroOffset, pNum	    bne- again    }    return temp;}/*********************************************************************** * MAC / PowerPC (PB) * * Implementation Notes: * * Use the atomic operations exposed by DriverSynchronization.h * * Note: This is an imcompletely-defined platform, be aware that * not all standard HXAtomic operators are defined! * */#elif defined(_MACINTOSH) || defined(_MAC_UNIX)inline UINT32HXAtomicIncRetUINT32(UINT32* pNum){    return (UINT32)(IncrementAtomic((SInt32*)pNum) + 1);}inline UINT32HXAtomicDecRetUINT32(UINT32* pNum){    return (UINT32)(DecrementAtomic((SInt32*)pNum) - 1);}/*********************************************************************** * Linux / PowerPC * * Implementation Notes: * * Use PowerPC load exclusive and store exclusive instructions * */#elif defined(_LINUX) && defined(__powerpc__)static inline UINT32HXAtomicIncRetUINT32(UINT32* pNum){    volatile UINT32 result;	__asm__ __volatile__ ("1:      lwarx  %0, %3, %2;\n""        addi   %0, %0, 1;\n""        stwcx. %0, %3, %2;\n""        bne- 1b;"         : "=b" (result)         : "0" (result), "b" (pNum), "b" (0x0)         : "cc", "memory"		 );		return result;}static inline UINT32HXAtomicDecRetUINT32(UINT32* pNum){    volatile UINT32 result;	__asm__ __volatile__ ("1:      lwarx  %0, %3, %2;\n""        subi   %0, %0, 1;\n""        stwcx. %0, %3, %2;\n""        bne- 1b;"         : "=b" (result)         : "0" (result), "b" (pNum), "b" (0x0)         : "cc", "memory"         );		return result;}/*********************************************************************** * Generic * * Implementation Notes: * * This should work on any platform with a HXMutex-style mutex. * It allocates a pool of mutexes and hashes the int pointers * to one of the mutexes.  Since the mutexes are held for * such a short time, only long enough to increment an int, * collisions should be extremely rare and this should work fine, * although it is probably less fast than the extra-high-performance * atomic operators provided above.  You need to link in atomic.cpp * to get HXAtomic::m_pLocks defined. * * Basic design of the mutex-based lock-pool implementation: *   At startup, allocate an array of N mutexes (where N is a power of 2). *   When a method is called, hash the int pointer to one of the locks. *   Lock this mutex. *   Modify the value. *   Unlock this mutex. * * * Platform-specific notes: *   Any platforms that use this should be documented here! *   Why are you using the generic operators for this platform? * * HP-UX / HP-PA: *   This is used on the HP-PA processor since it doesn't provide the *   necessary assembler operators to implement proper atomic updates *   of ints.  HP's mutex primitive seems pretty fast however, resulting *   in a workable solution. * * OpenBSD: *   The standard assembler on x86 can't handle the gcc/asm operators *   defined above, so we're using the lock-pool approach for now. *   This approach also makes it possible to support non-x86 OpenBSD *   builds more easily (someday). *

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -