at v3.2-rc6 180 lines 4.7 kB view raw
1/* 2 * Copyright 2010 Tilera Corporation. All Rights Reserved. 3 * 4 * This program is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU General Public License 6 * as published by the Free Software Foundation, version 2. 7 * 8 * This program is distributed in the hope that it will be useful, but 9 * WITHOUT ANY WARRANTY; without even the implied warranty of 10 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or 11 * NON INFRINGEMENT. See the GNU General Public License for 12 * more details. 13 * 14 * Atomic primitives. 15 */ 16 17#ifndef _ASM_TILE_ATOMIC_H 18#define _ASM_TILE_ATOMIC_H 19 20#ifndef __ASSEMBLY__ 21 22#include <linux/compiler.h> 23#include <asm/system.h> 24 25#define ATOMIC_INIT(i) { (i) } 26 27/** 28 * atomic_read - read atomic variable 29 * @v: pointer of type atomic_t 30 * 31 * Atomically reads the value of @v. 32 */ 33static inline int atomic_read(const atomic_t *v) 34{ 35 return ACCESS_ONCE(v->counter); 36} 37 38/** 39 * atomic_sub_return - subtract integer and return 40 * @v: pointer of type atomic_t 41 * @i: integer value to subtract 42 * 43 * Atomically subtracts @i from @v and returns @v - @i 44 */ 45#define atomic_sub_return(i, v) atomic_add_return((int)(-(i)), (v)) 46 47/** 48 * atomic_sub - subtract integer from atomic variable 49 * @i: integer value to subtract 50 * @v: pointer of type atomic_t 51 * 52 * Atomically subtracts @i from @v. 53 */ 54#define atomic_sub(i, v) atomic_add((int)(-(i)), (v)) 55 56/** 57 * atomic_sub_and_test - subtract value from variable and test result 58 * @i: integer value to subtract 59 * @v: pointer of type atomic_t 60 * 61 * Atomically subtracts @i from @v and returns true if the result is 62 * zero, or false for all other cases. 63 */ 64#define atomic_sub_and_test(i, v) (atomic_sub_return((i), (v)) == 0) 65 66/** 67 * atomic_inc_return - increment memory and return 68 * @v: pointer of type atomic_t 69 * 70 * Atomically increments @v by 1 and returns the new value. 71 */ 72#define atomic_inc_return(v) atomic_add_return(1, (v)) 73 74/** 75 * atomic_dec_return - decrement memory and return 76 * @v: pointer of type atomic_t 77 * 78 * Atomically decrements @v by 1 and returns the new value. 79 */ 80#define atomic_dec_return(v) atomic_sub_return(1, (v)) 81 82/** 83 * atomic_inc - increment atomic variable 84 * @v: pointer of type atomic_t 85 * 86 * Atomically increments @v by 1. 87 */ 88#define atomic_inc(v) atomic_add(1, (v)) 89 90/** 91 * atomic_dec - decrement atomic variable 92 * @v: pointer of type atomic_t 93 * 94 * Atomically decrements @v by 1. 95 */ 96#define atomic_dec(v) atomic_sub(1, (v)) 97 98/** 99 * atomic_dec_and_test - decrement and test 100 * @v: pointer of type atomic_t 101 * 102 * Atomically decrements @v by 1 and returns true if the result is 0. 103 */ 104#define atomic_dec_and_test(v) (atomic_dec_return(v) == 0) 105 106/** 107 * atomic_inc_and_test - increment and test 108 * @v: pointer of type atomic_t 109 * 110 * Atomically increments @v by 1 and returns true if the result is 0. 111 */ 112#define atomic_inc_and_test(v) (atomic_inc_return(v) == 0) 113 114/** 115 * atomic_add_negative - add and test if negative 116 * @v: pointer of type atomic_t 117 * @i: integer value to add 118 * 119 * Atomically adds @i to @v and returns true if the result is 120 * negative, or false when result is greater than or equal to zero. 121 */ 122#define atomic_add_negative(i, v) (atomic_add_return((i), (v)) < 0) 123 124/* Nonexistent functions intended to cause link errors. */ 125extern unsigned long __xchg_called_with_bad_pointer(void); 126extern unsigned long __cmpxchg_called_with_bad_pointer(void); 127 128#define xchg(ptr, x) \ 129 ({ \ 130 typeof(*(ptr)) __x; \ 131 switch (sizeof(*(ptr))) { \ 132 case 4: \ 133 __x = (typeof(__x))(typeof(__x-__x))atomic_xchg( \ 134 (atomic_t *)(ptr), \ 135 (u32)(typeof((x)-(x)))(x)); \ 136 break; \ 137 case 8: \ 138 __x = (typeof(__x))(typeof(__x-__x))atomic64_xchg( \ 139 (atomic64_t *)(ptr), \ 140 (u64)(typeof((x)-(x)))(x)); \ 141 break; \ 142 default: \ 143 __xchg_called_with_bad_pointer(); \ 144 } \ 145 __x; \ 146 }) 147 148#define cmpxchg(ptr, o, n) \ 149 ({ \ 150 typeof(*(ptr)) __x; \ 151 switch (sizeof(*(ptr))) { \ 152 case 4: \ 153 __x = (typeof(__x))(typeof(__x-__x))atomic_cmpxchg( \ 154 (atomic_t *)(ptr), \ 155 (u32)(typeof((o)-(o)))(o), \ 156 (u32)(typeof((n)-(n)))(n)); \ 157 break; \ 158 case 8: \ 159 __x = (typeof(__x))(typeof(__x-__x))atomic64_cmpxchg( \ 160 (atomic64_t *)(ptr), \ 161 (u64)(typeof((o)-(o)))(o), \ 162 (u64)(typeof((n)-(n)))(n)); \ 163 break; \ 164 default: \ 165 __cmpxchg_called_with_bad_pointer(); \ 166 } \ 167 __x; \ 168 }) 169 170#define tas(ptr) (xchg((ptr), 1)) 171 172#endif /* __ASSEMBLY__ */ 173 174#ifndef __tilegx__ 175#include <asm/atomic_32.h> 176#else 177#include <asm/atomic_64.h> 178#endif 179 180#endif /* _ASM_TILE_ATOMIC_H */