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
wsbmAtomicIncZero(struct _WsbmAtomic * v)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
wsbmAtomicDecNegative(struct _WsbmAtomic * v)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
wsbmAtomicDecZero(struct _WsbmAtomic * v)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
wsbmAtomicInc(struct _WsbmAtomic * v)53 wsbmAtomicInc(struct _WsbmAtomic *v)
54 {
55     __asm__ __volatile__("lock; incl %0":"+m"(v->count));
56 }
57 
58 static inline void
wsbmAtomicDec(struct _WsbmAtomic * v)59 wsbmAtomicDec(struct _WsbmAtomic *v)
60 {
61     __asm__ __volatile__("lock; decl %0":"+m"(v->count));
62 }
63 
64 static inline int32_t
wsbmAtomicCmpXchg(volatile struct _WsbmAtomic * v,int32_t old,int32_t new)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