1 /** 2 * This file is under no copyright claims due to its 3 * simplicity. 4 */ 5 6 #ifndef _WSBM_ATOMIC_H_ 7 #define _WSBM_ATOMIC_H_ 8 9 #include <stdint.h> 10 11 struct _WsbmAtomic 12 { 13 int32_t count; 14 }; 15 16 #define wsbmAtomicInit(_i) {(i)} 17 #define wsbmAtomicSet(_v, _i) (((_v)->count) = (_i)) 18 #define wsbmAtomicRead(_v) ((_v)->count) 19 20 static inline int 21 wsbmAtomicIncZero(struct _WsbmAtomic *v) 22 { 23 unsigned char c; 24 __asm__ __volatile__("lock; incl %0; sete %1":"+m"(v->count), "=qm"(c) 25 ::"memory"); 26 27 return c != 0; 28 } 29 30 static inline int 31 wsbmAtomicDecNegative(struct _WsbmAtomic *v) 32 { 33 unsigned char c; 34 int i = -1; 35 __asm__ __volatile__("lock; addl %2,%0; sets %1":"+m"(v->count), "=qm"(c) 36 :"ir"(i):"memory"); 37 38 return c; 39 } 40 41 static inline int 42 wsbmAtomicDecZero(struct _WsbmAtomic *v) 43 { 44 unsigned char c; 45 46 __asm__ __volatile__("lock; decl %0; sete %1":"+m"(v->count), "=qm"(c) 47 ::"memory"); 48 49 return c != 0; 50 } 51 52 static inline void 53 wsbmAtomicInc(struct _WsbmAtomic *v) 54 { 55 __asm__ __volatile__("lock; incl %0":"+m"(v->count)); 56 } 57 58 static inline void 59 wsbmAtomicDec(struct _WsbmAtomic *v) 60 { 61 __asm__ __volatile__("lock; decl %0":"+m"(v->count)); 62 } 63 64 static inline int32_t 65 wsbmAtomicCmpXchg(volatile struct _WsbmAtomic *v, int32_t old, int32_t new) 66 { 67 int32_t previous; 68 69 __asm__ __volatile__("lock; cmpxchgl %k1,%2":"=a"(previous) 70 :"r"(new), "m"(v->count), "0"(old) 71 :"memory"); 72 73 return previous; 74 } 75 76 #endif 77