2007-01-25 16:16:00

by Mathieu Desnoyers

[permalink] [raw]
Subject: [PATCH 00/09] atomic.h : standardizing atomic primitives

atomic.h : standardizing atomic primitives

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 apply on 2.6.20-rc5-git4.

Signed-off-by : Mathieu Desnoyers <[email protected]>


2007-01-25 16:16:08

by Mathieu Desnoyers

[permalink] [raw]
Subject: [PATCH 04/09] atomic.h : Add atomic64 cmpxchg, xchg and add_unless to ia64

atomic.h : Add atomic64 cmpxchg, xchg and add_unless to ia64

Signed-off-by: Mathieu Desnoyers <[email protected]>

--- a/include/asm-ia64/atomic.h
+++ b/include/asm-ia64/atomic.h
@@ -88,12 +88,17 @@ ia64_atomic64_sub (__s64 i, atomic64_t *v)
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 @@ ia64_atomic64_sub (__s64 i, atomic64_t *v)
})
#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); \

2007-01-25 16:21:06

by Mathieu Desnoyers

[permalink] [raw]
Subject: [PATCH 02/09] atomic.h : Complete atomic_long operations in asm-generic

atomic.h : Complete atomic_long operations in asm-generic

Signed-off-by: Mathieu Desnoyers <[email protected]>

--- a/include/asm-generic/atomic.h
+++ b/include/asm-generic/atomic.h
@@ -66,6 +66,90 @@ static inline void atomic_long_sub(long i, atomic_long_t *l)
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 i, atomic_long_t *l)
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 */

2007-01-25 16:21:09

by Mathieu Desnoyers

[permalink] [raw]
Subject: [PATCH 06/09] atomic.h : Add atomic64 cmpxchg, xchg and add_unless to parisc

atomic.h : Add atomic64 cmpxchg, xchg and add_unless to parisc

Signed-off-by: Mathieu Desnoyers <[email protected]>

--- a/include/asm-parisc/atomic.h
+++ b/include/asm-parisc/atomic.h
@@ -163,7 +163,8 @@ static __inline__ int atomic_read(const atomic_t *v)
}

