一起学JUCE之Atomic

  Atomic功能是提供简单的类保持原始值,并且提供对其执行原子操作;Atomic是线程安全的,类型的实现比较简单,就是通过各种措施保证变量的操作达到原子操作,有一点需要注意Atomic使用的时候只支持长度是32位或者64位的类或者类型,其他类型会出现问题。这里对类中用到的一些系统函数进行一些说明。

 

类型转换

 template <typename Dest, typename Source>
    static inline Dest castTo (Source value) noexcept         { union { Dest d; Source s; } u; u.s = value; return u.d; }

    static inline Type castFrom32Bit (int32 value) noexcept   { return castTo <Type, int32> (value); }
    static inline Type castFrom64Bit (int64 value) noexcept   { return castTo <Type, int64> (value); }
    static inline int32 castTo32Bit (Type value) noexcept     { return castTo <int32, Type> (value); }
    static inline int64 castTo64Bit (Type value) noexcept     { return castTo <int64, Type> (value); }

以上类型转换比较巧妙,直接使用联合体进行两个变量的转换不用再对类型进行判断,Dest和Source占用的内存空间都位4或者8

 

以下对各个系统使用到的api做些说明
MAC:

原子操作

 #include <libkern/OSAtomic.h>
 int32_t
     OSAtomicAdd32(int32_t theAmount, volatile int32_t *theValue);

     int32_t
     OSAtomicAdd32Barrier(int32_t theAmount, volatile int32_t *theValue);

     int32_t
     OSAtomicIncrement32(volatile int32_t *theValue);

     int32_t
     OSAtomicIncrement32Barrier(volatile int32_t *theValue);

     int32_t
     OSAtomicDecrement32(volatile int32_t *theValue);

     int32_t
     OSAtomicDecrement32Barrier(volatile int32_t *theValue);

     int32_t
     OSAtomicOr32(uint32_t theMask, volatile uint32_t *theValue);

     int32_t
     OSAtomicOr32Barrier(uint32_t theMask, volatile uint32_t *theValue);

     int32_t
     OSAtomicAnd32(uint32_t theMask, volatile uint32_t *theValue);

     int32_t
     OSAtomicAnd32Barrier(uint32_t theMask, volatile uint32_t *theValue);

     int32_t
     OSAtomicXor32(uint32_t theMask, volatile uint32_t *theValue);

     int32_t
     OSAtomicXor32Barrier(uint32_t theMask, volatile uint32_t *theValue);

     int32_t
     OSAtomicOr32Orig(uint32_t theMask, volatile uint32_t *theValue);

     int32_t
     OSAtomicOr32OrigBarrier(uint32_t theMask, volatile uint32_t *theValue);

     int32_t
     OSAtomicAnd32Orig(uint32_t theMask, volatile uint32_t *theValue);

     int32_t
     OSAtomicAnd32OrigBarrier(uint32_t theMask, volatile uint32_t *theValue);

     int32_t
     OSAtomicXor32Orig(uint32_t theMask, volatile uint32_t *theValue);

     int32_t
     OSAtomicXor32OrigBarrier(uint32_t theMask, volatile uint32_t *theValue);

     int64_t
     OSAtomicAdd64(int64_t theAmount, volatile int64_t *theValue);

     int64_t
     OSAtomicAdd64Barrier(int64_t theAmount, volatile int64_t *theValue);

     int64_t
     OSAtomicIncrement64(volatile int64_t *theValue);

     int64_t
     OSAtomicIncrement64Barrier(volatile int64_t *theValue);

     int64_t
     OSAtomicDecrement64(volatile int64_t *theValue);

     int64_t
     OSAtomicDecrement64Barrier(volatile int64_t *theValue);

     bool
     OSAtomicCompareAndSwapInt(int oldValue, int newValue,
         volatile int *theValue);

     bool
     OSAtomicCompareAndSwapIntBarrier(int oldValue, int newValue,
         volatile int *theValue);

     bool
     OSAtomicCompareAndSwapLong(long oldValue, long newValue,
         volatile long *theValue);

     bool
     OSAtomicCompareAndSwapLongBarrier(long oldValue, long newValue,
         volatile long *theValue);

     bool
     OSAtomicCompareAndSwapPtr(void* oldValue, void* newValue,
         void* volatile *theValue);

     bool
     OSAtomicCompareAndSwapPtrBarrier(void* oldValue, void* newValue,
         void* volatile *theValue);

     bool
     OSAtomicCompareAndSwap32(int32_t oldValue, int32_t newValue,
         volatile int32_t *theValue);

     bool
     OSAtomicCompareAndSwap32Barrier(int32_t oldValue, int32_t newValue,
         volatile int32_t *theValue);

     bool
     OSAtomicCompareAndSwap64(int64_t oldValue, int64_t newValue,
         volatile int64_t *theValue);

     bool
     OSAtomicCompareAndSwap64Barrier(int64_t oldValue, int64_t newValue,
         volatile int64_t *theValue);

     bool
     OSAtomicTestAndSet(uint32_t n, volatile void *theAddress);

     bool
     OSAtomicTestAndSetBarrier(uint32_t n, volatile void *theAddress);

     bool
     OSAtomicTestAndClear(uint32_t n, volatile void *theAddress);

     bool
     OSAtomicTestAndClearBarrier(uint32_t n, volatile void *theAddress);

     bool
     OSSpinLockTry(OSSpinLock *lock);

     void
     OSSpinLockLock(OSSpinLock *lock);

     void
     OSSpinLockUnlock(OSSpinLock *lock);

     void
     OSAtomicEnqueue(OSQueueHead *list, void *new, size_t offset);

     void*
     OSAtomicDequeue(OSQueueHead *list, size_t offset);

 

 

LINUX:

原子操作

type __sync_fetch_and_add (type *ptr, type value);
type __sync_fetch_and_sub (type *ptr, type value);
type __sync_fetch_and_or (type *ptr, type value);
type __sync_fetch_and_and (type *ptr, type value);
type __sync_fetch_and_xor (type *ptr, type value);
type __sync_fetch_and_nand (type *ptr, type value);
type __sync_add_and_fetch (type *ptr, type value);
type __sync_sub_and_fetch (type *ptr, type value);
type __sync_or_and_fetch (type *ptr, type value);
type __sync_and_and_fetch (type *ptr, type value);
type __sync_xor_and_fetch (type *ptr, type value);
type __sync_nand_and_fetch (type *ptr, type value);

 

 

 

WINDOWS:

原子操作

LONG InterLockedIncrement(
  LPLONG lpAddend // variable address
  );
LONG InterlockedDecrement(
  LPLONG lpAddend // variable address
  );

LONG__cdeclInterlockedExchangeAdd(
_Inout_LONGvolatile*Addend,
_In_LONGValue
);

 LONG InterlockedCompareExchange(
LPLONG Destination, LONG Exchange, LONG Comperand );
 PVOID InterlockedCompareExchangePointer(
PVOID *Destination, PVOID Exchange, PVOID Comperand );

 总体的原子操作完全是依赖于系统API来实现的,留一下相关系统的原子操作api即可

posted @ 2015-02-07 13:23  davygeek  阅读(554)  评论(0编辑  收藏  举报