假设 pid_t 始终是 int 类型(如标准中所定义)是否安全?
Is it safe to assume pid_t is always an int type (as defined in the standard)?
我想自动比较和交换 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还是什么?
只需检查宏中值的大小:
#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++-ish typeid),只检查大小。
如果您需要 return 一个值,如果您认为您需要传递另一个变量:
#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)
或前。将指向变量的指针传递给 memcpy-ied 以及结果等。或者您可以使用 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; \
})
我想自动比较和交换 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还是什么?
只需检查宏中值的大小:
#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++-ish typeid),只检查大小。
如果您需要 return 一个值,如果您认为您需要传递另一个变量:
#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)
或前。将指向变量的指针传递给 memcpy-ied 以及结果等。或者您可以使用 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; \
})