aboutsummaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
authorNick Piggin <nickpiggin@yahoo.com.au>2005-11-13 16:07:24 -0800
committerLinus Torvalds <torvalds@g5.osdl.org>2005-11-13 18:14:16 -0800
commit4a6dae6d382e9edf3ff440b819e554ed706359bc (patch)
tree2945a5095973e2ecf05b503d6deb859083045b8e /arch
parent53e86b91b7ae66d4c2757195cbd42e00d9199cf2 (diff)
[PATCH] atomic: cmpxchg
Introduce an atomic_cmpxchg operation. Signed-off-by: Nick Piggin <npiggin@suse.de> Cc: "Paul E. McKenney" <paulmck@us.ibm.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'arch')
-rw-r--r--arch/sparc/lib/atomic32.c21
1 files changed, 16 insertions, 5 deletions
diff --git a/arch/sparc/lib/atomic32.c b/arch/sparc/lib/atomic32.c
index 2e64e8c3e8e..be46f654518 100644
--- a/arch/sparc/lib/atomic32.c
+++ b/arch/sparc/lib/atomic32.c
@@ -37,17 +37,28 @@ int __atomic_add_return(int i, atomic_t *v)
spin_unlock_irqrestore(ATOMIC_HASH(v), flags);
return ret;
}
+EXPORT_SYMBOL(__atomic_add_return);
-void atomic_set(atomic_t *v, int i)
+int atomic_cmpxchg(atomic_t *v, int old, int new)
{
+ int ret;
unsigned long flags;
- spin_lock_irqsave(ATOMIC_HASH(v), flags);
- v->counter = i;
+ spin_lock_irqsave(ATOMIC_HASH(v), flags);
+ ret = v->counter;
+ if (likely(ret == old))
+ v->counter = new;
spin_unlock_irqrestore(ATOMIC_HASH(v), flags);
+ return ret;
}
-EXPORT_SYMBOL(__atomic_add_return);
-EXPORT_SYMBOL(atomic_set);
+void atomic_set(atomic_t *v, int i)
+{
+ unsigned long flags;
+ spin_lock_irqsave(ATOMIC_HASH(v), flags);
+ v->counter = i;
+ spin_unlock_irqrestore(ATOMIC_HASH(v), flags);
+}
+EXPORT_SYMBOL(atomic_set);