]> git.saurik.com Git - apple/libplatform.git/blobdiff - src/os/atomic.c
libplatform-161.tar.gz
[apple/libplatform.git] / src / os / atomic.c
index 6c846f66aac1822807ebc326141cfdcff7bb2b01..180c090fc0604a7c7f2d4a956303dab187533d35 100644 (file)
  */
 
 #include "os/internal.h"
-#include "libkern/OSAtomic.h"
 #include "resolver.h"
+#include "libkern/OSAtomic.h"
 
 #if TARGET_OS_EMBEDDED
 
+OS_ATOMIC_EXPORT
+int32_t OSAtomicAdd32(int32_t v, volatile int32_t *p);
 OS_ATOMIC_EXPORT
 int32_t OSAtomicAdd32Barrier(int32_t v, volatile int32_t *p);
 OS_ATOMIC_EXPORT
+int32_t OSAtomicIncrement32(volatile int32_t *p);
+OS_ATOMIC_EXPORT
 int32_t OSAtomicIncrement32Barrier(volatile int32_t *p);
 OS_ATOMIC_EXPORT
+int32_t OSAtomicDecrement32(volatile int32_t *p);
+OS_ATOMIC_EXPORT
 int32_t OSAtomicDecrement32Barrier(volatile int32_t *p);
 OS_ATOMIC_EXPORT
+int64_t OSAtomicAdd64(int64_t v, volatile int64_t *p);
+OS_ATOMIC_EXPORT
 int64_t OSAtomicAdd64Barrier(int64_t v, volatile int64_t *p);
 OS_ATOMIC_EXPORT
+int64_t OSAtomicIncrement64(volatile int64_t *p);
+OS_ATOMIC_EXPORT
 int64_t OSAtomicIncrement64Barrier(volatile int64_t *p);
 OS_ATOMIC_EXPORT
+int64_t OSAtomicDecrement64(volatile int64_t *p);
+OS_ATOMIC_EXPORT
 int64_t OSAtomicDecrement64Barrier(volatile int64_t *p);
 OS_ATOMIC_EXPORT
+int32_t OSAtomicAnd32(uint32_t v, volatile uint32_t *p);
+OS_ATOMIC_EXPORT
 int32_t OSAtomicAnd32Barrier(uint32_t v, volatile uint32_t *p);
 OS_ATOMIC_EXPORT
+int32_t OSAtomicAnd32Orig(uint32_t v, volatile uint32_t *p);
+OS_ATOMIC_EXPORT
 int32_t OSAtomicAnd32OrigBarrier(uint32_t v, volatile uint32_t *p);
 OS_ATOMIC_EXPORT
+int32_t OSAtomicOr32(uint32_t v, volatile uint32_t *p);
+OS_ATOMIC_EXPORT
 int32_t OSAtomicOr32Barrier(uint32_t v, volatile uint32_t *p);
 OS_ATOMIC_EXPORT
+int32_t OSAtomicOr32Orig(uint32_t v, volatile uint32_t *p);
+OS_ATOMIC_EXPORT
 int32_t OSAtomicOr32OrigBarrier(uint32_t v, volatile uint32_t *p);
 OS_ATOMIC_EXPORT
+int32_t OSAtomicXor32(uint32_t v, volatile uint32_t *p);
+OS_ATOMIC_EXPORT
 int32_t OSAtomicXor32Barrier(uint32_t v, volatile uint32_t *p);
 OS_ATOMIC_EXPORT
+int32_t OSAtomicXor32Orig(uint32_t v, volatile uint32_t *p);
+OS_ATOMIC_EXPORT
 int32_t OSAtomicXor32OrigBarrier(uint32_t v, volatile uint32_t *p);
 OS_ATOMIC_EXPORT
+bool OSAtomicCompareAndSwap32(int32_t o, int32_t n, volatile int32_t *p);
+OS_ATOMIC_EXPORT
 bool OSAtomicCompareAndSwap32Barrier(int32_t o, int32_t n, volatile int32_t *p);
 OS_ATOMIC_EXPORT
