2 * Many similar implementations exist. See for example libwsbm
3 * or the linux kernel include/atomic.h
5 * No copyright claimed on this file.
12 #include "p_defines.h"
19 #if (defined(PIPE_CC_GCC))
24 #define p_atomic_set(_v, _i) ((_v)->count = (_i))
25 #define p_atomic_read(_v) ((_v)->count)
29 p_atomic_dec_zero(struct pipe_atomic
*v
)
34 __asm__
__volatile__("lock; decl %0; sete %1":"+m"(v
->count
), "=qm"(c
)
39 return (__sync_sub_and_fetch(&v
->count
, 1) == 0);
44 p_atomic_inc(struct pipe_atomic
*v
)
47 __asm__
__volatile__("lock; incl %0":"+m"(v
->count
));
49 (void) __sync_add_and_fetch(&v
->count
, 1);
54 p_atomic_dec(struct pipe_atomic
*v
)
57 __asm__
__volatile__("lock; decl %0":"+m"(v
->count
));
59 (void) __sync_sub_and_fetch(&v
->count
, 1);
64 p_atomic_cmpxchg(struct pipe_atomic
*v
, int32_t old
, int32_t new)
66 return __sync_val_compare_and_swap(&v
->count
, old
, new);
69 #else /* (defined(PIPE_CC_GCC)) */
71 #include "pipe/p_thread.h"
74 * This implementation should really not be used.
75 * Add an assembly port instead. It may abort and
76 * doesn't destroy used mutexes.
85 p_atomic_set(struct pipe_atomic
*v
, int32_t i
)
88 ret
= pipe_mutex_init(v
->mutex
);
91 pipe_mutex_lock(v
->mutex
);
93 pipe_mutex_unlock(v
->mutex
);
97 p_atomic_read(struct pipe_atomic
*v
)
101 pipe_mutex_lock(v
->mutex
);
103 pipe_mutex_unlock(v
->mutex
);
108 p_atomic_inc(struct pipe_atomic
*v
)
110 pipe_mutex_lock(v
->mutex
);
112 pipe_mutex_unlock(v
->mutex
);
116 p_atomic_dec(struct pipe_atomic
*v
)
118 pipe_mutex_lock(v
->mutex
);
120 pipe_mutex_unlock(v
->mutex
);
123 static INLINE boolean
124 p_atomic_dec_zero(struct pipe_atomic
*v
)
128 pipe_mutex_lock(v
->mutex
);
129 ret
= (--v
->count
== 0);
130 pipe_mutex_unlock(v
->mutex
);
134 static INLINE
int32_t
135 p_atomic_cmpxchg(struct pipe_atomic
*v
, int32_t old
, int32_t new)
139 pipe_mutex_lock(v
->mutex
);
143 pipe_mutex_unlock(v
->mutex
);
148 #endif /* (defined(PIPE_CC_GCC)) */
154 #endif /* P_ATOMIC_H */