gallium/auxiliary: add inc and dec alternative with return (v4)

At this moment we use only zero or positive values.

v2: Implement it for also for Solaris, MSVC assembly
    and enable for other combinations.

v3: Replace MSVC assembly by assert + warning during compilation

v4: remove inc and dec with return for MSVC assembly

Acked-by: Jose Fonseca <jfonseca@vmware.com>
Reviewed-by: Ilia Mirkin <imirkin@alum.mit.edu>
Signed-off-by: David Heidelberg <david@ixit.cz>
(cherry picked from commit cb49132166)
This commit is contained in:
Christoph Bumiller 2014-11-17 20:05:53 +01:00 committed by Emil Velikov
parent 7bbf0836c8
commit 504d73f342

View file

@ -68,6 +68,18 @@ p_atomic_dec(int32_t *v)
__asm__ __volatile__("lock; decl %0":"+m"(*v));
}
static INLINE int32_t
p_atomic_inc_return(int32_t *v)
{
return __sync_add_and_fetch(v, 1);
}
static INLINE int32_t
p_atomic_dec_return(int32_t *v)
{
return __sync_sub_and_fetch(v, 1);
}
static INLINE int32_t
p_atomic_cmpxchg(int32_t *v, int32_t old, int32_t _new)
{
@ -115,6 +127,18 @@ p_atomic_dec(int32_t *v)
__asm__ __volatile__("lock; decl %0":"+m"(*v));
}
static INLINE int32_t
p_atomic_inc_return(int32_t *v)
{
return __sync_add_and_fetch(v, 1);
}
static INLINE int32_t
p_atomic_dec_return(int32_t *v)
{
return __sync_sub_and_fetch(v, 1);
}
static INLINE int32_t
p_atomic_cmpxchg(int32_t *v, int32_t old, int32_t _new)
{
@ -160,6 +184,18 @@ p_atomic_dec(int32_t *v)
(void) __sync_sub_and_fetch(v, 1);
}
static INLINE int32_t
p_atomic_inc_return(int32_t *v)
{
return __sync_add_and_fetch(v, 1);
}
static INLINE int32_t
p_atomic_dec_return(int32_t *v)
{
return __sync_sub_and_fetch(v, 1);
}
static INLINE int32_t
p_atomic_cmpxchg(int32_t *v, int32_t old, int32_t _new)
{
@ -186,6 +222,8 @@ p_atomic_cmpxchg(int32_t *v, int32_t old, int32_t _new)
#define p_atomic_dec_zero(_v) ((boolean) --(*(_v)))
#define p_atomic_inc(_v) ((void) (*(_v))++)
#define p_atomic_dec(_v) ((void) (*(_v))--)
#define p_atomic_inc_return(_v) ((*(_v))++)
#define p_atomic_dec_return(_v) ((*(_v))--)
#define p_atomic_cmpxchg(_v, old, _new) (*(_v) == old ? *(_v) = (_new) : *(_v))
#endif
@ -288,12 +326,24 @@ p_atomic_inc(int32_t *v)
_InterlockedIncrement((long *)v);
}
static INLINE int32_t
p_atomic_inc_return(int32_t *v)
{
return _InterlockedIncrement((long *)v);
}
static INLINE void
p_atomic_dec(int32_t *v)
{
_InterlockedDecrement((long *)v);
}
static INLINE int32_t
p_atomic_dec_return(int32_t *v)
{
return _InterlockedDecrement((long *)v);
}
static INLINE int32_t
p_atomic_cmpxchg(int32_t *v, int32_t old, int32_t _new)
{
@ -329,6 +379,8 @@ p_atomic_dec_zero(int32_t *v)
#define p_atomic_inc(_v) atomic_inc_32((uint32_t *) _v)
#define p_atomic_dec(_v) atomic_dec_32((uint32_t *) _v)
#define p_atomic_inc_return(_v) atomic_inc_32_nv((uint32_t *) _v)
#define p_atomic_dec_return(_v) atomic_dec_32_nv((uint32_t *) _v)
#define p_atomic_cmpxchg(_v, _old, _new) \
atomic_cas_32( (uint32_t *) _v, (uint32_t) _old, (uint32_t) _new)