+bool OSAtomicCompareAndSwapPtr(void *o, void *n, void * volatile *p);
+OS_ATOMIC_EXPORT
+bool OSAtomicCompareAndSwapPtrBarrier(void *o, void *n, void * volatile *p);
+OS_ATOMIC_EXPORT
+bool OSAtomicCompareAndSwapInt(int o, int n, volatile int *p);
+OS_ATOMIC_EXPORT
+bool OSAtomicCompareAndSwapIntBarrier(int o, int n, volatile int *p);
+OS_ATOMIC_EXPORT
+bool OSAtomicCompareAndSwapLong(long o, long n, volatile long *p);
+OS_ATOMIC_EXPORT
+bool OSAtomicCompareAndSwapLongBarrier(long o, long n, volatile long *p);
+OS_ATOMIC_EXPORT
+bool OSAtomicCompareAndSwap64(int64_t o, int64_t n, volatile int64_t *p);
+OS_ATOMIC_EXPORT
 bool OSAtomicCompareAndSwap64Barrier(int64_t o, int64_t n, volatile int64_t *p);
 OS_ATOMIC_EXPORT
+bool OSAtomicTestAndSet(uint32_t n, volatile void * p);
+OS_ATOMIC_EXPORT
 bool OSAtomicTestAndSetBarrier(uint32_t n, volatile void * p);
 OS_ATOMIC_EXPORT
+bool OSAtomicTestAndClear(uint32_t n, volatile void * p);
+OS_ATOMIC_EXPORT
 bool OSAtomicTestAndClearBarrier(uint32_t n, volatile void * p);
 OS_ATOMIC_EXPORT
 void OSAtomicEnqueue(OSQueueHead *list, void *new, size_t offset);
@@ -63,139 +107,232 @@ void* OSAtomicDequeue(OSQueueHead *list, size_t offset);
 OS_ATOMIC_EXPORT
 void OSMemoryBarrier(void);
 
-#if OS_ATOMIC_UP
-#define OS_ATOMIC_ALIAS_NO_BARRIER(n) OS_ATOMIC_EXPORT_ALIAS(n, n##Barrier)
-#else
-#define OS_ATOMIC_ALIAS_NO_BARRIER(n)
-#endif
+int32_t
+OSAtomicAdd32(int32_t v, volatile int32_t *p)
+{
+       int32_t r = os_atomic_add(p, v, relaxed);
+       return r;
+}
 
 int32_t
 OSAtomicAdd32Barrier(int32_t v, volatile int32_t *p)
 {
-       OS_ATOMIC_ALIAS_NO_BARRIER(OSAtomicAdd32);
-       int32_t r = os_atomic_add(p, v, acq_rel);
+       int32_t r = os_atomic_add(p, v, seq_cst);
+       return r;
+}
+
+int32_t
+OSAtomicIncrement32(volatile int32_t *p)
+{
+       int32_t r = os_atomic_add(p, 1, relaxed);
        return r;
 }
 
 int32_t
 OSAtomicIncrement32Barrier(volatile int32_t *p)
 {
-       OS_ATOMIC_ALIAS_NO_BARRIER(OSAtomicIncrement32);
-       int32_t r = os_atomic_add(p, 1, acq_rel);
+       int32_t r = os_atomic_add(p, 1, seq_cst);
+       return r;
+}
+
+int32_t
+OSAtomicDecrement32(volatile int32_t *p)
+{
+       int32_t r = os_atomic_add(p, -1, relaxed);
        return r;
 }
 
 int32_t
 OSAtomicDecrement32Barrier(volatile int32_t *p)
 {
-       OS_ATOMIC_ALIAS_NO_BARRIER(OSAtomicDecrement32);
-       int32_t r = os_atomic_add(p, -1, acq_rel);
+       int32_t r = os_atomic_add(p, -1, seq_cst);
+       return r;
+}
+
+int64_t
+OSAtomicAdd64(int64_t v, volatile int64_t *p)
+{
+       int64_t r = os_atomic_add(p, v, relaxed);
        return r;
 }
 
 int64_t
 OSAtomicAdd64Barrier(int64_t v, volatile int64_t *p)
 {
-       OS_ATOMIC_ALIAS_NO_BARRIER(OSAtomicAdd64);
-       int64_t r = os_atomic_add(p, v, acq_rel);
+       int64_t r = os_atomic_add(p, v, seq_cst);
+       return r;
+}
+
+int64_t
+OSAtomicIncrement64(volatile int64_t *p)
+{
+       int64_t r = os_atomic_add(p, 1, relaxed);
        return r;
 }
 
 int64_t
 OSAtomicIncrement64Barrier(volatile int64_t *p)
 {
-       OS_ATOMIC_ALIAS_NO_BARRIER(OSAtomicIncrement64);
-       int64_t r = os_atomic_add(p, 1, acq_rel);
+       int64_t r = os_atomic_add(p, 1, seq_cst);
+       return r;
+}
+
+int64_t
+OSAtomicDecrement64(volatile int64_t *p)
+{
+       int64_t r = os_atomic_add(p, -1, relaxed);
        return r;
 }
 
 int64_t
 OSAtomicDecrement64Barrier(volatile int64_t *p)
 {
-       OS_ATOMIC_ALIAS_NO_BARRIER(OSAtomicDecrement64);
-       int64_t r = os_atomic_add(p, -1, acq_rel);
+       int64_t r = os_atomic_add(p, -1, seq_cst);
        return r;
 }
 
