一起学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即可

上一篇:[转] c# 数据类型占用的字节数


下一篇:WPF之插件开发