/* 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 @@ static __inline__ int atomic_read(const atomic_t *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 @@ atomic64_read(const atomic64_t *v)
#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>

2007-01-25 16:22:04

by Mathieu Desnoyers

[permalink] [raw]
Subject: [PATCH 05/09] atomic.h : Add atomic64 cmpxchg, xchg and add_unless to mips

atomic.h : Add atomic64 cmpxchg, xchg and add_unless to mips

Signed-off-by: Mathieu Desnoyers <[email protected]>

--- a/include/asm-mips/atomic.h
+++ b/include/asm-mips/atomic.h
@@ -291,8 +291,9 @@ static __inline__ int atomic_sub_if_positive(int i, atomic_t * v)
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 @@ static __inline__ int atomic_sub_if_positive(int i, atomic_t * 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_positive(long i, atomic64_t * v)
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))

2007-01-25 17:01:32

by Mathieu Desnoyers

[permalink] [raw]
Subject: [PATCH 01/09] atomic.h : Add atomic64 cmpxchg, xchg and add_unless to alpha

atomic.h : Add atomic64 cmpxchg, xchg and add_unless to alpha

Signed-off-by: Mathieu Desnoyers <[email protected]>

--- a/include/asm-alpha/atomic.h
+++ b/include/asm-alpha/atomic.h
@@ -175,19 +175,64 @@ static __inline__ long atomic64_sub_return(long i, atomic64_t * v)
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)

2007-01-25 17:06:35

by Mathieu Desnoyers

[permalink] [raw]
Subject: [PATCH 09/09] atomic.h : Add atomic64 cmpxchg, xchg and add_unless to x86_64

atomic.h : Add atomic64 cmpxchg, xchg and add_unless to x86_64

Signed-off-by: Mathieu Desnoyers <[email protected]>

--- a/include/asm-x86_64/atomic.h
+++ b/include/asm-x86_64/atomic.h
@@ -375,8 +375,8 @@ static __inline__ long atomic64_add_return(long i, atomic64_t *v)
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;
}

@@ -388,7 +388,12 @@ static __inline__ long atomic64_sub_return(long i, atomic64_t *v)
#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 @@ static __inline__ long atomic64_sub_return(long i, atomic64_t *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 @@ static __inline__ long atomic64_sub_return(long i, atomic64_t *v)
})
#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" \

2007-01-25 17:06:40

by Mathieu Desnoyers

[permalink] [raw]
Subject: [PATCH 07/09] atomic.h : Add atomic64 cmpxchg, xchg and add_unless to powerpc

atomic.h : Add atomic64 cmpxchg, xchg and add_unless to powerpc

Signed-off-by: Mathieu Desnoyers <[email protected]>

--- a/include/asm-powerpc/atomic.h
+++ b/include/asm-powerpc/atomic.h
@@ -165,7 +165,8 @@ static __inline__ int atomic_dec_return(atomic_t *v)
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))

/**
@@ -413,6 +414,43 @@ static __inline__ long atomic64_dec_if_positive(atomic64_t *v)
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"
+" 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>

2007-01-25 17:07:08

by Mathieu Desnoyers

[permalink] [raw]
Subject: [PATCH 08/09] atomic.h : Add atomic64 cmpxchg, xchg and add_unless to sparc64

atomic.h : Add atomic64 cmpxchg, xchg and add_unless to sparc64

Signed-off-by: Mathieu Desnoyers <[email protected]>

--- a/include/asm-sparc64/atomic.h
+++ b/include/asm-sparc64/atomic.h
@@ -70,12 +70,13 @@ extern int atomic64_sub_ret(int, atomic64_t *);
#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 @@ extern int atomic64_sub_ret(int, atomic64_t *);
})
#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();

2007-01-25 18:06:36

by Mathieu Desnoyers

[permalink] [raw]
Subject: [PATCH 03/09] atomic.h : i386 type safety fix

atomic.h : i386 type safety fix

This patch removes an explicit cast to an integer type for the result returned
by cmpxchg. It is not per se a problem on the i386 architecture, because
sizeof(int) == sizeof(long), but whenever this code is cut'n'pasted to a
different architecture (which happened at least for x86_64), it would simply
accept passing an atomic64_t value as parameter to cmpxchg, xchg and
add_unless, having 64 bits inputs casted to 32 bits.

Signed-off-by: Mathieu Desnoyers <[email protected]>

--- a/include/asm-i386/atomic.h
+++ b/include/asm-i386/atomic.h
@@ -207,8 +207,9 @@ static __inline__ int atomic_sub_return(int i, atomic_t *v)
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 @@ static __inline__ int atomic_sub_return(int i, atomic_t *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))) \

2007-01-26 02:54:46

by Mathieu Desnoyers

[permalink] [raw]
Subject: Re: [PATCH 02/09] atomic.h : Complete atomic_long operations in asm-generic

As Joe Perches pointed out, 4 casts to (long) are unneeded here.

The *_test functions only return integers, never a long.

Signed-off-by: Mathieu Desnoyers <[email protected]>

--- a/include/asm-generic/atomic.h
+++ b/include/asm-generic/atomic.h
@@ -70,28 +70,28 @@ 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);
+ return 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);
+ return 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);
+ return 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);
+ return atomic64_add_negative(i, v);
}

static inline long atomic_long_add_return(long i, atomic_long_t *l)
--
OpenPGP public key: http://krystal.dyndns.org:8080/key/compudj.gpg
Key fingerprint: 8CD5 52C3 8E3C 4140 715F BA06 3F25 A8FE 3BAE 9A68

2007-01-26 11:38:35

by Peter Zijlstra

[permalink] [raw]
Subject: Re: [PATCH 00/09] atomic.h : standardizing atomic primitives

On Thu, 2007-01-25 at 11:15 -0500, Mathieu Desnoyers wrote:
> atomic.h : standardizing atomic primitives
>
> 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 apply on 2.6.20-rc5-git4.

ARCH=um SUBARCH=i386

In file included from include2/asm/arch/atomic.h:257,
from include2/asm/atomic.h:10,
from /usr/src/linux-2.6-git/include/linux/file.h:9,
from /usr/src/linux-2.6-git/mm/fadvise.c:12:
/usr/src/linux-2.6-git/include/asm-generic/atomic.h: In function ‘atomic_long_add_unless’:
/usr/src/linux-2.6-git/include/asm-generic/atomic.h:260: warning: implicit declaration of function ‘cmpxchg’
/usr/src/linux-2.6-git/include/asm-generic/atomic.h: In function ‘atomic_long_xchg’:
/usr/src/linux-2.6-git/include/asm-generic/atomic.h:281: warning: implicit declaration of function ‘xchg’


Signed-off-by: Peter Zijlstra <[email protected]>
---
diff --git a/include/asm-um/atomic.h b/include/asm-um/atomic.h
index b683f10..b2766b0 100644
--- a/include/asm-um/atomic.h
+++ b/include/asm-um/atomic.h
@@ -6,6 +6,7 @@ #define __UM_ATOMIC_H
*/
#include "linux/kernel.h"

