this repo has no description
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Initial OSAtomic implementation

+339
+228
libmac/libc/OSAtomic.cpp
··· 1 + #include "OSAtomic.h" 2 + #include "libc-stub.h" 3 + #include <cassert> 4 + #include <sched.h> 5 + 6 + int32_t OSAtomicAdd32(int32_t theAmount, volatile int32_t *theValue) 7 + { 8 + return __sync_add_and_fetch(theValue, theAmount); 9 + } 10 + 11 + int32_t OSAtomicAdd32Barrier(int32_t theAmount, volatile int32_t *theValue) 12 + { 13 + return __sync_add_and_fetch(theValue, theAmount); 14 + } 15 + 16 + int32_t OSAtomicIncrement32(volatile int32_t *theValue) 17 + { 18 + return OSAtomicAdd32(1, theValue); 19 + } 20 + 21 + int32_t OSAtomicIncrement32Barrier(volatile int32_t *theValue) 22 + { 23 + return OSAtomicAdd32Barrier(1, theValue); 24 + } 25 + 26 + int32_t OSAtomicDecrement32(volatile int32_t *theValue) 27 + { 28 + return OSAtomicAdd32(-1, theValue); 29 + } 30 + 31 + int32_t OSAtomicDecrement32Barrier(volatile int32_t *theValue) 32 + { 33 + return OSAtomicAdd32Barrier(-1, theValue); 34 + } 35 + 36 + int32_t OSAtomicOr32(uint32_t theMask, volatile uint32_t *theValue) 37 + { 38 + return __sync_or_and_fetch(theValue, theMask); 39 + } 40 + 41 + int32_t OSAtomicOr32Barrier(uint32_t theMask, volatile uint32_t *theValue) 42 + { 43 + return __sync_or_and_fetch(theValue, theMask); 44 + } 45 + 46 + int32_t OSAtomicAnd32(uint32_t theMask, volatile uint32_t *theValue) 47 + { 48 + return __sync_and_and_fetch(theValue, theMask); 49 + } 50 + 51 + int32_t OSAtomicAnd32Barrier(uint32_t theMask, volatile uint32_t *theValue) 52 + { 53 + return __sync_and_and_fetch(theValue, theMask); 54 + } 55 + 56 + int32_t OSAtomicXor32(uint32_t theMask, volatile uint32_t *theValue) 57 + { 58 + return __sync_xor_and_fetch(theValue, theMask); 59 + } 60 + 61 + int32_t OSAtomicXor32Barrier(uint32_t theMask, volatile uint32_t *theValue) 62 + { 63 + return __sync_xor_and_fetch(theValue, theMask); 64 + } 65 + 66 + int32_t OSAtomicOr32Orig(uint32_t theMask, volatile uint32_t *theValue) 67 + { 68 + return __sync_fetch_and_or(theValue, theMask); 69 + } 70 + 71 + int32_t OSAtomicOr32OrigBarrier(uint32_t theMask, volatile uint32_t *theValue) 72 + { 73 + return __sync_fetch_and_or(theValue, theMask); 74 + } 75 + 76 + int32_t OSAtomicAnd32Orig(uint32_t theMask, volatile uint32_t *theValue) 77 + { 78 + return __sync_fetch_and_and(theValue, theMask); 79 + } 80 + 81 + int32_t OSAtomicAnd32OrigBarrier(uint32_t theMask, volatile uint32_t *theValue) 82 + { 83 + return __sync_fetch_and_and(theValue, theMask); 84 + } 85 + 86 + int32_t OSAtomicXor32Orig(uint32_t theMask, volatile uint32_t *theValue) 87 + { 88 + return __sync_fetch_and_xor(theValue, theMask); 89 + } 90 + 91 + int32_t OSAtomicXor32OrigBarrier(uint32_t theMask, volatile uint32_t *theValue) 92 + { 93 + return __sync_fetch_and_xor(theValue, theMask); 94 + } 95 + 96 + int64_t OSAtomicAdd64(int64_t theAmount, volatile int64_t *theValue) 97 + { 98 + return __sync_add_and_fetch(theValue, theAmount); 99 + } 100 + 101 + int64_t OSAtomicAdd64Barrier(int64_t theAmount, volatile int64_t *theValue) 102 + { 103 + return __sync_add_and_fetch(theValue, theAmount); 104 + } 105 + 106 + int64_t OSAtomicIncrement64(volatile int64_t *theValue) 107 + { 108 + return OSAtomicAdd64(1, theValue); 109 + } 110 + 111 + int64_t OSAtomicIncrement64Barrier(volatile int64_t *theValue) 112 + { 113 + return OSAtomicAdd64Barrier(1, theValue); 114 + } 115 + 116 + int64_t OSAtomicDecrement64(volatile int64_t *theValue) 117 + { 118 + return OSAtomicAdd64(-1, theValue); 119 + } 120 + 121 + int64_t OSAtomicDecrement64Barrier(volatile int64_t *theValue) 122 + { 123 + return OSAtomicAdd64Barrier(-1, theValue); 124 + } 125 + 126 + bool OSAtomicCompareAndSwapInt(int oldValue, int newValue, volatile int *theValue) 127 + { 128 + return __sync_bool_compare_and_swap(theValue, oldValue, newValue); 129 + } 130 + 131 + bool OSAtomicCompareAndSwapIntBarrier(int oldValue, int newValue, volatile int *theValue) 132 + { 133 + return __sync_bool_compare_and_swap(theValue, oldValue, newValue); 134 + } 135 + 136 + bool OSAtomicCompareAndSwapLong(long oldValue, long newValue, volatile long *theValue) 137 + { 138 + return __sync_bool_compare_and_swap(theValue, oldValue, newValue); 139 + } 140 + 141 + bool OSAtomicCompareAndSwapLongBarrier(long oldValue, long newValue, volatile long *theValue) 142 + { 143 + return __sync_bool_compare_and_swap(theValue, oldValue, newValue); 144 + } 145 + 146 + bool OSAtomicCompareAndSwapPtr(void* oldValue, void* newValue, void* volatile *theValue) 147 + { 148 + return __sync_bool_compare_and_swap(theValue, oldValue, newValue); 149 + } 150 + 151 + bool OSAtomicCompareAndSwapPtrBarrier(void* oldValue, void* newValue, void* volatile *theValue) 152 + { 153 + return __sync_bool_compare_and_swap(theValue, oldValue, newValue); 154 + } 155 + 156 + bool OSAtomicCompareAndSwap32(int32_t oldValue, int32_t newValue, volatile int32_t *theValue) 157 + { 158 + return __sync_bool_compare_and_swap(theValue, oldValue, newValue); 159 + } 160 + 161 + bool OSAtomicCompareAndSwap32Barrier(int32_t oldValue, int32_t newValue, volatile int32_t *theValue) 162 + { 163 + return __sync_bool_compare_and_swap(theValue, oldValue, newValue); 164 + } 165 + 166 + bool OSAtomicCompareAndSwap64(int64_t oldValue, int64_t newValue, volatile int64_t *theValue) 167 + { 168 + return __sync_bool_compare_and_swap(theValue, oldValue, newValue); 169 + } 170 + 171 + bool OSAtomicCompareAndSwap64Barrier(int64_t oldValue, int64_t newValue, volatile int64_t *theValue) 172 + { 173 + return __sync_bool_compare_and_swap(theValue, oldValue, newValue); 174 + } 175 + 176 + bool OSAtomicTestAndSet(uint32_t n, volatile void *theAddress) 177 + { 178 + LIBC_STUB(); 179 + return false; 180 + } 181 + 182 + bool OSAtomicTestAndSetBarrier(uint32_t n, volatile void *theAddress) 183 + { 184 + LIBC_STUB(); 185 + return false; 186 + } 187 + 188 + bool OSAtomicTestAndClear(uint32_t n, volatile void *theAddress) 189 + { 190 + LIBC_STUB(); 191 + return false; 192 + } 193 + 194 + bool OSAtomicTestAndClearBarrier(uint32_t n, volatile void *theAddress) 195 + { 196 + LIBC_STUB(); 197 + return false; 198 + } 199 + 200 + bool OSSpinLockTry(OSSpinLock *lock) 201 + { 202 + return __sync_bool_compare_and_swap(lock, 0, 1); 203 + } 204 + 205 + void OSSpinLockLock(OSSpinLock *lock) 206 + { 207 + // We cannot use pthread spinlocks, these need init and destruction 208 + while (!OSSpinLockTry(lock)) 209 + sched_yield(); // TODO: still a busy wait... 210 + } 211 + 212 + void OSSpinLockUnlock(OSSpinLock *lock) 213 + { 214 + bool success = __sync_bool_compare_and_swap(lock, 1, 0); 215 + assert(success); // Will fail if spinlock wasn't locked 216 + } 217 + 218 + // http://i.stack.imgur.com/FSBA3.png 219 + void OSAtomicEnqueue(OSQueueHead *list, void *_new, size_t offset) 220 + { 221 + LIBC_STUB(); 222 + } 223 + 224 + void* OSAtomicDequeue(OSQueueHead *list, size_t offset) 225 + { 226 + LIBC_STUB(); 227 + } 228 +
+104
libmac/libc/OSAtomic.h
··· 1 + #ifndef OSATOMIC_H 2 + #define OSATOMIC_H 3 + #include <stdint.h> 4 + #include <pthread.h> 5 + 6 + typedef pthread_spinlock_t OSSpinLock; 7 + struct OSQueueHead 8 + { 9 + void* p; 10 + long l; 11 + }; 12 + 13 + extern "C" { 14 + 15 + int32_t OSAtomicAdd32(int32_t theAmount, volatile int32_t *theValue); 16 + 17 + int32_t OSAtomicAdd32Barrier(int32_t theAmount, volatile int32_t *theValue); 18 + 19 + int32_t OSAtomicIncrement32(volatile int32_t *theValue); 20 + 21 + int32_t OSAtomicIncrement32Barrier(volatile int32_t *theValue); 22 + 23 + int32_t OSAtomicDecrement32(volatile int32_t *theValue); 24 + 25 + int32_t OSAtomicDecrement32Barrier(volatile int32_t *theValue); 26 + 27 + int32_t OSAtomicOr32(uint32_t theMask, volatile uint32_t *theValue); 28 + 29 + int32_t OSAtomicOr32Barrier(uint32_t theMask, volatile uint32_t *theValue); 30 + 31 + int32_t OSAtomicAnd32(uint32_t theMask, volatile uint32_t *theValue); 32 + 33 + int32_t OSAtomicAnd32Barrier(uint32_t theMask, volatile uint32_t *theValue); 34 + 35 + int32_t OSAtomicXor32(uint32_t theMask, volatile uint32_t *theValue); 36 + 37 + int32_t OSAtomicXor32Barrier(uint32_t theMask, volatile uint32_t *theValue); 38 + 39 + int32_t OSAtomicOr32Orig(uint32_t theMask, volatile uint32_t *theValue); 40 + 41 + int32_t OSAtomicOr32OrigBarrier(uint32_t theMask, volatile uint32_t *theValue); 42 + 43 + int32_t OSAtomicAnd32Orig(uint32_t theMask, volatile uint32_t *theValue); 44 + 45 + int32_t OSAtomicAnd32OrigBarrier(uint32_t theMask, volatile uint32_t *theValue); 46 + 47 + int32_t OSAtomicXor32Orig(uint32_t theMask, volatile uint32_t *theValue); 48 + 49 + int32_t OSAtomicXor32OrigBarrier(uint32_t theMask, volatile uint32_t *theValue); 50 + 51 + int64_t OSAtomicAdd64(int64_t theAmount, volatile int64_t *theValue); 52 + 53 + int64_t OSAtomicAdd64Barrier(int64_t theAmount, volatile int64_t *theValue); 54 + 55 + int64_t OSAtomicIncrement64(volatile int64_t *theValue); 56 + 57 + int64_t OSAtomicIncrement64Barrier(volatile int64_t *theValue); 58 + 59 + int64_t OSAtomicDecrement64(volatile int64_t *theValue); 60 + 61 + int64_t OSAtomicDecrement64Barrier(volatile int64_t *theValue); 62 + 63 + bool OSAtomicCompareAndSwapInt(int oldValue, int newValue, volatile int *theValue); 64 + 65 + bool OSAtomicCompareAndSwapIntBarrier(int oldValue, int newValue, volatile int *theValue); 66 + 67 + bool OSAtomicCompareAndSwapLong(long oldValue, long newValue, volatile long *theValue); 68 + 69 + bool OSAtomicCompareAndSwapLongBarrier(long oldValue, long newValue, volatile long *theValue); 70 + 71 + bool OSAtomicCompareAndSwapPtr(void* oldValue, void* newValue, void* volatile *theValue); 72 + 73 + bool OSAtomicCompareAndSwapPtrBarrier(void* oldValue, void* newValue, void* volatile *theValue); 74 + 75 + bool OSAtomicCompareAndSwap32(int32_t oldValue, int32_t newValue, volatile int32_t *theValue); 76 + 77 + bool OSAtomicCompareAndSwap32Barrier(int32_t oldValue, int32_t newValue, volatile int32_t *theValue); 78 + 79 + bool OSAtomicCompareAndSwap64(int64_t oldValue, int64_t newValue, volatile int64_t *theValue); 80 + 81 + bool OSAtomicCompareAndSwap64Barrier(int64_t oldValue, int64_t newValue, volatile int64_t *theValue); 82 + 83 + bool OSAtomicTestAndSet(uint32_t n, volatile void *theAddress); 84 + 85 + bool OSAtomicTestAndSetBarrier(uint32_t n, volatile void *theAddress); 86 + 87 + bool OSAtomicTestAndClear(uint32_t n, volatile void *theAddress); 88 + 89 + bool OSAtomicTestAndClearBarrier(uint32_t n, volatile void *theAddress); 90 + 91 + bool OSSpinLockTry(OSSpinLock *lock); 92 + 93 + void OSSpinLockLock(OSSpinLock *lock); 94 + 95 + void OSSpinLockUnlock(OSSpinLock *lock); 96 + 97 + void OSAtomicEnqueue(OSQueueHead *list, void *_new, size_t offset); 98 + 99 + void* OSAtomicDequeue(OSQueueHead *list, size_t offset); 100 + 101 + } 102 + 103 + #endif 104 +
+7
libmac/libc/libc-stub.h
··· 1 + #ifndef LIBC_STUB_H 2 + #define LIBC_STUB_H 3 + 4 + #define LIBC_STUB() { fprintf(stderr, "LIBC_STUB(): %s\n", __PRETTY_FUNCTION__); } 5 + 6 + #endif 7 +