From 07b8ce1ee87d291ff564c02cf878fae973317a52 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Mon, 20 Jun 2011 10:52:57 -0400 Subject: lockless get_write_access/deny_write_access new helpers: atomic_inc_unless_negative()/atomic_dec_unless_positive() Signed-off-by: Al Viro --- include/linux/atomic.h | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) (limited to 'include/linux/atomic.h') diff --git a/include/linux/atomic.h b/include/linux/atomic.h index ee456c79b0e6..bc6615d4132b 100644 --- a/include/linux/atomic.h +++ b/include/linux/atomic.h @@ -34,6 +34,32 @@ static inline int atomic_inc_not_zero_hint(atomic_t *v, int hint) } #endif +#ifndef atomic_inc_unless_negative +static inline int atomic_inc_unless_negative(atomic_t *p) +{ + int v, v1; + for (v = 0; v >= 0; v = v1) { + v1 = atomic_cmpxchg(p, v, v + 1); + if (likely(v1 == v)) + return 1; + } + return 0; +} +#endif + +#ifndef atomic_dec_unless_positive +static inline int atomic_dec_unless_positive(atomic_t *p) +{ + int v, v1; + for (v = 0; v <= 0; v = v1) { + v1 = atomic_cmpxchg(p, v, v - 1); + if (likely(v1 == v)) + return 1; + } + return 0; +} +#endif + #ifndef CONFIG_ARCH_HAS_ATOMIC_OR static inline void atomic_or(int i, atomic_t *v) { -- cgit v1.2.3 From 60063497a95e716c9a689af3be2687d261f115b4 Mon Sep 17 00:00:00 2001 From: Arun Sharma Date: Tue, 26 Jul 2011 16:09:06 -0700 Subject: atomic: use This allows us to move duplicated code in (atomic_inc_not_zero() for now) to Signed-off-by: Arun Sharma Reviewed-by: Eric Dumazet Cc: Ingo Molnar Cc: David Miller Cc: Eric Dumazet Acked-by: Mike Frysinger Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/atomic.h | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'include/linux/atomic.h') diff --git a/include/linux/atomic.h b/include/linux/atomic.h index bc6615d4132b..66fed6364122 100644 --- a/include/linux/atomic.h +++ b/include/linux/atomic.h @@ -2,6 +2,15 @@ #define _LINUX_ATOMIC_H #include +/** + * atomic_inc_not_zero - increment unless the number is zero + * @v: pointer of type atomic_t + * + * Atomically increments @v by 1, so long as @v is non-zero. + * Returns non-zero if @v was non-zero, and zero otherwise. + */ +#define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0) + /** * atomic_inc_not_zero_hint - increment if not null * @v: pointer of type atomic_t -- cgit v1.2.3 From f24219b4e90cf70ec4a211b17fbabc725a0ddf3c Mon Sep 17 00:00:00 2001 From: Arun Sharma Date: Tue, 26 Jul 2011 16:09:07 -0700 Subject: atomic: move atomic_add_unless to generic code This is in preparation for more generic atomic primitives based on __atomic_add_unless. Signed-off-by: Arun Sharma Signed-off-by: Hans-Christian Egtvedt Reviewed-by: Eric Dumazet Cc: Ingo Molnar Cc: David Miller Acked-by: Mike Frysinger Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/atomic.h | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'include/linux/atomic.h') diff --git a/include/linux/atomic.h b/include/linux/atomic.h index 66fed6364122..d5e167a6a398 100644 --- a/include/linux/atomic.h +++ b/include/linux/atomic.h @@ -2,6 +2,20 @@ #define _LINUX_ATOMIC_H #include +/** + * atomic_add_unless - add unless the number is already a given value + * @v: pointer of type atomic_t + * @a: the amount to add to v... + * @u: ...unless v is equal to u. + * + * Atomically adds @a to @v, so long as @v was not already @u. + * Returns non-zero if @v was not @u, and zero otherwise. + */ +static inline int atomic_add_unless(atomic_t *v, int a, int u) +{ + return __atomic_add_unless(v, a, u) != u; +} + /** * atomic_inc_not_zero - increment unless the number is zero * @v: pointer of type atomic_t -- cgit v1.2.3 From 7847777a45f9f8bfc8617dbf107bde1ecb59caee Mon Sep 17 00:00:00 2001 From: Arun Sharma Date: Tue, 26 Jul 2011 16:09:08 -0700 Subject: atomic: cleanup asm-generic atomic*.h inclusion After changing all consumers of atomics to include , we ran into some compile time errors due to this dependency chain: linux/atomic.h -> asm/atomic.h -> asm-generic/atomic-long.h where atomic-long.h could use funcs defined later in linux/atomic.h without a prototype. This patches moves the code that includes asm-generic/atomic*.h to linux/atomic.h. Archs that need need to select CONFIG_GENERIC_ATOMIC64 from now on (some of them used to include it unconditionally). Compile tested on i386 and x86_64 with allnoconfig. Signed-off-by: Arun Sharma Cc: Eric Dumazet Cc: Ingo Molnar Cc: David Miller Acked-by: Mike Frysinger Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/atomic.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'include/linux/atomic.h') diff --git a/include/linux/atomic.h b/include/linux/atomic.h index d5e167a6a398..42e7f6372ce2 100644 --- a/include/linux/atomic.h +++ b/include/linux/atomic.h @@ -96,4 +96,8 @@ static inline void atomic_or(int i, atomic_t *v) } #endif /* #ifndef CONFIG_ARCH_HAS_ATOMIC_OR */ +#include +#ifdef CONFIG_GENERIC_ATOMIC64 +#include +#endif #endif /* _LINUX_ATOMIC_H */ -- cgit v1.2.3 From acac43e2fc4b14ecf1ff229eaa8d1e011d063749 Mon Sep 17 00:00:00 2001 From: Arun Sharma Date: Tue, 26 Jul 2011 16:09:08 -0700 Subject: atomic: Update comments in atomic.h This clarifies the differences between and Signed-off-by: Arun Sharma Suggested-by: Mike Frysinger Cc: Eric Dumazet Cc: Ingo Molnar Cc: David Miller Acked-by: Mike Frysinger Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/atomic.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux/atomic.h') diff --git a/include/linux/atomic.h b/include/linux/atomic.h index 42e7f6372ce2..42b77b5446d2 100644 --- a/include/linux/atomic.h +++ b/include/linux/atomic.h @@ -1,3 +1,4 @@ +/* Atomic operations usable in machine independent code */ #ifndef _LINUX_ATOMIC_H #define _LINUX_ATOMIC_H #include -- cgit v1.2.3