+#include "asm/arch/system.h"
#include "asm/arch/atomic.h"

#endif


2007-01-26 16:01:32

by Mathieu Desnoyers

[permalink] [raw]
Subject: Re: [PATCH 00/09] atomic.h : standardizing atomic primitives

* Peter Zijlstra ([email protected]) wrote:
> On Thu, 2007-01-25 at 11:15 -0500, Mathieu Desnoyers wrote:
> > atomic.h : standardizing atomic primitives
> >
> > 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 apply on 2.6.20-rc5-git4.
>
> ARCH=um SUBARCH=i386
>
> In file included from include2/asm/arch/atomic.h:257,
> from include2/asm/atomic.h:10,
> from /usr/src/linux-2.6-git/include/linux/file.h:9,
> from /usr/src/linux-2.6-git/mm/fadvise.c:12:
> /usr/src/linux-2.6-git/include/asm-generic/atomic.h: In function ‘atomic_long_add_unless’:
> /usr/src/linux-2.6-git/include/asm-generic/atomic.h:260: warning: implicit declaration of function ‘cmpxchg’
> /usr/src/linux-2.6-git/include/asm-generic/atomic.h: In function ‘atomic_long_xchg’:
> /usr/src/linux-2.6-git/include/asm-generic/atomic.h:281: warning: implicit declaration of function ‘xchg’
>
>
> Signed-off-by: Peter Zijlstra <[email protected]>
> ---
> diff --git a/include/asm-um/atomic.h b/include/asm-um/atomic.h
> index b683f10..b2766b0 100644
> --- a/include/asm-um/atomic.h
> +++ b/include/asm-um/atomic.h
> @@ -6,6 +6,7 @@ #define __UM_ATOMIC_H
> */
> #include "linux/kernel.h"
>
> +#include "asm/arch/system.h"
> #include "asm/arch/atomic.h"
>
> #endif
>
>

Thanks for the fix,

Acked-by: Mathieu Desnoyers <[email protected]>


--
OpenPGP public key: http://krystal.dyndns.org:8080/key/compudj.gpg
Key fingerprint: 8CD5 52C3 8E3C 4140 715F BA06 3F25 A8FE 3BAE 9A68

2007-01-27 09:49:13

by Andrew Morton

[permalink] [raw]
Subject: Re: [PATCH 00/09] atomic.h : standardizing atomic primitives

