* [PATCH 0/9] atomic.h : standardising atomic primitives
@ 2006-12-21 0:08 Mathieu Desnoyers
2006-12-21 0:09 ` [PATCH 2/9] atomic.h : generic atomic_long Mathieu Desnoyers
` (8 more replies)
0 siblings, 9 replies; 13+ messages in thread
From: Mathieu Desnoyers @ 2006-12-21 0:08 UTC (permalink / raw)
To: linux-kernel, Andrew Morton, Ingo Molnar, Greg Kroah-Hartman,
Christoph Hellwig
Cc: ltt-dev, systemtap, Douglas Niehaus, Martin J. Bligh, Thomas Gleixner
It mainly adds support for missing 64 bits cmpxchg and 64 bits atomic add
unless. Therefore, principally 64 bits architectures are targeted by these
patches. It also adds the complete list of atomic operations on the atomic_long
type.
These patches applies on 2.6.20-rc1-git7.
Signed-off-by : Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca>
OpenPGP public key: http://krystal.dyndns.org:8080/key/compudj.gpg
Key fingerprint: 8CD5 52C3 8E3C 4140 715F BA06 3F25 A8FE 3BAE 9A68
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH 2/9] atomic.h : generic atomic_long
2006-12-21 0:08 [PATCH 0/9] atomic.h : standardising atomic primitives Mathieu Desnoyers
@ 2006-12-21 0:09 ` Mathieu Desnoyers
2006-12-21 0:10 ` [PATCH 3/9] atomic.h : i386 "64 bits" ready fix Mathieu Desnoyers
` (7 subsequent siblings)
8 siblings, 0 replies; 13+ messages in thread
From: Mathieu Desnoyers @ 2006-12-21 0:09 UTC (permalink / raw)
To: linux-kernel, Andrew Morton, Ingo Molnar, Greg Kroah-Hartman,
Christoph Hellwig
Cc: ltt-dev, systemtap, Douglas Niehaus, Martin J. Bligh, Thomas Gleixner
This patch completes the atomic_long operations in asm-generic.
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca>
--- a/include/asm-generic/atomic.h
+++ b/include/asm-generic/atomic.h
@@ -66,6 +66,90 @@ static inline void atomic_long_sub(long
atomic64_sub(i, v);
}
+static inline int atomic_long_sub_and_test(long i, atomic_long_t *l)
+{
+ atomic64_t *v = (atomic64_t *)l;
+
+ return (long)atomic64_sub_and_test(i, v);
+}
+
+static inline int atomic_long_dec_and_test(atomic_long_t *l)
+{
+ atomic64_t *v = (atomic64_t *)l;
+
+ return (long)atomic64_dec_and_test(v);
+}
+
+static inline int atomic_long_inc_and_test(atomic_long_t *l)
+{
+ atomic64_t *v = (atomic64_t *)l;
+
+ return (long)atomic64_inc_and_test(v);
+}
+
+static inline int atomic_long_add_negative(long i, atomic_long_t *l)
+{
+ atomic64_t *v = (atomic64_t *)l;
+
+ return (long)atomic64_add_negative(i, v);
+}
+
+static inline long atomic_long_add_return(long i, atomic_long_t *l)
+{
+ atomic64_t *v = (atomic64_t *)l;
+
+ return (long)atomic64_add_return(i, v);
+}
+
+static inline long atomic_long_sub_return(long i, atomic_long_t *l)
+{
+ atomic64_t *v = (atomic64_t *)l;
+
+ return (long)atomic64_sub_return(i, v);
+}
+
+static inline long atomic_long_inc_return(atomic_long_t *l)
+{
+ atomic64_t *v = (atomic64_t *)l;
+
+ return (long)atomic64_inc_return(v);
+}
+
+static inline long atomic_long_dec_return(atomic_long_t *l)
+{
+ atomic64_t *v = (atomic64_t *)l;
+
+ return (long)atomic64_dec_return(v);
+}
+
+static inline long atomic_long_add_unless(atomic_long_t *l, long a, long u)
+{
+ atomic64_t *v = (atomic64_t *)l;
+
+ return (long)atomic64_add_unless(v, a, u);
+}
+
+static inline long atomic_long_inc_not_zero(atomic_long_t *l)
+{
+ atomic64_t *v = (atomic64_t *)l;
+
+ return (long)atomic64_inc_not_zero(v);
+}
+
+static inline long atomic_long_cmpxchg(atomic_long_t *l, long old, long new)
+{
+ atomic64_t *v = (atomic64_t *)l;
+
+ return (long)atomic64_cmpxchg(v, old, new);
+}
+
+static inline long atomic_long_xchg(atomic_long_t *l, long new)
+{
+ atomic64_t *v = (atomic64_t *)l;
+
+ return (long)atomic64_xchg(v, new);
+}
+
#else /* BITS_PER_LONG == 64 */
typedef atomic_t atomic_long_t;
@@ -113,6 +197,90 @@ static inline void atomic_long_sub(long
atomic_sub(i, v);
}
+static inline int atomic_long_sub_and_test(long i, atomic_long_t *l)
+{
+ atomic_t *v = (atomic_t *)l;
+
+ return atomic_sub_and_test(i, v);
+}
+
+static inline int atomic_long_dec_and_test(atomic_long_t *l)
+{
+ atomic_t *v = (atomic_t *)l;
+
+ return atomic_dec_and_test(v);
+}
+
+static inline int atomic_long_inc_and_test(atomic_long_t *l)
+{
+ atomic_t *v = (atomic_t *)l;
+
+ return atomic_inc_and_test(v);
+}
+
+static inline int atomic_long_add_negative(long i, atomic_long_t *l)
+{
+ atomic_t *v = (atomic_t *)l;
+
+ return atomic_add_negative(i, v);
+}
+
+static inline long atomic_long_add_return(long i, atomic_long_t *l)
+{
+ atomic_t *v = (atomic_t *)l;
+
+ return (long)atomic_add_return(i, v);
+}
+
+static inline long atomic_long_sub_return(long i, atomic_long_t *l)
+{
+ atomic_t *v = (atomic_t *)l;
+
+ return (long)atomic_sub_return(i, v);
+}
+
+static inline long atomic_long_inc_return(atomic_long_t *l)
+{
+ atomic_t *v = (atomic_t *)l;
+
+ return (long)atomic_inc_return(v);
+}
+
+static inline long atomic_long_dec_return(atomic_long_t *l)
+{
+ atomic_t *v = (atomic_t *)l;
+
+ return (long)atomic_dec_return(v);
+}
+
+static inline long atomic_long_add_unless(atomic_long_t *l, long a, long u)
+{
+ atomic_t *v = (atomic_t *)l;
+
+ return (long)atomic_add_unless(v, a, u);
+}
+
+static inline long atomic_long_inc_not_zero(atomic_long_t *l)
+{
+ atomic_t *v = (atomic_t *)l;
+
+ return (long)atomic_inc_not_zero(v);
+}
+
+static inline long atomic_long_cmpxchg(atomic_long_t *l, long old, long new)
+{
+ atomic_t *v = (atomic_t *)l;
+
+ return (long)atomic_cmpxchg(v, old, new);
+}
+
+static inline long atomic_long_xchg(atomic_long_t *l, long new)
+{
+ atomic_t *v = (atomic_t *)l;
+
+ return (long)atomic_xchg(v, new);
+}
+
#endif /* BITS_PER_LONG == 64 */
#endif /* _ASM_GENERIC_ATOMIC_H */
OpenPGP public key: http://krystal.dyndns.org:8080/key/compudj.gpg
Key fingerprint: 8CD5 52C3 8E3C 4140 715F BA06 3F25 A8FE 3BAE 9A68
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH 3/9] atomic.h : i386 "64 bits" ready fix.
2006-12-21 0:08 [PATCH 0/9] atomic.h : standardising atomic primitives Mathieu Desnoyers
2006-12-21 0:09 ` [PATCH 2/9] atomic.h : generic atomic_long Mathieu Desnoyers
@ 2006-12-21 0:10 ` Mathieu Desnoyers
2006-12-21 0:11 ` [PATCH 5/9] atomic.h : standardising atomic primitives Mathieu Desnoyers
` (6 subsequent siblings)
8 siblings, 0 replies; 13+ messages in thread
From: Mathieu Desnoyers @ 2006-12-21 0:10 UTC (permalink / raw)
To: linux-kernel, Andrew Morton, Ingo Molnar, Greg Kroah-Hartman,
Christoph Hellwig
Cc: ltt-dev, systemtap, Douglas Niehaus, Martin J. Bligh, Thomas Gleixner
This patch changes the cmpxchg, xchg and add_unless atomic operations on i386 so
they will still work if, for instance, they are cut'n'pasted to operate of
atomic64_t types. The correct fix might be to create inline functions for
cmpxchg for every architecture, but until then, it looks safer to put this kind
of automatic typing instead of using an integer.
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca>
--- a/include/asm-i386/atomic.h
+++ b/include/asm-i386/atomic.h
@@ -207,8 +207,9 @@ static __inline__ int atomic_sub_return(
return atomic_add_return(-i,v);
}
-#define atomic_cmpxchg(v, old, new) ((int)cmpxchg(&((v)->counter), old, new))
-#define atomic_xchg(v, new) (xchg(&((v)->counter), new))
+#define atomic_cmpxchg(v, old, new) \
+ ((__typeof__((v)->counter))cmpxchg(&((v)->counter), (old), (new)))
+#define atomic_xchg(v, new) (xchg(&((v)->counter), (new)))
/**
* atomic_add_unless - add unless the number is a given value
@@ -221,7 +222,7 @@ #define atomic_xchg(v, new) (xchg(&((v)-
*/
#define atomic_add_unless(v, a, u) \
({ \
- int c, old; \
+ __typeof__((v)->counter) c, old; \
c = atomic_read(v); \
for (;;) { \
if (unlikely(c == (u))) \
OpenPGP public key: http://krystal.dyndns.org:8080/key/compudj.gpg
Key fingerprint: 8CD5 52C3 8E3C 4140 715F BA06 3F25 A8FE 3BAE 9A68
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH 5/9] atomic.h : standardising atomic primitives
2006-12-21 0:08 [PATCH 0/9] atomic.h : standardising atomic primitives Mathieu Desnoyers
2006-12-21 0:09 ` [PATCH 2/9] atomic.h : generic atomic_long Mathieu Desnoyers
2006-12-21 0:10 ` [PATCH 3/9] atomic.h : i386 "64 bits" ready fix Mathieu Desnoyers
@ 2006-12-21 0:11 ` Mathieu Desnoyers
2006-12-21 0:11 ` [PATCH 4/9] atomic.h : ia64 Mathieu Desnoyers
` (5 subsequent siblings)
8 siblings, 0 replies; 13+ messages in thread
From: Mathieu Desnoyers @ 2006-12-21 0:11 UTC (permalink / raw)
To: linux-kernel, Andrew Morton, Ingo Molnar, Greg Kroah-Hartman,
Christoph Hellwig, Linux-MIPS
Cc: ltt-dev, systemtap, Douglas Niehaus, Martin J. Bligh, Thomas Gleixner
64 bits cmpxchg, xchg and add_unless for MIPS.
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca>
--- a/include/asm-mips/atomic.h
+++ b/include/asm-mips/atomic.h
@@ -291,8 +291,9 @@ static __inline__ int atomic_sub_if_posi
return result;
}
-#define atomic_cmpxchg(v, o, n) ((int)cmpxchg(&((v)->counter), (o), (n)))
-#define atomic_xchg(v, new) (xchg(&((v)->counter), new))
+#define atomic_cmpxchg(v, o, n) \
+ (((__typeof__((v)->counter)))cmpxchg(&((v)->counter), (o), (n)))
+#define atomic_xchg(v, new) (xchg(&((v)->counter), (new)))
/**
* atomic_add_unless - add unless the number is a given value
@@ -305,7 +306,7 @@ #define atomic_xchg(v, new) (xchg(&((v)-
*/
#define atomic_add_unless(v, a, u) \
({ \
- int c, old; \
+ __typeof__((v)->counter) c, old; \
c = atomic_read(v); \
while (c != (u) && (old = atomic_cmpxchg((v), c, c + (a))) != c) \
c = old; \
@@ -651,6 +652,29 @@ static __inline__ long atomic64_sub_if_p
return result;
}
+#define atomic64_cmpxchg(v, o, n) \
+ (((__typeof__((v)->counter)))cmpxchg(&((v)->counter), (o), (n)))
+#define atomic64_xchg(v, new) (xchg(&((v)->counter), (new)))
+
+/**
+ * atomic64_add_unless - add unless the number is a given value
+ * @v: pointer of type atomic64_t
+ * @a: the amount to add to v...
+ * @u: ...unless v is equal to u.
+ *
+ * Atomically adds @a to @v, so long as it was not @u.
+ * Returns non-zero if @v was not @u, and zero otherwise.
+ */
+#define atomic64_add_unless(v, a, u) \
+({ \
+ __typeof__((v)->counter) c, old; \
+ c = atomic_read(v); \
+ while (c != (u) && (old = atomic64_cmpxchg((v), c, c + (a))) != c) \
+ c = old; \
+ c != (u); \
+})
+#define atomic64_inc_not_zero(v) atomic64_add_unless((v), 1, 0)
+
#define atomic64_dec_return(v) atomic64_sub_return(1,(v))
#define atomic64_inc_return(v) atomic64_add_return(1,(v))
OpenPGP public key: http://krystal.dyndns.org:8080/key/compudj.gpg
Key fingerprint: 8CD5 52C3 8E3C 4140 715F BA06 3F25 A8FE 3BAE 9A68
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH 4/9] atomic.h : ia64
2006-12-21 0:08 [PATCH 0/9] atomic.h : standardising atomic primitives Mathieu Desnoyers
` (2 preceding siblings ...)
2006-12-21 0:11 ` [PATCH 5/9] atomic.h : standardising atomic primitives Mathieu Desnoyers
@ 2006-12-21 0:11 ` Mathieu Desnoyers
2006-12-21 0:12 ` [PATCH 6/9] atomic.h : parisc Mathieu Desnoyers
` (4 subsequent siblings)
8 siblings, 0 replies; 13+ messages in thread
From: Mathieu Desnoyers @ 2006-12-21 0:11 UTC (permalink / raw)
To: linux-kernel, Andrew Morton, Ingo Molnar, Greg Kroah-Hartman,
Christoph Hellwig
Cc: ltt-dev, systemtap, Douglas Niehaus, Martin J. Bligh, Thomas Gleixner
64 bits cmpxchg, xchg and add_unless for ia64.
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca>
--- a/include/asm-ia64/atomic.h
+++ b/include/asm-ia64/atomic.h
@@ -88,12 +88,17 @@ ia64_atomic64_sub (__s64 i, atomic64_t *
return new;
}
-#define atomic_cmpxchg(v, old, new) ((int)cmpxchg(&((v)->counter), old, new))
+#define atomic_cmpxchg(v, old, new) \
+ ((__typeof__((v)->counter))cmpxchg(&((v)->counter), old, new))
#define atomic_xchg(v, new) (xchg(&((v)->counter), new))
+#define atomic64_cmpxchg(v, old, new) \
+ ((__typeof__((v)->counter))cmpxchg(&((v)->counter), old, new))
+#define atomic64_xchg(v, new) (xchg(&((v)->counter), new))
+
#define atomic_add_unless(v, a, u) \
({ \
- int c, old; \
+ __typeof__(v->counter) c, old; \
c = atomic_read(v); \
for (;;) { \
if (unlikely(c == (u))) \
@@ -107,6 +112,22 @@ ({ \
})
#define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0)
+#define atomic64_add_unless(v, a, u) \
+({ \
+ __typeof__(v->counter) c, old; \
+ c = atomic64_read(v); \
+ for (;;) { \
+ if (unlikely(c == (u))) \
+ break; \
+ old = atomic64_cmpxchg((v), c, c + (a)); \
+ if (likely(old == c)) \
+ break; \
+ c = old; \
+ } \
+ c != (u); \
+})
+#define atomic64_inc_not_zero(v) atomic64_add_unless((v), 1, 0)
+
#define atomic_add_return(i,v) \
({ \
int __ia64_aar_i = (i); \
OpenPGP public key: http://krystal.dyndns.org:8080/key/compudj.gpg
Key fingerprint: 8CD5 52C3 8E3C 4140 715F BA06 3F25 A8FE 3BAE 9A68
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH 6/9] atomic.h : parisc
2006-12-21 0:08 [PATCH 0/9] atomic.h : standardising atomic primitives Mathieu Desnoyers
` (3 preceding siblings ...)
2006-12-21 0:11 ` [PATCH 4/9] atomic.h : ia64 Mathieu Desnoyers
@ 2006-12-21 0:12 ` Mathieu Desnoyers
2006-12-21 0:13 ` [PATCH 1/9] atomic.h : alpha architecture Mathieu Desnoyers
` (3 subsequent siblings)
8 siblings, 0 replies; 13+ messages in thread
From: Mathieu Desnoyers @ 2006-12-21 0:12 UTC (permalink / raw)
To: linux-kernel, Andrew Morton, Ingo Molnar, Greg Kroah-Hartman,
Christoph Hellwig
Cc: ltt-dev, systemtap, Douglas Niehaus, Martin J. Bligh, Thomas Gleixner
64 bits cmpxchg, xchg, add_unless operations for parisc.
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca>
--- a/include/asm-parisc/atomic.h
+++ b/include/asm-parisc/atomic.h
@@ -163,7 +163,8 @@ static __inline__ int atomic_read(const
}
/* exported interface */
-#define atomic_cmpxchg(v, o, n) ((int)cmpxchg(&((v)->counter), (o), (n)))
+#define atomic_cmpxchg(v, o, n) \
+ ((__typeof__((v)->counter))cmpxchg(&((v)->counter), (o), (n)))
#define atomic_xchg(v, new) (xchg(&((v)->counter), new))
/**
@@ -177,7 +178,7 @@ #define atomic_xchg(v, new) (xchg(&((v)-
*/
#define atomic_add_unless(v, a, u) \
({ \
- int c, old; \
+ __typeof__((v)->counter) c, old; \
c = atomic_read(v); \
while (c != (u) && (old = atomic_cmpxchg((v), c, c + (a))) != c) \
c = old; \
@@ -270,6 +271,31 @@ #define atomic64_inc_and_test(v) (atomi
#define atomic64_dec_and_test(v) (atomic64_dec_return(v) == 0)
#define atomic64_sub_and_test(i,v) (atomic64_sub_return((i),(v)) == 0)
+/* exported interface */
+#define atomic64_cmpxchg(v, o, n) \
+ ((__typeof__((v)->counter))cmpxchg(&((v)->counter), (o), (n)))
+#define atomic64_xchg(v, new) (xchg(&((v)->counter), new))
+
+/**
+ * atomic64_add_unless - add unless the number is a given value
+ * @v: pointer of type atomic64_t
+ * @a: the amount to add to v...
+ * @u: ...unless v is equal to u.
+ *
+ * Atomically adds @a to @v, so long as it was not @u.
+ * Returns non-zero if @v was not @u, and zero otherwise.
+ */
+#define atomic64_add_unless(v, a, u) \
+({ \
+ __typeof__((v)->counter) c, old; \
+ c = atomic64_read(v); \
+ while (c != (u) && (old = atomic64_cmpxchg((v), c, c + (a))) != c) \
+ c = old; \
+ c != (u); \
+})
+#define atomic64_inc_not_zero(v) atomic64_add_unless((v), 1, 0)
+
+
#endif /* __LP64__ */
#include <asm-generic/atomic.h>
OpenPGP public key: http://krystal.dyndns.org:8080/key/compudj.gpg
Key fingerprint: 8CD5 52C3 8E3C 4140 715F BA06 3F25 A8FE 3BAE 9A68
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH 1/9] atomic.h : alpha architecture
2006-12-21 0:08 [PATCH 0/9] atomic.h : standardising atomic primitives Mathieu Desnoyers
` (4 preceding siblings ...)
2006-12-21 0:12 ` [PATCH 6/9] atomic.h : parisc Mathieu Desnoyers
@ 2006-12-21 0:13 ` Mathieu Desnoyers
2006-12-21 0:14 ` [PATCH 7/9] atomic.h : powerpc Mathieu Desnoyers
` (2 subsequent siblings)
8 siblings, 0 replies; 13+ messages in thread
From: Mathieu Desnoyers @ 2006-12-21 0:13 UTC (permalink / raw)
To: linux-kernel, Andrew Morton, Ingo Molnar, Greg Kroah-Hartman,
Christoph Hellwig
Cc: ltt-dev, systemtap, Douglas Niehaus, Martin J. Bligh, Thomas Gleixner
This patch adds atomic64_cmpxchg, atomic64_xchg and atomic64_add_unless to
alpha.
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca>
--- a/include/asm-alpha/atomic.h
+++ b/include/asm-alpha/atomic.h
@@ -175,19 +175,64 @@ static __inline__ long atomic64_sub_retu
return result;
}
-#define atomic_cmpxchg(v, o, n) ((int)cmpxchg(&((v)->counter), (o), (n)))
+#define atomic64_cmpxchg(v, old, new) \
+ ((__typeof__((v)->counter))cmpxchg(&((v)->counter), old, new))
+#define atomic64_xchg(v, new) (xchg(&((v)->counter), new))
+
+#define atomic_cmpxchg(v, old, new) \
+ ((__typeof__((v)->counter))cmpxchg(&((v)->counter), old, new))
#define atomic_xchg(v, new) (xchg(&((v)->counter), new))
+/**
+ * atomic_add_unless - add unless the number is 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 it was not @u.
+ * Returns non-zero if @v was not @u, and zero otherwise.
+ */
#define atomic_add_unless(v, a, u) \
({ \
- int c, old; \
+ __typeof__((v)->counter) c, old; \
c = atomic_read(v); \
- while (c != (u) && (old = atomic_cmpxchg((v), c, c + (a))) != c) \
+ for (;;) { \
+ if (unlikely(c == (u))) \
+ break; \
+ old = atomic_cmpxchg((v), c, c + (a)); \
+ if (likely(old == c)) \
+ break; \
c = old; \
+ } \
c != (u); \
})
#define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0)
+/**
+ * atomic64_add_unless - add unless the number is a given value
+ * @v: pointer of type atomic64_t
+ * @a: the amount to add to v...
+ * @u: ...unless v is equal to u.
+ *
+ * Atomically adds @a to @v, so long as it was not @u.
+ * Returns non-zero if @v was not @u, and zero otherwise.
+ */
+#define atomic64_add_unless(v, a, u) \
+({ \
+ __typeof__((v)->counter) c, old; \
+ c = atomic64_read(v); \
+ for (;;) { \
+ if (unlikely(c == (u))) \
+ break; \
+ old = atomic64_cmpxchg((v), c, c + (a)); \
+ if (likely(old == c)) \
+ break; \
+ c = old; \
+ } \
+ c != (u); \
+})
+#define atomic64_inc_not_zero(v) atomic64_add_unless((v), 1, 0)
+
#define atomic_add_negative(a, v) (atomic_add_return((a), (v)) < 0)
#define atomic64_add_negative(a, v) (atomic64_add_return((a), (v)) < 0)
OpenPGP public key: http://krystal.dyndns.org:8080/key/compudj.gpg
Key fingerprint: 8CD5 52C3 8E3C 4140 715F BA06 3F25 A8FE 3BAE 9A68
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH 7/9] atomic.h : powerpc
2006-12-21 0:08 [PATCH 0/9] atomic.h : standardising atomic primitives Mathieu Desnoyers
` (5 preceding siblings ...)
2006-12-21 0:13 ` [PATCH 1/9] atomic.h : alpha architecture Mathieu Desnoyers
@ 2006-12-21 0:14 ` Mathieu Desnoyers
2006-12-21 3:40 ` Benjamin Herrenschmidt
2006-12-21 0:15 ` [PATCH 8/9] atomic.h : sparc Mathieu Desnoyers
2006-12-21 0:21 ` [PATCH 9/9] atomic.h : x86_64 Mathieu Desnoyers
8 siblings, 1 reply; 13+ messages in thread
From: Mathieu Desnoyers @ 2006-12-21 0:14 UTC (permalink / raw)
To: linux-kernel, Andrew Morton, Ingo Molnar, Greg Kroah-Hartman,
Christoph Hellwig, paulus
Cc: ltt-dev, systemtap, linuxppc-dev, Douglas Niehaus,
Martin J. Bligh, Thomas Gleixner
64 bits cmpxchg, xchg and add_unless for powerpc.
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca>
--- a/include/asm-powerpc/atomic.h
+++ b/include/asm-powerpc/atomic.h
@@ -165,7 +165,8 @@ static __inline__ int atomic_dec_return(
return t;
}
-#define atomic_cmpxchg(v, o, n) ((int)cmpxchg(&((v)->counter), (o), (n)))
+#define atomic_cmpxchg(v, o, n) \
+ ((__typeof__((v)->counter))cmpxchg(&((v)->counter), (o), (n)))
#define atomic_xchg(v, new) (xchg(&((v)->counter), new))
/**
@@ -411,6 +412,44 @@ static __inline__ long atomic64_dec_if_p
return t;
}
+#define atomic64_cmpxchg(v, o, n) \
+ ((__typeof__((v)->counter))cmpxchg(&((v)->counter), (o), (n)))
+#define atomic64_xchg(v, new) (xchg(&((v)->counter), new))
+
+/**
+ * atomic64_add_unless - add unless the number is a given value
+ * @v: pointer of type atomic64_t
+ * @a: the amount to add to v...
+ * @u: ...unless v is equal to u.
+ *
+ * Atomically adds @a to @v, so long as it was not @u.
+ * Returns non-zero if @v was not @u, and zero otherwise.
+ */
+static __inline__ int atomic64_add_unless(atomic64_t *v, long a, long u)
+{
+ long t;
+
+ __asm__ __volatile__ (
+ LWSYNC_ON_SMP
+"1: ldarx %0,0,%1 # atomic_add_unless\n\
+ cmpd 0,%0,%3 \n\
+ beq- 2f \n\
+ add %0,%2,%0 \n"
+ PPC405_ERR77(0,%2)
+" stdcx. %0,0,%1 \n\
+ bne- 1b \n"
+ ISYNC_ON_SMP
+" subf %0,%2,%0 \n\
+2:"
+ : "=&r" (t)
+ : "r" (&v->counter), "r" (a), "r" (u)
+ : "cc", "memory");
+
+ return t != u;
+}
+
+#define atomic64_inc_not_zero(v) atomic64_add_unless((v), 1, 0)
+
#endif /* __powerpc64__ */
#include <asm-generic/atomic.h>
OpenPGP public key: http://krystal.dyndns.org:8080/key/compudj.gpg
Key fingerprint: 8CD5 52C3 8E3C 4140 715F BA06 3F25 A8FE 3BAE 9A68
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH 8/9] atomic.h : sparc
2006-12-21 0:08 [PATCH 0/9] atomic.h : standardising atomic primitives Mathieu Desnoyers
` (6 preceding siblings ...)
2006-12-21 0:14 ` [PATCH 7/9] atomic.h : powerpc Mathieu Desnoyers
@ 2006-12-21 0:15 ` Mathieu Desnoyers
2006-12-21 0:21 ` [PATCH 9/9] atomic.h : x86_64 Mathieu Desnoyers
8 siblings, 0 replies; 13+ messages in thread
From: Mathieu Desnoyers @ 2006-12-21 0:15 UTC (permalink / raw)
To: linux-kernel, Andrew Morton, Ingo Molnar, Greg Kroah-Hartman,
Christoph Hellwig
Cc: ltt-dev, systemtap, Douglas Niehaus, Martin J. Bligh, Thomas Gleixner
64 bits cmpxchg, xchg and add_unless for sparc.
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca>
--- a/include/asm-sparc64/atomic.h
+++ b/include/asm-sparc64/atomic.h
@@ -70,12 +70,13 @@ #define atomic64_dec(v) atomic64_sub(1,
#define atomic_add_negative(i, v) (atomic_add_ret(i, v) < 0)
#define atomic64_add_negative(i, v) (atomic64_add_ret(i, v) < 0)
-#define atomic_cmpxchg(v, o, n) ((int)cmpxchg(&((v)->counter), (o), (n)))
+#define atomic_cmpxchg(v, o, n) \
+ ((__typeof__((v)->counter))cmpxchg(&((v)->counter), (o), (n)))
#define atomic_xchg(v, new) (xchg(&((v)->counter), new))
#define atomic_add_unless(v, a, u) \
({ \
- int c, old; \
+ __typeof__((v)->counter) c, old; \
c = atomic_read(v); \
for (;;) { \
if (unlikely(c == (u))) \
@@ -89,6 +90,26 @@ ({ \
})
#define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0)
+#define atomic64_cmpxchg(v, o, n) \
+ ((__typeof__((v)->counter))cmpxchg(&((v)->counter), (o), (n)))
+#define atomic64_xchg(v, new) (xchg(&((v)->counter), new))
+
+#define atomic64_add_unless(v, a, u) \
+({ \
+ __typeof__((v)->counter) c, old; \
+ c = atomic64_read(v); \
+ for (;;) { \
+ if (unlikely(c == (u))) \
+ break; \
+ old = atomic64_cmpxchg((v), c, c + (a)); \
+ if (likely(old == c)) \
+ break; \
+ c = old; \
+ } \
+ likely(c != (u)); \
+})
+#define atomic64_inc_not_zero(v) atomic64_add_unless((v), 1, 0)
+
/* Atomic operations are already serializing */
#ifdef CONFIG_SMP
#define smp_mb__before_atomic_dec() membar_storeload_loadload();
OpenPGP public key: http://krystal.dyndns.org:8080/key/compudj.gpg
Key fingerprint: 8CD5 52C3 8E3C 4140 715F BA06 3F25 A8FE 3BAE 9A68
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH 9/9] atomic.h : x86_64
2006-12-21 0:08 [PATCH 0/9] atomic.h : standardising atomic primitives Mathieu Desnoyers
` (7 preceding siblings ...)
2006-12-21 0:15 ` [PATCH 8/9] atomic.h : sparc Mathieu Desnoyers
@ 2006-12-21 0:21 ` Mathieu Desnoyers
2006-12-21 22:27 ` [PATCH] atomic.h : x86_64 atomic64_add_return Mathieu Desnoyers
8 siblings, 1 reply; 13+ messages in thread
From: Mathieu Desnoyers @ 2006-12-21 0:21 UTC (permalink / raw)
To: linux-kernel, Andrew Morton, Ingo Molnar, Greg Kroah-Hartman,
Christoph Hellwig
Cc: ltt-dev, systemtap, Douglas Niehaus, Martin J. Bligh, Thomas Gleixner
64 bits cmpxchg, xchg and add_less for x86_64.
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca>
--- a/include/asm-x86_64/atomic.h
+++ b/include/asm-x86_64/atomic.h
@@ -388,7 +388,12 @@ static __inline__ long atomic64_sub_retu
#define atomic64_inc_return(v) (atomic64_add_return(1,v))
#define atomic64_dec_return(v) (atomic64_sub_return(1,v))
-#define atomic_cmpxchg(v, old, new) ((int)cmpxchg(&((v)->counter), old, new))
+#define atomic64_cmpxchg(v, old, new) \
+ ((__typeof__((v)->counter))cmpxchg(&((v)->counter), old, new))
+#define atomic64_xchg(v, new) (xchg(&((v)->counter), new))
+
+#define atomic_cmpxchg(v, old, new) \
+ ((__typeof__((v)->counter))cmpxchg(&((v)->counter), old, new))
#define atomic_xchg(v, new) (xchg(&((v)->counter), new))
/**
@@ -402,7 +407,7 @@ #define atomic_xchg(v, new) (xchg(&((v)-
*/
#define atomic_add_unless(v, a, u) \
({ \
- int c, old; \
+ __typeof__((v)->counter) c, old; \
c = atomic_read(v); \
for (;;) { \
if (unlikely(c == (u))) \
@@ -416,6 +421,31 @@ ({ \
})
#define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0)
+/**
+ * atomic64_add_unless - add unless the number is a given value
+ * @v: pointer of type atomic64_t
+ * @a: the amount to add to v...
+ * @u: ...unless v is equal to u.
+ *
+ * Atomically adds @a to @v, so long as it was not @u.
+ * Returns non-zero if @v was not @u, and zero otherwise.
+ */
+#define atomic64_add_unless(v, a, u) \
+({ \
+ __typeof__((v)->counter) c, old; \
+ c = atomic64_read(v); \
+ for (;;) { \
+ if (unlikely(c == (u))) \
+ break; \
+ old = atomic64_cmpxchg((v), c, c + (a)); \
+ if (likely(old == c)) \
+ break; \
+ c = old; \
+ } \
+ c != (u); \
+})
+#define atomic64_inc_not_zero(v) atomic64_add_unless((v), 1, 0)
+
/* These are x86-specific, used by some header files */
#define atomic_clear_mask(mask, addr) \
__asm__ __volatile__(LOCK_PREFIX "andl %0,%1" \
OpenPGP public key: http://krystal.dyndns.org:8080/key/compudj.gpg
Key fingerprint: 8CD5 52C3 8E3C 4140 715F BA06 3F25 A8FE 3BAE 9A68
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH 7/9] atomic.h : powerpc
2006-12-21 0:14 ` [PATCH 7/9] atomic.h : powerpc Mathieu Desnoyers
@ 2006-12-21 3:40 ` Benjamin Herrenschmidt
2006-12-21 10:32 ` Mathieu Desnoyers
0 siblings, 1 reply; 13+ messages in thread
From: Benjamin Herrenschmidt @ 2006-12-21 3:40 UTC (permalink / raw)
To: Mathieu Desnoyers
Cc: linux-kernel, Andrew Morton, Ingo Molnar, Greg Kroah-Hartman,
Christoph Hellwig, paulus, Martin J. Bligh, linuxppc-dev,
Douglas Niehaus, ltt-dev, systemtap, Thomas Gleixner
> +
> +/**
> + * atomic64_add_unless - add unless the number is a given value
> + * @v: pointer of type atomic64_t
> + * @a: the amount to add to v...
> + * @u: ...unless v is equal to u.
> + *
> + * Atomically adds @a to @v, so long as it was not @u.
> + * Returns non-zero if @v was not @u, and zero otherwise.
> + */
> +static __inline__ int atomic64_add_unless(atomic64_t *v, long a, long u)
> +{
> + long t;
> +
> + __asm__ __volatile__ (
> + LWSYNC_ON_SMP
> +"1: ldarx %0,0,%1 # atomic_add_unless\n\
> + cmpd 0,%0,%3 \n\
> + beq- 2f \n\
> + add %0,%2,%0 \n"
> + PPC405_ERR77(0,%2)
> +" stdcx. %0,0,%1 \n\
> + bne- 1b \n"
> + ISYNC_ON_SMP
> +" subf %0,%2,%0 \n\
> +2:"
> + : "=&r" (t)
> + : "r" (&v->counter), "r" (a), "r" (u)
> + : "cc", "memory");
> +
> + return t != u;
> +}
> +
You shouldn't try to define those when building 32 bits code... Also,
the PPC405 errata, as it's name implies, is specific to 405 cores which
are all 32 bits.
Ben.
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH 7/9] atomic.h : powerpc
2006-12-21 3:40 ` Benjamin Herrenschmidt
@ 2006-12-21 10:32 ` Mathieu Desnoyers
0 siblings, 0 replies; 13+ messages in thread
From: Mathieu Desnoyers @ 2006-12-21 10:32 UTC (permalink / raw)
To: Benjamin Herrenschmidt
Cc: linux-kernel, Andrew Morton, Ingo Molnar, Greg Kroah-Hartman,
Christoph Hellwig, paulus, Martin J. Bligh, linuxppc-dev,
Douglas Niehaus, ltt-dev, systemtap, Thomas Gleixner
* Benjamin Herrenschmidt (benh@kernel.crashing.org) wrote:
>
> > +
> > +/**
> > + * atomic64_add_unless - add unless the number is a given value
> > + * @v: pointer of type atomic64_t
> > + * @a: the amount to add to v...
> > + * @u: ...unless v is equal to u.
> > + *
> > + * Atomically adds @a to @v, so long as it was not @u.
> > + * Returns non-zero if @v was not @u, and zero otherwise.
> > + */
> > +static __inline__ int atomic64_add_unless(atomic64_t *v, long a, long u)
> > +{
> > + long t;
> > +
> > + __asm__ __volatile__ (
> > + LWSYNC_ON_SMP
> > +"1: ldarx %0,0,%1 # atomic_add_unless\n\
> > + cmpd 0,%0,%3 \n\
> > + beq- 2f \n\
> > + add %0,%2,%0 \n"
> > + PPC405_ERR77(0,%2)
> > +" stdcx. %0,0,%1 \n\
> > + bne- 1b \n"
> > + ISYNC_ON_SMP
> > +" subf %0,%2,%0 \n\
> > +2:"
> > + : "=&r" (t)
> > + : "r" (&v->counter), "r" (a), "r" (u)
> > + : "cc", "memory");
> > +
> > + return t != u;
> > +}
> > +
>
> You shouldn't try to define those when building 32 bits code... Also,
> the PPC405 errata, as it's name implies, is specific to 405 cores which
> are all 32 bits.
>
> Ben.
>
>
Hi Ben,
It is within a
#ifdef __powerpc64__
...
#endif /* __powerpc64__ */
so it should only build on 64 bits.
You are right about the PPC405 errata, it seems unnecessary.
The same is true for my asm-powerpc/local.h modification.
Thanks,
Mathieu
--
OpenPGP public key: http://krystal.dyndns.org:8080/key/compudj.gpg
Key fingerprint: 8CD5 52C3 8E3C 4140 715F BA06 3F25 A8FE 3BAE 9A68
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH] atomic.h : x86_64 atomic64_add_return
2006-12-21 0:21 ` [PATCH 9/9] atomic.h : x86_64 Mathieu Desnoyers
@ 2006-12-21 22:27 ` Mathieu Desnoyers
0 siblings, 0 replies; 13+ messages in thread
From: Mathieu Desnoyers @ 2006-12-21 22:27 UTC (permalink / raw)
To: linux-kernel, Andrew Morton, Ingo Molnar, Greg Kroah-Hartman,
Christoph Hellwig
Cc: Douglas Niehaus, Martin J. Bligh, ltt-dev, Thomas Gleixner, systemtap
atomic64_add_return fix for volatile removal
atomic64_add_return should follow the change done to atomic.h following the
removal of "volatile" in the atomic_t type, just like atomic_add_return.
It applies cleanly on top of my "atomic.h : x86_64" patch posted in this
thread.
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca>
diff --git a/include/asm-x86_64/atomic.h b/include/asm-x86_64/atomic.h
index e9922ae..3e9f838 100644
--- a/include/asm-x86_64/atomic.h
+++ b/include/asm-x86_64/atomic.h
@@ -375,8 +375,8 @@ static __inline__ long atomic64_add_retu
long __i = i;
__asm__ __volatile__(
LOCK_PREFIX "xaddq %0, %1;"
- :"=r"(i)
- :"m"(v->counter), "0"(i));
+ :"+r" (i), "+m" (v->counter)
+ : : "memory");
return i + __i;
}
--
OpenPGP public key: http://krystal.dyndns.org:8080/key/compudj.gpg
Key fingerprint: 8CD5 52C3 8E3C 4140 715F BA06 3F25 A8FE 3BAE 9A68
^ permalink raw reply [flat|nested] 13+ messages in thread
end of thread, other threads:[~2006-12-21 19:47 UTC | newest]
Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2006-12-21 0:08 [PATCH 0/9] atomic.h : standardising atomic primitives Mathieu Desnoyers
2006-12-21 0:09 ` [PATCH 2/9] atomic.h : generic atomic_long Mathieu Desnoyers
2006-12-21 0:10 ` [PATCH 3/9] atomic.h : i386 "64 bits" ready fix Mathieu Desnoyers
2006-12-21 0:11 ` [PATCH 5/9] atomic.h : standardising atomic primitives Mathieu Desnoyers
2006-12-21 0:11 ` [PATCH 4/9] atomic.h : ia64 Mathieu Desnoyers
2006-12-21 0:12 ` [PATCH 6/9] atomic.h : parisc Mathieu Desnoyers
2006-12-21 0:13 ` [PATCH 1/9] atomic.h : alpha architecture Mathieu Desnoyers
2006-12-21 0:14 ` [PATCH 7/9] atomic.h : powerpc Mathieu Desnoyers
2006-12-21 3:40 ` Benjamin Herrenschmidt
2006-12-21 10:32 ` Mathieu Desnoyers
2006-12-21 0:15 ` [PATCH 8/9] atomic.h : sparc Mathieu Desnoyers
2006-12-21 0:21 ` [PATCH 9/9] atomic.h : x86_64 Mathieu Desnoyers
2006-12-21 22:27 ` [PATCH] atomic.h : x86_64 atomic64_add_return Mathieu Desnoyers
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).