diff options
author | Maarten Lankhorst <maarten.lankhorst@canonical.com> | 2013-10-04 10:04:25 +1000 |
---|---|---|
committer | Ben Skeggs <bskeggs@redhat.com> | 2013-11-05 16:15:42 +1000 |
commit | 371195b22031f550b7bfb64630c67a873e920dd1 (patch) | |
tree | 50528f3f0f8fda0634a816fd6d8451d228ec101f /lib/core/os.h | |
parent | 98cbe24b0dee21fb7a4b34fa75dd7d38c26de6fe (diff) | |
download | nouveau-371195b22031f550b7bfb64630c67a873e920dd1.tar.gz |
lib: fixup and tidy atomic ops, add test_bit and friends
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Diffstat (limited to 'lib/core/os.h')
-rw-r--r-- | lib/core/os.h | 43 |
1 files changed, 37 insertions, 6 deletions
diff --git a/lib/core/os.h b/lib/core/os.h index 956b495b3..5cf75ce9d 100644 --- a/lib/core/os.h +++ b/lib/core/os.h @@ -159,6 +159,40 @@ hweight32(u32 v) { return i; } +static inline int +test_bit(int bit, volatile unsigned long *ptr) +{ + return !!(*ptr & (1 << bit)); +} + +static inline int +__test_and_clear_bit(int bit, volatile unsigned long *ptr) +{ + int ret = test_bit(bit, ptr); + *ptr &= ~(1L << bit); + return ret; +} + +static inline int +test_and_clear_bit(int bit, volatile unsigned long *ptr) +{ + return !!(__sync_fetch_and_and(ptr, ~(1L << bit)) & (1L << bit)); +} + +static inline int +__test_and_set_bit(int bit, volatile unsigned long *ptr) +{ + int ret = test_bit(bit, ptr); + *ptr |= (1L << bit); + return ret; +} + +static inline int +test_and_set_bit(int bit, volatile unsigned long *ptr) +{ + return !(__sync_fetch_and_or(ptr, (1L << bit)) & (1L << bit)); +} + /****************************************************************************** * atomics *****************************************************************************/ @@ -170,14 +204,11 @@ typedef struct atomic { #define atomic_set(a,b) ((a)->value = (b)) #define atomic_inc(a) ((void) __sync_fetch_and_add (&(a)->value, 1)) #define atomic_dec(a) ((void) __sync_fetch_and_add (&(a)->value, -1)) -#define atomic_dec_and_test(a) (__sync_fetch_and_add (&(a)->value, -1) == 1) #define atomic_add(a,b) ((void) __sync_add_and_fetch(&(a)->value, (b))) #define atomic_add_return(b,a) (__sync_add_and_fetch(&(a)->value, (b))) - -/*XXX*/ -#define atomic_add_unless(a,b,c) (atomic_read((a)) != (c) ? \ - atomic_add_return((b), (a)) : \ - atomic_read((a))) +#define atomic_inc_return(a) atomic_add_return(1, (a)) +#define atomic_dec_return(a) atomic_add_return(-1, (a)) +#define atomic_dec_and_test(a) (atomic_dec_return(a) == 0) /****************************************************************************** * krefs |