1 /* 2 * include/xen/atomic.h 3 * 4 * Common atomic operations entities (atomic_t, function prototypes). 5 * Include _from_ arch-side <asm/atomic.h>. 6 * 7 * Copyright (c) 2016 Bitdefender S.R.L. 8 * 9 * This program is free software; you can redistribute it and/or modify it 10 * under the terms and conditions of the GNU General Public License, 11 * version 2, as published by the Free Software Foundation. 12 * 13 * This program is distributed in the hope it will be useful, but WITHOUT 14 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 15 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 16 * more details. 17 * 18 * You should have received a copy of the GNU General Public License along with 19 * this program; If not, see <http://www.gnu.org/licenses/>. 20 */ 21 22 #ifndef __XEN_ATOMIC_H__ 23 #define __XEN_ATOMIC_H__ 24 25 typedef struct { int counter; } atomic_t; 26 27 #define ATOMIC_INIT(i) { (i) } 28 29 /** 30 * atomic_read - read atomic variable 31 * @v: pointer of type atomic_t 32 * 33 * Atomically reads the value of @v. 34 */ 35 static inline int atomic_read(const atomic_t *v); 36 37 /** 38 * _atomic_read - read atomic variable non-atomically 39 * @v atomic_t 40 * 41 * Non-atomically reads the value of @v 42 */ 43 static inline int _atomic_read(atomic_t v); 44 45 /** 46 * atomic_set - set atomic variable 47 * @v: pointer of type atomic_t 48 * @i: required value 49 * 50 * Atomically sets the value of @v to @i. 51 */ 52 static inline void atomic_set(atomic_t *v, int i); 53 54 /** 55 * _atomic_set - set atomic variable non-atomically 56 * @v: pointer of type atomic_t 57 * @i: required value 58 * 59 * Non-atomically sets the value of @v to @i. 60 */ 61 static inline void _atomic_set(atomic_t *v, int i); 62 63 /** 64 * atomic_cmpxchg - compare and exchange an atomic variable 65 * @v: pointer of type atomic_t 66 * @old: old value 67 * @new: new value 68 * 69 * Before calling, @old should be set to @v. 70 * Succeeds if @old == @v (likely), in which case stores @new in @v. 71 * Returns the initial value in @v, hence succeeds when the return value 72 * matches that of @old. 73 * 74 * Sample (tries atomic increment of v until the operation succeeds): 75 * 76 * while(1) 77 * { 78 * int old = atomic_read(&v); 79 * int new = old + 1; 80 * if ( likely(old == atomic_cmpxchg(&v, old, new)) ) 81 * break; // success! 82 * } 83 */ 84 static inline int atomic_cmpxchg(atomic_t *v, int old, int new); 85 86 /** 87 * atomic_add - add integer to atomic variable 88 * @i: integer value to add 89 * @v: pointer of type atomic_t 90 * 91 * Atomically adds @i to @v. 92 */ 93 static inline void atomic_add(int i, atomic_t *v); 94 95 /** 96 * atomic_add_return - add integer and return 97 * @i: integer value to add 98 * @v: pointer of type atomic_t 99 * 100 * Atomically adds @i to @v and returns @i + @v 101 */ 102 static inline int atomic_add_return(int i, atomic_t *v); 103 104 /** 105 * atomic_sub - subtract the atomic variable 106 * @i: integer value to subtract 107 * @v: pointer of type atomic_t 108 * 109 * Atomically subtracts @i from @v. 110 */ 111 static inline void atomic_sub(int i, atomic_t *v); 112 113 /** 114 * atomic_sub_return - sub integer and return 115 * @i: integer value to sub 116 * @v: pointer of type atomic_t 117 * 118 * Atomically subtracts @i from @v and returns @v - @i. 119 */ 120 static inline int atomic_sub_return(int i, atomic_t *v); 121 122 /** 123 * atomic_sub_and_test - subtract value from variable and test result 124 * @i: integer value to subtract 125 * @v: pointer of type atomic_t 126 * 127 * Atomically subtracts @i from @v and returns 128 * true if the result is zero, or false for all 129 * other cases. 130 */ 131 static inline int atomic_sub_and_test(int i, atomic_t *v); 132 133 /** 134 * atomic_inc - increment atomic variable 135 * @v: pointer of type atomic_t 136 * 137 * Atomically increments @v by 1. 138 */ 139 static inline void atomic_inc(atomic_t *v); 140 141 /** 142 * atomic_inc_return - increment atomic variable and return 143 * @v: pointer of type atomic_t 144 * 145 * Atomically increments @v by 1 and returns @v + 1. 146 */ 147 static inline int atomic_inc_return(atomic_t *v); 148 149 /** 150 * atomic_inc_and_test - increment and test 151 * @v: pointer of type atomic_t 152 * 153 * Atomically increments @v by 1 154 * and returns true if the result is zero, or false for all 155 * other cases. 156 */ 157 static inline int atomic_inc_and_test(atomic_t *v); 158 159 /** 160 * atomic_dec - decrement atomic variable 161 * @v: pointer of type atomic_t 162 * 163 * Atomically decrements @v by 1. 164 */ 165 static inline void atomic_dec(atomic_t *v); 166 167 /** 168 * atomic_dec_return - decrement atomic variable and return 169 * @v: pointer of type atomic_t 170 * 171 * Atomically decrements @v by 1 and returns @v - 1. 172 */ 173 static inline int atomic_dec_return(atomic_t *v); 174 175 /** 176 * atomic_dec_and_test - decrement and test 177 * @v: pointer of type atomic_t 178 * 179 * Atomically decrements @v by 1 and 180 * returns true if the result is 0, or false for all other 181 * cases. 182 */ 183 static inline int atomic_dec_and_test(atomic_t *v); 184 185 /** 186 * atomic_add_negative - add and test if negative 187 * @v: pointer of type atomic_t 188 * @i: integer value to add 189 * 190 * Atomically adds @i to @v and returns true 191 * if the result is negative, or false when 192 * result is greater than or equal to zero. 193 */ 194 static inline int atomic_add_negative(int i, atomic_t *v); 195 196 /** 197 * atomic_add_unless - add to atomic variable unless it has a specified value 198 * @v: pointer of type atomic_t 199 * @a: integer value to add 200 * @u: integer value @v must -not- be for the add to be performed 201 * 202 * If @v != @u, adds @a to @v and returns @v + @a. 203 * Otherwise returns @u (== @v). 204 */ 205 static inline int atomic_add_unless(atomic_t *v, int a, int u); 206 207 #endif /* __XEN_ATOMIC_H__ */ 208