Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[SPARC]: Emulate cmpxchg like parisc

Signed-off-by: Kyle McMartin <kyle@parisc-linux.org>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Kyle McMartin and committed by
David S. Miller
6197fe4d 67929299

+53
+15
arch/sparc/lib/atomic32.c
··· 2 2 * atomic32.c: 32-bit atomic_t implementation 3 3 * 4 4 * Copyright (C) 2004 Keith M Wesolowski 5 + * Copyright (C) 2007 Kyle McMartin 5 6 * 6 7 * Based on asm-parisc/atomic.h Copyright (C) 2000 Philipp Rumpf 7 8 */ ··· 118 117 return old & mask; 119 118 } 120 119 EXPORT_SYMBOL(___change_bit); 120 + 121 + unsigned long __cmpxchg_u32(volatile u32 *ptr, u32 old, u32 new) 122 + { 123 + unsigned long flags; 124 + u32 prev; 125 + 126 + spin_lock_irqsave(ATOMIC_HASH(addr), flags); 127 + if ((prev = *ptr) == old) 128 + *ptr = new; 129 + spin_unlock_irqrestore(ATOMIC_HASH(addr), flags); 130 + 131 + return (unsigned long)prev; 132 + } 133 + EXPORT_SYMBOL(__cmpxchg_u32);
+38
include/asm-sparc/atomic.h
··· 2 2 * 3 3 * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu) 4 4 * Copyright (C) 2000 Anton Blanchard (anton@linuxcare.com.au) 5 + * Copyright (C) 2007 Kyle McMartin (kyle@parisc-linux.org) 5 6 * 6 7 * Additions by Keith M Wesolowski (wesolows@foobazco.org) based 7 8 * on asm-parisc/atomic.h Copyright (C) 2000 Philipp Rumpf <prumpf@tux.org>. ··· 11 10 #ifndef __ARCH_SPARC_ATOMIC__ 12 11 #define __ARCH_SPARC_ATOMIC__ 13 12 13 + #include <linux/types.h> 14 14 15 15 typedef struct { volatile int counter; } atomic_t; 16 16 17 17 #ifdef __KERNEL__ 18 + 19 + /* Emulate cmpxchg() the same way we emulate atomics, 20 + * by hashing the object address and indexing into an array 21 + * of spinlocks to get a bit of performance... 22 + * 23 + * See arch/sparc/lib/atomic32.c for implementation. 24 + * 25 + * Cribbed from <asm-parisc/atomic.h> 26 + */ 27 + #define __HAVE_ARCH_CMPXCHG 1 28 + 29 + /* bug catcher for when unsupported size is used - won't link */ 30 + extern void __cmpxchg_called_with_bad_pointer(void); 31 + /* we only need to support cmpxchg of a u32 on sparc */ 32 + extern unsigned long __cmpxchg_u32(volatile u32 *m, u32 old, u32 new_); 33 + 34 + /* don't worry...optimizer will get rid of most of this */ 35 + static __inline__ unsigned long 36 + __cmpxchg(volatile void *ptr, unsigned long old, unsigned long new_, int size) 37 + { 38 + switch(size) { 39 + case 4: 40 + return __cmpxchg_u32((u32 *)ptr, (u32)old, (u32)new_); 41 + default: 42 + __cmpxchg_called_with_bad_pointer(); 43 + break; 44 + } 45 + return old; 46 + } 47 + 48 + #define cmpxchg(ptr,o,n) ({ \ 49 + __typeof__(*(ptr)) _o_ = (o); \ 50 + __typeof__(*(ptr)) _n_ = (n); \ 51 + (__typeof__(*(ptr))) __cmpxchg((ptr), (unsigned long)_o_, \ 52 + (unsigned long)_n_, sizeof(*(ptr))); \ 53 + }) 18 54 19 55 #define ATOMIC_INIT(i) { (i) } 20 56