···22 * atomic32.c: 32-bit atomic_t implementation33 *44 * Copyright (C) 2004 Keith M Wesolowski55+ * Copyright (C) 2007 Kyle McMartin56 * 67 * Based on asm-parisc/atomic.h Copyright (C) 2000 Philipp Rumpf78 */···118117 return old & mask;119118}120119EXPORT_SYMBOL(___change_bit);120120+121121+unsigned long __cmpxchg_u32(volatile u32 *ptr, u32 old, u32 new)122122+{123123+ unsigned long flags;124124+ u32 prev;125125+126126+ spin_lock_irqsave(ATOMIC_HASH(addr), flags);127127+ if ((prev = *ptr) == old)128128+ *ptr = new;129129+ spin_unlock_irqrestore(ATOMIC_HASH(addr), flags);130130+131131+ return (unsigned long)prev;132132+}133133+EXPORT_SYMBOL(__cmpxchg_u32);
+38
include/asm-sparc/atomic.h
···22 *33 * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)44 * Copyright (C) 2000 Anton Blanchard (anton@linuxcare.com.au)55+ * Copyright (C) 2007 Kyle McMartin (kyle@parisc-linux.org)56 *67 * Additions by Keith M Wesolowski (wesolows@foobazco.org) based78 * on asm-parisc/atomic.h Copyright (C) 2000 Philipp Rumpf <prumpf@tux.org>.···1110#ifndef __ARCH_SPARC_ATOMIC__1211#define __ARCH_SPARC_ATOMIC__13121313+#include <linux/types.h>14141515typedef struct { volatile int counter; } atomic_t;16161717#ifdef __KERNEL__1818+1919+/* Emulate cmpxchg() the same way we emulate atomics,2020+ * by hashing the object address and indexing into an array2121+ * of spinlocks to get a bit of performance...2222+ *2323+ * See arch/sparc/lib/atomic32.c for implementation.2424+ *2525+ * Cribbed from <asm-parisc/atomic.h>2626+ */2727+#define __HAVE_ARCH_CMPXCHG 12828+2929+/* bug catcher for when unsupported size is used - won't link */3030+extern void __cmpxchg_called_with_bad_pointer(void);3131+/* we only need to support cmpxchg of a u32 on sparc */3232+extern unsigned long __cmpxchg_u32(volatile u32 *m, u32 old, u32 new_);3333+3434+/* don't worry...optimizer will get rid of most of this */3535+static __inline__ unsigned long3636+__cmpxchg(volatile void *ptr, unsigned long old, unsigned long new_, int size)3737+{3838+ switch(size) {3939+ case 4:4040+ return __cmpxchg_u32((u32 *)ptr, (u32)old, (u32)new_);4141+ default:4242+ __cmpxchg_called_with_bad_pointer();4343+ break;4444+ }4545+ return old;4646+}4747+4848+#define cmpxchg(ptr,o,n) ({ \4949+ __typeof__(*(ptr)) _o_ = (o); \5050+ __typeof__(*(ptr)) _n_ = (n); \5151+ (__typeof__(*(ptr))) __cmpxchg((ptr), (unsigned long)_o_, \5252+ (unsigned long)_n_, sizeof(*(ptr))); \5353+})18541955#define ATOMIC_INIT(i) { (i) }2056