[PATCH 2.6.9] sh: Add cmpxchg(...)
Tom Rini <[email protected]> Tue, 23 Nov 2004 09:25:44 -0700
| Newsgroups | gmane.linux.ports.sh.devel,gmane.linux.ports.sh.general |
|---|---|
| Message-ID | <[email protected]> |
The following is based on the MIPS version of cmpxchg, and is briefly tested. Signed-off-by: Tom Rini <[email protected]> --- linux-2.6.9.orig/include/asm-sh/system.h +++ linux-2.6.9/include/asm-sh/system.h @@ -7,6 +7,7 @@ */ #include <linux/config.h> +#include <asm/types.h> /* * switch_to() should switch tasks to task nr n, first @@ -252,6 +253,43 @@ static __inline__ unsigned long __xchg(u return x; } +static inline unsigned long __cmpxchg_u32(volatile int * m, unsigned long old, + unsigned long new) +{ + __u32 retval; + unsigned long flags; + + local_irq_save(flags); + retval = *m; + if (retval == old) + *m = new; + local_irq_restore(flags); /* implies memory barrier */ + return retval; +} + +/* This function doesn't exist, so you'll get a linker error + * if something tries to do an invalid cmpxchg(). */ +extern void __cmpxchg_called_with_bad_pointer(void); + +static inline unsigned long __cmpxchg(volatile void * ptr, unsigned long old, + unsigned long new, int size) +{ + switch (size) { + case 4: + return __cmpxchg_u32(ptr, old, new); + } + __cmpxchg_called_with_bad_pointer(); + return old; +} + +#define cmpxchg(ptr,o,n) \ + ({ \ + __typeof__(*(ptr)) _o_ = (o); \ + __typeof__(*(ptr)) _n_ = (n); \ + (__typeof__(*(ptr))) __cmpxchg((ptr), (unsigned long)_o_, \ + (unsigned long)_n_, sizeof(*(ptr))); \ + }) + /* XXX * disable hlt during certain critical i/o operations */ -- Tom Rini http://gate.crashing.org/~trini/ ------------------------------------------------------- SF email is sponsored by - The IT Product Guide Read honest & candid reviews on hundreds of IT Products from real users. Discover which products truly live up to the hype. Start reading now. http://productguide.itmanagersjournal.com/