+int32_t
+OSAtomicAnd32(uint32_t v, volatile uint32_t *p)
+{
+       uint32_t r = os_atomic_and(p, v, relaxed);
+       return (int32_t)r;
+}
+
 int32_t
 OSAtomicAnd32Barrier(uint32_t v, volatile uint32_t *p)
 {
-       OS_ATOMIC_ALIAS_NO_BARRIER(OSAtomicAnd32);
-       uint32_t r = os_atomic_and(p, v, acq_rel);
+       uint32_t r = os_atomic_and(p, v, seq_cst);
+       return (int32_t)r;
+}
+
+int32_t
+OSAtomicAnd32Orig(uint32_t v, volatile uint32_t *p)
+{
+       uint32_t r = os_atomic_and_orig(p, v, relaxed);
        return (int32_t)r;
 }
 
 int32_t
 OSAtomicAnd32OrigBarrier(uint32_t v, volatile uint32_t *p)
 {
-       OS_ATOMIC_ALIAS_NO_BARRIER(OSAtomicAnd32Orig);
-       uint32_t r = os_atomic_and_orig(p, v, acq_rel);
+       uint32_t r = os_atomic_and_orig(p, v, seq_cst);
+       return (int32_t)r;
+}
+
+int32_t
+OSAtomicOr32(uint32_t v, volatile uint32_t *p)
+{
+       uint32_t r = os_atomic_or(p, v, relaxed);
        return (int32_t)r;
 }
 
 int32_t
 OSAtomicOr32Barrier(uint32_t v, volatile uint32_t *p)
 {
-       OS_ATOMIC_ALIAS_NO_BARRIER(OSAtomicOr32);
-       uint32_t r = os_atomic_or(p, v, acq_rel);
+       uint32_t r = os_atomic_or(p, v, seq_cst);
+       return (int32_t)r;
+}
+
+int32_t
+OSAtomicOr32Orig(uint32_t v, volatile uint32_t *p)
+{
+       uint32_t r = os_atomic_or_orig(p, v, relaxed);
        return (int32_t)r;
 }
 
 int32_t
 OSAtomicOr32OrigBarrier(uint32_t v, volatile uint32_t *p)
 {
-       OS_ATOMIC_ALIAS_NO_BARRIER(OSAtomicOr32Orig);
-       uint32_t r = os_atomic_or_orig(p, v, acq_rel);
+       uint32_t r = os_atomic_or_orig(p, v, seq_cst);
+       return (int32_t)r;
+}
+
+int32_t
+OSAtomicXor32(uint32_t v, volatile uint32_t *p)
+{
+       uint32_t r = os_atomic_xor(p, v, relaxed);
        return (int32_t)r;
 }
 
 int32_t
 OSAtomicXor32Barrier(uint32_t v, volatile uint32_t *p)
 {
-       OS_ATOMIC_ALIAS_NO_BARRIER(OSAtomicXor32);
-       uint32_t r = os_atomic_xor(p, v, acq_rel);
+       uint32_t r = os_atomic_xor(p, v, seq_cst);
+       return (int32_t)r;
+}
+
+int32_t
+OSAtomicXor32Orig(uint32_t v, volatile uint32_t *p)
+{
+       uint32_t r = os_atomic_xor_orig(p, v, relaxed);
        return (int32_t)r;
 }
 
 int32_t
 OSAtomicXor32OrigBarrier(uint32_t v, volatile uint32_t *p)
 {
-       OS_ATOMIC_ALIAS_NO_BARRIER(OSAtomicXor32Orig);
-       uint32_t r = os_atomic_xor_orig(p, v, acq_rel);
+       uint32_t r = os_atomic_xor_orig(p, v, seq_cst);
        return (int32_t)r;
 }
 