On Thu, 25 Jan 2007 11:15:45 -0500
Mathieu Desnoyers <[email protected]> wrote:

> 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.

Can you do s390 please?

2007-01-27 10:19:39

by Andrew Morton

[permalink] [raw]
Subject: Re: [PATCH 00/09] atomic.h : standardizing atomic primitives

On Thu, 25 Jan 2007 11:15:45 -0500
Mathieu Desnoyers <[email protected]> wrote:

> 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.

OK, I fixed eight separate compile errors in this patch series and
now powerpc is being very ugly with a twisty maze of include dependencies.

I'm giving up. Someone should publish a suite of cross-compilers for us
so stuff like this doesn't need to happen.

2007-01-27 17:31:29

by Mathieu Desnoyers

[permalink] [raw]
Subject: Re: [PATCH 00/09] atomic.h : standardizing atomic primitives

* Andrew Morton ([email protected]) wrote:
> On Thu, 25 Jan 2007 11:15:45 -0500
> Mathieu Desnoyers <[email protected]> wrote:
>
> > 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.
>
> OK, I fixed eight separate compile errors in this patch series and
> now powerpc is being very ugly with a twisty maze of include dependencies.
>
> I'm giving up. Someone should publish a suite of cross-compilers for us
> so stuff like this doesn't need to happen.

Hi Andrew,

This seems to be caused by the fact that I use inline functions for
atomic_long_cmpxchg and atomic_long_xchg. I could simply use macros and
this problem would fade away.

I agree about the cross-compiler suite, it would be very useful here.

Mathieu

--
OpenPGP public key: http://krystal.dyndns.org:8080/key/compudj.gpg
Key fingerprint: 8CD5 52C3 8E3C 4140 715F BA06 3F25 A8FE 3BAE 9A68

2007-01-27 18:11:22

by Mathieu Desnoyers

[permalink] [raw]
Subject: Re: [Ltt-dev] [PATCH 00/09] atomic.h : standardizing atomic primitives

* Andrew Morton ([email protected]) wrote:
> I'm giving up. Someone should publish a suite of cross-compilers for us
> so stuff like this doesn't need to happen.

Hi Andrew,

I am currently trying crosstool by Dan Kegel, it looks promising.
http://www.kegel.com/crosstool/

I will let you know more when my cross compiler chain is set up.

Mathieu


--
OpenPGP public key: http://krystal.dyndns.org:8080/key/compudj.gpg
Key fingerprint: 8CD5 52C3 8E3C 4140 715F BA06 3F25 A8FE 3BAE 9A68

2007-01-27 20:06:09

by Andrew Morton

[permalink] [raw]
Subject: Re: [Ltt-dev] [PATCH 00/09] atomic.h : standardizing atomic primitives

On Sat, 27 Jan 2007 13:11:16 -0500
Mathieu Desnoyers <[email protected]> wrote:

> I am currently trying crosstool by Dan Kegel, it looks promising.
> http://www.kegel.com/crosstool/

Yeah, I spent a frustrating two days with crosstool, managed to eke a
number of cross-compilers out of it, but it took a *lot* of experimentation
with gcc, glibc and binutils versions to get combinations which actually
work. Good luck ;)

There used to be someone who had a full suite, and who regularly published
cross-compile results, but he stopped 6-12 months ago and I forget who that
clever person was?

2007-01-27 20:10:40

by Willy Tarreau

[permalink] [raw]
Subject: Re: [Ltt-dev] [PATCH 00/09] atomic.h : standardizing atomic primitives

On Sat, Jan 27, 2007 at 12:05:12PM -0800, Andrew Morton wrote:
> On Sat, 27 Jan 2007 13:11:16 -0500
> Mathieu Desnoyers <[email protected]> wrote:
>
> > I am currently trying crosstool by Dan Kegel, it looks promising.
> > http://www.kegel.com/crosstool/
>
> Yeah, I spent a frustrating two days with crosstool, managed to eke a
> number of cross-compilers out of it, but it took a *lot* of experimentation
> with gcc, glibc and binutils versions to get combinations which actually
> work. Good luck ;)
>
> There used to be someone who had a full suite, and who regularly published
> cross-compile results, but he stopped 6-12 months ago and I forget who that
> clever person was?

