| Viewing file:  cmpxchg.h (3.51 KB)      -rw-r--r-- Select action/file-type:
 
  (+) |  (+) |  (+) | Code (+) | Session (+) |  (+) | SDB (+) |  (+) |  (+) |  (+) |  (+) |  (+) | 
 
/** cmpxchg.h -- forked from asm/atomic.h with this copyright:
 *
 * Copyright 2010 Tilera Corporation. All Rights Reserved.
 *
 *   This program is free software; you can redistribute it and/or
 *   modify it under the terms of the GNU General Public License
 *   as published by the Free Software Foundation, version 2.
 *
 *   This program is distributed in the hope that it will be useful, but
 *   WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
 *   NON INFRINGEMENT.  See the GNU General Public License for
 *   more details.
 *
 */
 
 #ifndef _ASM_TILE_CMPXCHG_H
 #define _ASM_TILE_CMPXCHG_H
 
 #ifndef __ASSEMBLY__
 
 #include <asm/barrier.h>
 
 /* Nonexistent functions intended to cause compile errors. */
 extern void __xchg_called_with_bad_pointer(void)
 __compiletime_error("Bad argument size for xchg");
 extern void __cmpxchg_called_with_bad_pointer(void)
 __compiletime_error("Bad argument size for cmpxchg");
 
 #ifndef __tilegx__
 
 /* Note the _atomic_xxx() routines include a final mb(). */
 int _atomic_xchg(int *ptr, int n);
 int _atomic_xchg_add(int *v, int i);
 int _atomic_xchg_add_unless(int *v, int a, int u);
 int _atomic_cmpxchg(int *ptr, int o, int n);
 long long _atomic64_xchg(long long *v, long long n);
 long long _atomic64_xchg_add(long long *v, long long i);
 long long _atomic64_xchg_add_unless(long long *v, long long a, long long u);
 long long _atomic64_cmpxchg(long long *v, long long o, long long n);
 
 #define xchg(ptr, n)                            \
 ({                                \
 if (sizeof(*(ptr)) != 4)                \
 __xchg_called_with_bad_pointer();        \
 smp_mb();                        \
 (typeof(*(ptr)))_atomic_xchg((int *)(ptr), (int)(n));    \
 })
 
 #define cmpxchg(ptr, o, n)                        \
 ({                                \
 if (sizeof(*(ptr)) != 4)                \
 __cmpxchg_called_with_bad_pointer();        \
 smp_mb();                        \
 (typeof(*(ptr)))_atomic_cmpxchg((int *)ptr, (int)o,    \
 (int)n);        \
 })
 
 #define xchg64(ptr, n)                            \
 ({                                \
 if (sizeof(*(ptr)) != 8)                \
 __xchg_called_with_bad_pointer();        \
 smp_mb();                        \
 (typeof(*(ptr)))_atomic64_xchg((long long *)(ptr),    \
 (long long)(n));    \
 })
 
 #define cmpxchg64(ptr, o, n)                        \
 ({                                \
 if (sizeof(*(ptr)) != 8)                \
 __cmpxchg_called_with_bad_pointer();        \
 smp_mb();                        \
 (typeof(*(ptr)))_atomic64_cmpxchg((long long *)ptr,    \
 (long long)o, (long long)n);    \
 })
 
 #else
 
 #define xchg(ptr, n)                            \
 ({                                \
 typeof(*(ptr)) __x;                    \
 smp_mb();                        \
 switch (sizeof(*(ptr))) {                \
 case 4:                            \
 __x = (typeof(__x))(unsigned long)        \
 __insn_exch4((ptr),            \
 (u32)(unsigned long)(n));    \
 break;                        \
 case 8:                            \
 __x = (typeof(__x))                \
 __insn_exch((ptr), (unsigned long)(n));    \
 break;                        \
 default:                        \
 __xchg_called_with_bad_pointer();        \
 break;                        \
 }                            \
 smp_mb();                        \
 __x;                            \
 })
 
 #define cmpxchg(ptr, o, n)                        \
 ({                                \
 typeof(*(ptr)) __x;                    \
 __insn_mtspr(SPR_CMPEXCH_VALUE, (unsigned long)(o));    \
 smp_mb();                        \
 switch (sizeof(*(ptr))) {                \
 case 4:                            \
 __x = (typeof(__x))(unsigned long)        \
 __insn_cmpexch4((ptr),            \
 (u32)(unsigned long)(n));    \
 break;                        \
 case 8:                            \
 __x = (typeof(__x))__insn_cmpexch((ptr),    \
 (long long)(n));    \
 break;                        \
 default:                        \
 __cmpxchg_called_with_bad_pointer();        \
 break;                        \
 }                            \
 smp_mb();                        \
 __x;                            \
 })
 
 #define xchg64 xchg
 #define cmpxchg64 cmpxchg
 
 #endif
 
 #define tas(ptr) xchg((ptr), 1)
 
 #endif /* __ASSEMBLY__ */
 
 #endif /* _ASM_TILE_CMPXCHG_H */
 
 |