+bool
+OSAtomicCompareAndSwap32(int32_t o, int32_t n, volatile int32_t *p)
+{
+       return os_atomic_cmpxchg(p, o, n, relaxed);
+}
+
 bool
 OSAtomicCompareAndSwap32Barrier(int32_t o, int32_t n, volatile int32_t *p)
 {
-       OS_ATOMIC_ALIAS_NO_BARRIER(OSAtomicCompareAndSwap32);
-       OS_ATOMIC_ALIAS(OSAtomicCompareAndSwapIntBarrier,
-                       OSAtomicCompareAndSwap32Barrier);
-       OS_ATOMIC_ALIAS_NO_BARRIER(OSAtomicCompareAndSwapInt);
-#ifndef __LP64__
-       OS_ATOMIC_ALIAS(OSAtomicCompareAndSwapLongBarrier,
-                       OSAtomicCompareAndSwap32Barrier);
-       OS_ATOMIC_ALIAS_NO_BARRIER(OSAtomicCompareAndSwapLong);
-       OS_ATOMIC_ALIAS(OSAtomicCompareAndSwapPtrBarrier,
-                       OSAtomicCompareAndSwap32Barrier);
-       OS_ATOMIC_ALIAS_NO_BARRIER(OSAtomicCompareAndSwapPtr);
-#endif
-       return os_atomic_cmpxchg(p, o, n, acq_rel);
+       return os_atomic_cmpxchg(p, o, n, seq_cst);
+}
+
+bool
+OSAtomicCompareAndSwapPtr(void *o, void *n, void * volatile *p)
+{
+       return os_atomic_cmpxchg(p, o, n, relaxed);
+}
+
+bool
+OSAtomicCompareAndSwapPtrBarrier(void *o, void *n, void * volatile *p)
+{
+       return os_atomic_cmpxchg(p, o, n, seq_cst);
+}
+
+bool
+OSAtomicCompareAndSwapInt(int o, int n, volatile int *p)
+{
+       return os_atomic_cmpxchg(p, o, n, relaxed);
+}
+
+bool
+OSAtomicCompareAndSwapIntBarrier(int o, int n, volatile int *p)
+{
+       return os_atomic_cmpxchg(p, o, n, seq_cst);
+}
+
+bool
+OSAtomicCompareAndSwapLong(long o, long n, volatile long *p)
+{
+       return os_atomic_cmpxchg(p, o, n, relaxed);
+}
+
+bool
+OSAtomicCompareAndSwapLongBarrier(long o, long n, volatile long *p)
+{
+       return os_atomic_cmpxchg(p, o, n, seq_cst);
+}
+
+bool
+OSAtomicCompareAndSwap64(int64_t o, int64_t n, volatile int64_t *p)
+{
+       return os_atomic_cmpxchg(p, o, n, relaxed);
 }
 
 bool
 OSAtomicCompareAndSwap64Barrier(int64_t o, int64_t n, volatile int64_t *p)
 {
-       OS_ATOMIC_ALIAS_NO_BARRIER(OSAtomicCompareAndSwap64);
-#ifdef __LP64__
-       OS_ATOMIC_ALIAS(OSAtomicCompareAndSwapLongBarrier,
-                       OSAtomicCompareAndSwap64Barrier);
-       OS_ATOMIC_ALIAS_NO_BARRIER(OSAtomicCompareAndSwapLong);
-       OS_ATOMIC_ALIAS(OSAtomicCompareAndSwapPtrBarrier,
-                       OSAtomicCompareAndSwap64Barrier);
-       OS_ATOMIC_ALIAS_NO_BARRIER(OSAtomicCompareAndSwapPtr);
-#endif
-       return os_atomic_cmpxchg(p, o, n, acq_rel);
+       return os_atomic_cmpxchg(p, o, n, seq_cst);
 }
 
 static inline uint32_t*
