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_compiler.h"
13 #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 #elif (defined(PIPE_SUBSYSTEM_WINDOWS_USER)) /* (defined(PIPE_CC_GCC)) */
76 #define p_atomic_set(_v, _i) ((_v)->count = (_i))
77 #define p_atomic_read(_v) ((_v)->count)
80 p_atomic_dec_zero(struct pipe_atomic
*v
)
82 return InterlockedDecrement(&v
->count
);
86 p_atomic_inc(struct pipe_atomic
*v
)
88 InterlockedIncrement(&v
->count
);
92 p_atomic_dec(struct pipe_atomic
*v
)
94 InterlockedDecrement(&v
->count
);
98 p_atomic_cmpxchg(struct pipe_atomic
*v
, int32_t old
, int32_t new)
100 return InterlockedCompareExchange(&v
->count
, new, old
);
103 #else /* (defined(PIPE_SUBSYSTEM_WINDOWS_USER)) */
105 #include "pipe/p_thread.h"
108 * This implementation should really not be used.
109 * Add an assembly port instead. It may abort and
110 * doesn't destroy used mutexes.
119 p_atomic_set(struct pipe_atomic
*v
, int32_t i
)
121 pipe_mutex_init(v
->mutex
);
122 pipe_mutex_lock(v
->mutex
);
124 pipe_mutex_unlock(v
->mutex
);
127 static INLINE
int32_t
128 p_atomic_read(struct pipe_atomic
*v
)
132 pipe_mutex_lock(v
->mutex
);
134 pipe_mutex_unlock(v
->mutex
);
139 p_atomic_inc(struct pipe_atomic
*v
)
141 pipe_mutex_lock(v
->mutex
);
143 pipe_mutex_unlock(v
->mutex
);
147 p_atomic_dec(struct pipe_atomic
*v
)
149 pipe_mutex_lock(v
->mutex
);
151 pipe_mutex_unlock(v
->mutex
);
154 static INLINE boolean
155 p_atomic_dec_zero(struct pipe_atomic
*v
)
159 pipe_mutex_lock(v
->mutex
);
160 ret
= (--v
->count
== 0);
161 pipe_mutex_unlock(v
->mutex
);
165 static INLINE
int32_t
166 p_atomic_cmpxchg(struct pipe_atomic
*v
, int32_t old
, int32_t new)
170 pipe_mutex_lock(v
->mutex
);
174 pipe_mutex_unlock(v
->mutex
);
179 #endif /* (defined(PIPE_CC_GCC)) */
185 #endif /* P_ATOMIC_H */