我想自动比较和交换pid_t变量。我读的是标准的int类型。
我知道,atomic_compare_exchange_strong_explicit()可以自行管理。我需要做的就是将类型设置为_Atomic(pid_t)。
但是当我在macOS上工作时,我也想使其与OSX旧库兼容,libkern/OSAtomic.h需要知道CAS的类型和类型。
就像是size_t一样,我可以简单地这样做,
# ifdef __LP64__
# define CAS_size_t(old, new, mem) \
OSAtomicCompareAndSwap64((int64_t) (*old), (int64_t) (new), (volatile int64_t *) (mem))
# else
# define CAS_size_t(old, new, mem) \
OSAtomicCompareAndSwap32((int32_t) (*old), (int32_t) (new), (volatile int32_t *) (mem))
# endif
但是对于pid_t,我不确定,因为即使未定义__LP64__
,它也可能是int64_t,int32_t,int16_t还是什么?
答案 0 :(得分:3)
只需检查宏内部值的大小:
#define OSAtomicCompareAndSwap(old, new, mem) do{ \
if (sizeof(*old) == sizeof(int32_t)) { \
OSAtomicCompareAndSwap32((int32_t)(*old), (int32_t) (new), (volatile int32_t *) (mem)); \
} else if (sizeof(*old) == sizeof(int64_t)) { \
OSAtomicCompareAndSwap64((int64_t)(*old), (int64_t) (new), (volatile int64_t *) (mem)); \
} else assert(0); }while(0)
无论如何,应该由编译器优化检查。这不是类型检查(为此,我们需要使用C ++的typeid),只检查大小。
如果您需要返回值,则认为需要传递另一个变量:
#define OSAtomicCompareAndSwap(ret, old, new, mem) do{ \
if (sizeof(*old) == sizeof(int32_t)) { \
ret = OSAtomicCompareAndSwap32((int32_t)(*old), (int32_t) (new), (volatile int32_t *) (mem)); \
} else if (sizeof(*old) == sizeof(int64_t)) { \
ret = OSAtomicCompareAndSwap64((int64_t)(*old), (int64_t) (new), (volatile int64_t *) (mem)); \
} else assert(0); }while(0)
或ex。将指针传递给要与结果等一起存储的变量。或者,您可以使用statement expression gcc扩展名。
带有如下语句的表达式:
#define OSAtomicCompareAndSwap(old, new, mem) __extension__({ \
int64_t ret = 0; \
if (sizeof(*old) == sizeof(int32_t)) { \
ret = OSAtomicCompareAndSwap32((int32_t)(*old), (int32_t) (new), (volatile int32_t *) (mem)); \
} else if (sizeof(*old) == sizeof(int64_t)) { \
ret = OSAtomicCompareAndSwap64((int64_t)(*old), (int64_t) (new), (volatile int64_t *) (mem)); \
} else { \
assert(0); \
} \
ret; \
})