Wasn't it buildroot from Erik Andersen ?

http://buildroot.uclibc.org/

Willy

2007-01-27 20:31:15

by Andrew Morton

[permalink] [raw]
Subject: Re: [Ltt-dev] [PATCH 00/09] atomic.h : standardizing atomic primitives

On Sat, 27 Jan 2007 21:09:11 +0100
Willy Tarreau <[email protected]> wrote:

> On Sat, Jan 27, 2007 at 12:05:12PM -0800, Andrew Morton wrote:
> > On Sat, 27 Jan 2007 13:11:16 -0500
> > Mathieu Desnoyers <[email protected]> wrote:
> >
> > > I am currently trying crosstool by Dan Kegel, it looks promising.
> > > http://www.kegel.com/crosstool/
> >
> > Yeah, I spent a frustrating two days with crosstool, managed to eke a
> > number of cross-compilers out of it, but it took a *lot* of experimentation
> > with gcc, glibc and binutils versions to get combinations which actually
> > work. Good luck ;)
> >
> > There used to be someone who had a full suite, and who regularly published
> > cross-compile results, but he stopped 6-12 months ago and I forget who that
> > clever person was?
>
> Wasn't it buildroot from Erik Andersen ?
>
> http://buildroot.uclibc.org/
>

No, it was http://l4x.org/k/ It still appears to be operating, with
scary-looking results.

Jan, is there any way in which you can help us publish a full suite of
cross-compiler binaries?

2007-01-27 20:33:55

by Martin Bligh

[permalink] [raw]
Subject: Re: [Ltt-dev] [PATCH 00/09] atomic.h : standardizing atomic primitives

> > Wasn't it buildroot from Erik Andersen ?
> >
> > http://buildroot.uclibc.org/
> >
>
> No, it was http://l4x.org/k/ It still appears to be operating, with
> scary-looking results.
>
> Jan, is there any way in which you can help us publish a full suite of
> cross-compiler binaries?

That's going to be tricky, even if they're statically linked, what architecture
do you want them for, etc? Plus some things seem to just refuse to statically
link now (anything with resolver code, though maybe gcc doesn't care).

If we can get the crosstool configs to build all that stuff ourselves,
for any platform, would be more flexible, IMHO.

M.

2007-01-27 23:05:26

by Jan Dittmer

[permalink] [raw]
Subject: Re: [Ltt-dev] [PATCH 00/09] atomic.h : standardizing atomic primitives

Andrew Morton wrote:
> On Sat, 27 Jan 2007 21:09:11 +0100
> Willy Tarreau <[email protected]> wrote:
>
>> On Sat, Jan 27, 2007 at 12:05:12PM -0800, Andrew Morton wrote:
>>> On Sat, 27 Jan 2007 13:11:16 -0500
>>> Mathieu Desnoyers <[email protected]> wrote:
>>>
>>>> I am currently trying crosstool by Dan Kegel, it looks promising.
>>>> http://www.kegel.com/crosstool/
>>> Yeah, I spent a frustrating two days with crosstool, managed to eke a
>>> number of cross-compilers out of it, but it took a *lot* of experimentation
>>> with gcc, glibc and binutils versions to get combinations which actually
>>> work. Good luck ;)
>>>
>>> There used to be someone who had a full suite, and who regularly published
>>> cross-compile results, but he stopped 6-12 months ago and I forget who that
>>> clever person was?
>> Wasn't it buildroot from Erik Andersen ?
>>
>> http://buildroot.uclibc.org/
>>
>
> No, it was http://l4x.org/k/ It still appears to be operating, with
> scary-looking results.
>
> Jan, is there any way in which you can help us publish a full suite of
> cross-compiler binaries?

