threading_internal.h [plain text]
#ifndef _H_THREADING_INTERNAL
#define _H_THREADING_INTERNAL
#include <security_utilities/utilities.h>
#include <libkern/OSAtomic.h>
namespace Security {
#define _HAVE_64BIT_ATOMIC (defined(__ppc64__) || defined(__i386__) || defined(__x86_64__))
template <unsigned wordsize>
struct AtomicTypes {
};
template <>
struct AtomicTypes<32> {
typedef int32_t Integer;
static Integer add(int delta, Integer &base)
{ return OSAtomicAdd32(delta, &base); }
static Integer addb(int delta, Integer &base) { return OSAtomicAdd32Barrier(delta, &base); }
static bool cas(Integer oldValue, Integer newValue, Integer &base)
{ return OSAtomicCompareAndSwap32(oldValue, newValue, &base); }
static bool casb(Integer oldValue, Integer newValue, Integer &base)
{ return OSAtomicCompareAndSwap32Barrier(oldValue, newValue, &base); }
};
#if _HAVE_64BIT_ATOMIC
template <>
struct AtomicTypes<64> {
typedef int64_t Integer;
static Integer add(int delta, Integer &base) { return OSAtomicAdd64(delta, &base); }
static Integer addb(int delta, Integer &base) { return OSAtomicAdd64Barrier(delta, &base); }
static bool cas(Integer oldValue, Integer newValue, Integer &base)
{ return OSAtomicCompareAndSwap64(oldValue, newValue, &base); }
static bool casb(Integer oldValue, Integer newValue, Integer &base)
{ return OSAtomicCompareAndSwap64Barrier(oldValue, newValue, &base); }
};
#endif //_HAVE_64BIT_ATOMIC
template <class Type>
class Atomic {
typedef AtomicTypes<sizeof(Type) * 8> _Ops;
typedef typename _Ops::Integer _Type;
public:
static Type add(int delta, Type &store)
{ return Type(_Ops::add(delta, (_Type &)store)); }
static Type addb(int delta, Type &store)
{ return Type(_Ops::addb(delta, (_Type &)store)); }
static bool cas(Type oldValue, Type newValue, Type &store)
{ return _Ops::cas(_Type(oldValue), _Type(newValue), (_Type &)store); }
static bool casb(Type oldValue, Type newValue, Type &store)
{ return _Ops::casb(_Type(oldValue), _Type(newValue), (_Type &)store); }
static void barrier() { OSMemoryBarrier(); }
static void readBarrier() { OSMemoryBarrier(); }
static void writeBarrier() { OSMemoryBarrier(); }
static Type increment(Type &store) { return add(1, store); }
static Type decrement(Type &store) { return add(-1, store); }
static Type load(const Type &store) { readBarrier(); return store; }
static Type store(Type value, Type &store)
{ while (!casb(store, value, store)) {}; return value; }
};
}
#endif //_H_THREADING_INTERNAL