5 #pragma GCC optimization_level 0
12 * Atomically incremente a reference count variable.
13 * \param valp address of atomic variable
14 * \return incremented reference count
16 typedef unsigned mvp_atomic_t;
17 static inline unsigned
18 __mvp_atomic_increment(mvp_atomic_t *valp)
21 #if defined __i486__ || defined __i586__ || defined __i686__
23 "lock xaddl %0, (%1);"
26 : "r" (valp), "0" (0x1)
29 #elif defined __i386__
30 asm volatile (".byte 0xf0, 0x0f, 0xc1, 0x02" /*lock; xaddl %eax, (%edx) */
32 : "0" (1), "m" (*valp), "d" (valp)
34 /* on the x86 __val is the pre-increment value, so normalize it. */
36 #elif defined __powerpc__ || defined __ppc__
37 asm volatile ("1: lwarx %0,0,%1\n"
46 #elif defined _MSC_VER
47 __val = InterlockedIncrement(valp);
50 * Don't know how to atomic increment for a generic architecture
51 * so punt and just increment the value.
54 #pragma message("unknown architecture, atomic increment is not...");
56 #warning unknown architecture, atomic increment is not...
64 * Atomically decrement a reference count variable.
65 * \param valp address of atomic variable
66 * \return decremented reference count
68 static inline unsigned
69 __mvp_atomic_decrement(mvp_atomic_t *valp)
72 #if defined __i486__ || defined __i586__ || defined __i686__
74 "lock xaddl %0, (%1);"
77 : "r" (valp), "0" (0x1)
80 #elif defined __i386__
81 asm volatile (".byte 0xf0, 0x0f, 0xc1, 0x02" /*lock; xaddl %eax, (%edx) */
83 : "0" (-1), "m" (*valp), "d" (valp)
85 /* __val is the pre-decrement value, so normalize it */
87 #elif defined __powerpc__ || defined __ppc__
88 asm volatile ("1: lwarx %0,0,%1\n"
97 #elif defined __sparcv9__
98 mvp_atomic_t __newval, __oldval = (*valp);
101 __newval = __oldval - 1;
102 __asm__ ("cas [%4], %2, %0"
103 : "=r" (__oldval), "=m" (*valp)
104 : "r" (__oldval), "m" (*valp), "r"((valp)), "0" (__newval));
106 while (__newval != __oldval);
107 /* The value for __val is in '__oldval' */
109 #elif defined _MSC_VER
110 __val = InterlockedDecrement(valp);
113 * Don't know how to atomic decrement for a generic architecture
114 * so punt and just decrement the value.
116 //#warning unknown architecture, atomic decrement is not...
121 #define mvp_atomic_inc __mvp_atomic_inc
122 static inline int mvp_atomic_inc(mvp_atomic_t *a) {
123 return __mvp_atomic_increment(a);
126 #define mvp_atomic_dec __mvp_atomic_dec
127 static inline int mvp_atomic_dec(mvp_atomic_t *a) {
128 return __mvp_atomic_decrement(a);
131 #define mvp_atomic_dec_and_test __mvp_atomic_dec_and_test
132 static inline int mvp_atomic_dec_and_test(mvp_atomic_t *a) {
133 return (__mvp_atomic_decrement(a) == 0);
136 #define mvp_atomic_set __mvp_atomic_set
137 static inline void mvp_atomic_set(mvp_atomic_t *a, unsigned val) {
142 #pragma GCC optimization_level reset
145 #endif /* __MVP_ATOMIC_H */