Probably not. I could publish a qemu i386 image with all cross compilers
though. But some are not build from source but are obtained from more or
less obscure sources (m32r, sh64). Currently this

CHK include/linux/utsrelease.h
"2.6.20-rc6cat:include/config/kernel.release:Nosuchfileordirectory" exceeds 64 characters
make[1]: *** [include/linux/utsrelease.h] Error 1
make: *** [_all] Error 2

bug, which I reported weeks ago, makes the result invalid for most
archs. But as I get nearly zero feedback about the results and I've
lots of other obligations currently, my motivation to work on that is
pretty much nil.

Jan

2007-01-29 18:40:00

by Richard Purdie

[permalink] [raw]
Subject: Re: [Ltt-dev] [PATCH 00/09] atomic.h : standardizing atomic primitives

On Sat, 2007-01-27 at 12:05 -0800, Andrew Morton wrote:
> On Sat, 27 Jan 2007 13:11:16 -0500
> Mathieu Desnoyers <[email protected]> wrote:
>
> > I am currently trying crosstool by Dan Kegel, it looks promising.
> > http://www.kegel.com/crosstool/
>
> Yeah, I spent a frustrating two days with crosstool, managed to eke a
> number of cross-compilers out of it, but it took a *lot* of experimentation
> with gcc, glibc and binutils versions to get combinations which actually
> work. Good luck ;)

FWIW, OpenEmbedded (http://www.openembedded.org/) is a very capable
toolchain builder amongst other things. I built an ARM toolchain for
Andrew a while back with it. I'm personally not sure of its support
outside ARM/i386 since I don't have hardware to test any other output
but others use it for a variety of targets and new ones are simple to
add due to its design.

I could probably arrange to share an ARM toolchain if there was
demand...

Richard





2007-01-29 18:56:53

by Randy Dunlap

[permalink] [raw]
Subject: Re: [Ltt-dev] [PATCH 00/09] atomic.h : standardizing atomic primitives

On Mon, 29 Jan 2007 18:36:49 +0000 Richard Purdie wrote:

> On Sat, 2007-01-27 at 12:05 -0800, Andrew Morton wrote:
> > On Sat, 27 Jan 2007 13:11:16 -0500
> > Mathieu Desnoyers <[email protected]> wrote:
> >
> > > I am currently trying crosstool by Dan Kegel, it looks promising.
> > > http://www.kegel.com/crosstool/
> >
> > Yeah, I spent a frustrating two days with crosstool, managed to eke a
> > number of cross-compilers out of it, but it took a *lot* of experimentation
> > with gcc, glibc and binutils versions to get combinations which actually
> > work. Good luck ;)
>
> FWIW, OpenEmbedded (http://www.openembedded.org/) is a very capable
> toolchain builder amongst other things. I built an ARM toolchain for
> Andrew a while back with it. I'm personally not sure of its support
> outside ARM/i386 since I don't have hardware to test any other output
> but others use it for a variety of targets and new ones are simple to
> add due to its design.
>
> I could probably arrange to share an ARM toolchain if there was
> demand...

I'd certainly like to see/use it.

---
~Randy

2007-01-29 19:17:57

by Andrew Morton

[permalink] [raw]
Subject: Re: [Ltt-dev] [PATCH 00/09] atomic.h : standardizing atomic primitives

On Mon, 29 Jan 2007 10:49:43 -0800
Randy Dunlap <[email protected]> wrote:

> > I could probably arrange to share an ARM toolchain if there was
> > demand...
>
> I'd certainly like to see/use it.

http://userweb.kernel.org/~akpm/arm-cross.tar.bz2 works. It's linked
on FC5 x86, runs OK on FC6 and FC3 or thereabouts.