@@ -211,42 +348,60 @@ _OSAtomicTestPtrVal(uint32_t bit, volatile void *addr, uint32_t *vp)
        return (uint32_t*)((char*)a + 4 * (bit / 32));
 }
 
+bool
+OSAtomicTestAndSet(uint32_t bit, volatile void *addr)
+{
+       uint32_t v;
+       volatile uint32_t *p = _OSAtomicTestPtrVal(bit, addr, &v);
+       uint32_t r = os_atomic_or_orig(p, v, relaxed);
+       return (r & v);
+}
+
 bool
 OSAtomicTestAndSetBarrier(uint32_t bit, volatile void *addr)
 {
-       OS_ATOMIC_ALIAS_NO_BARRIER(OSAtomicTestAndSet);
        uint32_t v;
        volatile uint32_t *p = _OSAtomicTestPtrVal(bit, addr, &v);
-       uint32_t r = os_atomic_or_orig(p, v, acq_rel);
+       uint32_t r = os_atomic_or_orig(p, v, seq_cst);
        return (r & v);
 }
 
 bool
-OSAtomicTestAndClearBarrier(uint32_t bit, volatile void *addr)
+OSAtomicTestAndClear(uint32_t bit, volatile void *addr)
 {
-       OS_ATOMIC_ALIAS_NO_BARRIER(OSAtomicTestAndClear);
        uint32_t v;
        volatile uint32_t *p = _OSAtomicTestPtrVal(bit, addr, &v);
-       uint32_t r = os_atomic_and_orig(p, ~v, acq_rel);
+       uint32_t r = os_atomic_and_orig(p, ~v, relaxed);
        return (r & v);
 }
 
-#if !OS_ATOMIC_NO_BARRIER_ONLY
+bool
+OSAtomicTestAndClearBarrier(uint32_t bit, volatile void *addr)
+{
+       uint32_t v;
+       volatile uint32_t *p = _OSAtomicTestPtrVal(bit, addr, &v);
+       uint32_t r = os_atomic_and_orig(p, ~v, seq_cst);
+       return (r & v);
+}
 
-typedef volatile struct {
-       void * volatile item;
-       long unused;
+typedef struct {
+       void *item;
+       long gencount;
 } _OSQueueHead;
 
+
 void
 OSAtomicEnqueue(OSQueueHead *list, void *new, size_t offset)
 {
        void * volatile *headptr = &(((_OSQueueHead*)list)->item);
        void * volatile *nextptr = (void*)((char*)new + offset);
-       void *head = *headptr;
+       void *head, *next;
+
+       head = os_atomic_load(headptr, relaxed);
+       next = new;
        do {
                *nextptr = head;
-       } while (!os_atomic_cmpxchgvw(headptr, head, new, &head, release));
+       } while (!os_atomic_cmpxchgvw(headptr, head, next, &head, release));
 }
 
 void*
@@ -255,23 +410,22 @@ OSAtomicDequeue(OSQueueHead *list, size_t offset)
        void * volatile *headptr = &(((_OSQueueHead*)list)->item);
        void * volatile *nextptr;
        void *head, *next;
-       (void)os_atomic_rmw_loop(headptr, head, next, acquire, {
-               if (!head) {
-                       os_atomic_rmw_loop_give_up(break);
-               }
+
+       os_atomic_rmw_loop(headptr, head, next, acquire, {
+               if (!head) os_atomic_rmw_loop_give_up(break);
                nextptr = (void*)((char*)head + offset);
                next = *nextptr;
        });
        return head;
 }
 
+
 void
 OSMemoryBarrier(void)
 {
        os_atomic_thread_fence(seq_cst);
 }
 
-#endif // !OS_ATOMIC_NO_BARRIER_ONLY
 #endif // TARGET_OS_EMBEDDED
 
 struct _os_empty_files_are_not_c_files;