From 09740315d4b914203c25c56e8f8909b4fae7b32d Mon Sep 17 00:00:00 2001 From: Andrea Bastoni Date: Mon, 19 Apr 2010 19:28:07 -0400 Subject: Add atomic operations on x86_64 --- include/asm_x86.h | 66 +++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 64 insertions(+), 2 deletions(-) diff --git a/include/asm_x86.h b/include/asm_x86.h index 6636abb..ccc6cce 100644 --- a/include/asm_x86.h +++ b/include/asm_x86.h @@ -27,10 +27,10 @@ static inline void sti(void) { asm volatile("sti": : :"memory"); } -#ifdef __i386__ - typedef struct { int counter; } atomic_t; +#ifdef __i386__ + #define ATOMIC_INIT(i) { (i) } /** @@ -78,5 +78,67 @@ static __inline__ int atomic_add_return(int i, atomic_t *v) #define atomic_inc_return(v) (atomic_add_return(1,v)) +#elif defined(__x86_64__) + +/* almost the same as i386, but extra care must be taken when + * specifying clobbered registers + */ + +#define ATOMIC_INIT(i) { (i) } + +/** + * atomic_read - read atomic variable + * @v: pointer of type atomic_t + * + * Atomically reads the value of @v. + */ +static inline int atomic_read(const atomic_t *v) +{ + return v->counter; +} + +/** + * atomic_set - set atomic variable + * @v: pointer of type atomic_t + * @i: required value + * + * Atomically sets the value of @v to @i. + */ +static inline void atomic_set(atomic_t *v, int i) +{ + v->counter = i; +} + +/** + * atomic_add - add integer to atomic variable + * @i: integer value to add + * @v: pointer of type atomic_t + * + * Atomically adds @i to @v. + */ +static inline void atomic_add(int i, atomic_t *v) +{ + asm volatile("lock; addl %1,%0" + : "=m" (v->counter) + : "ir" (i), "m" (v->counter)); +} + +/** + * atomic_add_return - add and return + * @i: integer value to add + * @v: pointer of type atomic_t + * + * Atomically adds @i to @v and returns @i + @v + */ +static inline int atomic_add_return(int i, atomic_t *v) +{ + int __i = i; + asm volatile("lock; xaddl %0, %1" + : "+r" (i), "+m" (v->counter) + : : "memory"); + return i + __i; +} + +#define atomic_inc_return(v) (atomic_add_return(1, v)) #endif -- cgit v1.2.2