summaryrefslogtreecommitdiff
path: root/lib/core/os.h
diff options
context:
space:
mode:
authorMaarten Lankhorst <maarten.lankhorst@canonical.com>2013-10-04 10:04:25 +1000
committerBen Skeggs <bskeggs@redhat.com>2013-11-05 16:15:42 +1000
commit371195b22031f550b7bfb64630c67a873e920dd1 (patch)
tree50528f3f0f8fda0634a816fd6d8451d228ec101f /lib/core/os.h
parent98cbe24b0dee21fb7a4b34fa75dd7d38c26de6fe (diff)
downloadnouveau-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.h43
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