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