| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent ab66dab commit d863a9d
3 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,146 @@ | |||
| 1 | + /** | ||
| 2 | + * hdr_atomic.h | ||
| 3 | + * Written by Philip Orwig and released to the public domain, | ||
| 4 | + * as explained at http://creativecommons.org/publicdomain/zero/1.0/ | ||
| 5 | + */ | ||
| 6 | + | ||
| 7 | + #ifndef HDR_ATOMIC_H__ | ||
| 8 | + #define HDR_ATOMIC_H__ | ||
| 9 | + | ||
| 10 | + | ||
| 11 | + #if defined(_MSC_VER) | ||
| 12 | + | ||
| 13 | + #include <stdint.h> | ||
| 14 | + #include <intrin.h> | ||
| 15 | + #include <stdbool.h> | ||
| 16 | + | ||
| 17 | + static void __inline * hdr_atomic_load_pointer(void** pointer) | ||
| 18 | + { | ||
| 19 | + _ReadBarrier(); | ||
| 20 | + return *pointer; | ||
| 21 | + } | ||
| 22 | + | ||
| 23 | + static void hdr_atomic_store_pointer(void** pointer, void* value) | ||
| 24 | + { | ||
| 25 | + _WriteBarrier(); | ||
| 26 | + *pointer = value; | ||
| 27 | + } | ||
| 28 | + | ||
| 29 | + static int64_t __inline hdr_atomic_load_64(int64_t* field) | ||
| 30 | + { | ||
| 31 | + _ReadBarrier(); | ||
| 32 | + return *field; | ||
| 33 | + } | ||
| 34 | + | ||
| 35 | + static void __inline hdr_atomic_store_64(int64_t* field, int64_t value) | ||
| 36 | + { | ||
| 37 | + _WriteBarrier(); | ||
| 38 | + *field = value; | ||
| 39 | + } | ||
| 40 | + | ||
| 41 | + static int64_t __inline hdr_atomic_exchange_64(volatile int64_t* field, int64_t value) | ||
| 42 | + { | ||
| 43 | + #if defined(_WIN64) | ||
| 44 | + return _InterlockedExchange64(field, value); | ||
| 45 | + #else | ||
| 46 | + int64_t comparand; | ||
| 47 | + int64_t initial_value = *field; | ||
| 48 | + do | ||
| 49 | + { | ||
| 50 | + comparand = initial_value; | ||
| 51 | + initial_value = _InterlockedCompareExchange64(field, value, comparand); | ||
| 52 | + } | ||
| 53 | + while (comparand != initial_value); | ||
| 54 | + | ||
| 55 | + return initial_value; | ||
| 56 | + #endif | ||
| 57 | + } | ||
| 58 | + | ||
| 59 | + static int64_t __inline hdr_atomic_add_fetch_64(volatile int64_t* field, int64_t value) | ||
| 60 | + { | ||
| 61 | + #if defined(_WIN64) | ||
| 62 | + return _InterlockedExchangeAdd64(field, value) + value; | ||
| 63 | + #else | ||
| 64 | + int64_t comparand; | ||
| 65 | + int64_t initial_value = *field; | ||
| 66 | + do | ||
| 67 | + { | ||
| 68 | + comparand = initial_value; | ||
| 69 | + initial_value = _InterlockedCompareExchange64(field, comparand + value, comparand); | ||
| 70 | + } | ||
| 71 | + while (comparand != initial_value); | ||
| 72 | + | ||
| 73 | + return initial_value + value; | ||
| 74 | + #endif | ||
| 75 | + } | ||
| 76 | + | ||
| 77 | + static bool __inline hdr_atomic_compare_exchange_64(volatile int64_t* field, int64_t* expected, int64_t desired) | ||
| 78 | + { | ||
| 79 | + return *expected == _InterlockedCompareExchange64(field, desired, *expected); | ||
| 80 | + } | ||
| 81 | + | ||
| 82 | + #elif defined(__ATOMIC_SEQ_CST) | ||
| 83 | + | ||
| 84 | + #define hdr_atomic_load_pointer(x) __atomic_load_n(x, __ATOMIC_SEQ_CST) | ||
| 85 | + #define hdr_atomic_store_pointer(f,v) __atomic_store_n(f,v, __ATOMIC_SEQ_CST) | ||
| 86 | + #define hdr_atomic_load_64(x) __atomic_load_n(x, __ATOMIC_SEQ_CST) | ||
| 87 | + #define hdr_atomic_store_64(f,v) __atomic_store_n(f,v, __ATOMIC_SEQ_CST) | ||
| 88 | + #define hdr_atomic_exchange_64(f,i) __atomic_exchange_n(f,i, __ATOMIC_SEQ_CST) | ||
| 89 | + #define hdr_atomic_add_fetch_64(field, value) __atomic_add_fetch(field, value, __ATOMIC_SEQ_CST) | ||
| 90 | + #define hdr_atomic_compare_exchange_64(field, expected, desired) __atomic_compare_exchange_n(field, expected, desired, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST) | ||
| 91 | + | ||
| 92 | + #elif defined(__x86_64__) | ||
| 93 | + | ||
| 94 | + #include <stdint.h> | ||
| 95 | + #include <stdbool.h> | ||
| 96 | + | ||
| 97 | + static inline void* hdr_atomic_load_pointer(void** pointer) | ||
| 98 | + { | ||
| 99 | + void* p = *pointer; | ||
| 100 | + asm volatile ("" ::: "memory"); | ||
| 101 | + return p; | ||
| 102 | + } | ||
| 103 | + | ||
| 104 | + static inline void hdr_atomic_store_pointer(void** pointer, void* value) | ||
| 105 | + { | ||
| 106 | + asm volatile ("lock; xchgq %0, %1" : "+q" (value), "+m" (*pointer)); | ||
| 107 | + } | ||
| 108 | + | ||
| 109 | + static inline int64_t hdr_atomic_load_64(int64_t* field) | ||
| 110 | + { | ||
| 111 | + int64_t i = *field; | ||
| 112 | + asm volatile ("" ::: "memory"); | ||
| 113 | + return i; | ||
| 114 | + } | ||
| 115 | + | ||
| 116 | + static inline void hdr_atomic_store_64(int64_t* field, int64_t value) | ||
| 117 | + { | ||
| 118 | + asm volatile ("lock; xchgq %0, %1" : "+q" (value), "+m" (*field)); | ||
| 119 | + } | ||
| 120 | + | ||
| 121 | + static inline int64_t hdr_atomic_exchange_64(volatile int64_t* field, int64_t value) | ||
| 122 | + { | ||
| 123 | + int64_t result = 0; | ||
| 124 | + asm volatile ("lock; xchgq %1, %2" : "=r" (result), "+q" (value), "+m" (*field)); | ||
| 125 | + return result; | ||
| 126 | + } | ||
| 127 | + | ||
| 128 | + static inline int64_t hdr_atomic_add_fetch_64(volatile int64_t* field, int64_t value) | ||
| 129 | + { | ||
| 130 | + return __sync_add_and_fetch(field, value); | ||
| 131 | + } | ||
| 132 | + | ||
| 133 | + static inline bool hdr_atomic_compare_exchange_64(volatile int64_t* field, int64_t* expected, int64_t desired) | ||
| 134 | + { | ||
| 135 | + int64_t original; | ||
| 136 | + asm volatile( "lock; cmpxchgq %2, %1" : "=a"(original), "+m"(*field) : "q"(desired), "0"(*expected)); | ||
| 137 | + return original == *expected; | ||
| 138 | + } | ||
| 139 | + | ||
| 140 | + #else | ||
| 141 | + | ||
| 142 | + #error "Unable to determine atomic operations for your platform" | ||
| 143 | + | ||
| 144 | + #endif | ||
| 145 | + | ||
| 146 | + #endif /* HDR_ATOMIC_H__ */ | ||
| Back | FazBrowse Home | New Git URL |
0 commit comments