OPIC
Object Persistence In C
op_atomic.h
Go to the documentation of this file.
1 
8 /* This program is free software: you can redistribute it and/or modify
9  * it under the terms of the GNU Lesser General Public License as
10  * published by the Free Software Foundation, either version 3 of the
11  * License, or (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful, but
14  * WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with this program. If not, see
20  * <http://www.gnu.org/licenses/>.
21  */
22 
23 /* Code: */
24 
25 #ifndef OPIC_COMMON_OP_ATOMIC_H
26 #define OPIC_COMMON_OP_ATOMIC_H 1
27 
28 #include <stdint.h>
29 #include <stdbool.h>
30 #include <stdatomic.h>
31 #include "op_macros.h"
32 
33 OP_BEGIN_DECLS
34 
35 typedef _Atomic int8_t a_int8_t;
36 typedef _Atomic int16_t a_int16_t;
37 typedef _Atomic int32_t a_int32_t;
38 typedef _Atomic int64_t a_int64_t;
39 typedef _Atomic uint8_t a_uint8_t;
40 typedef _Atomic uint16_t a_uint16_t;
41 typedef _Atomic uint32_t a_uint32_t;
42 typedef _Atomic uint64_t a_uint64_t;
43 
44 #define atomic_check_in(PUNCH_CARD) \
45  _Generic((PUNCH_CARD), \
46  a_int8_t*: atomic_check_in_8, \
47  a_int16_t*: atomic_check_in_16, \
48  a_int32_t*: atomic_check_in_32, \
49  a_int64_t*: atomic_check_in_64) \
50  (PUNCH_CARD)
51 
52 #define atomic_check_out(PUNCH_CARD) \
53  _Generic((PUNCH_CARD), \
54  a_int8_t*: atomic_check_out_8, \
55  a_int16_t*: atomic_check_out_16, \
56  a_int32_t*: atomic_check_out_32, \
57  a_int64_t*: atomic_check_out_64) \
58  (PUNCH_CARD)
59 
60 #define atomic_book_critical(PUNCH_CARD) \
61  _Generic((PUNCH_CARD), \
62  a_int8_t*: atomic_book_critical_8, \
63  a_int16_t*: atomic_book_critical_16, \
64  a_int32_t*: atomic_book_critical_32, \
65  a_int64_t*: atomic_book_critical_64) \
66  (PUNCH_CARD)
67 
68 #define atomic_check_in_book(PUNCH_CARD) \
69  _Generic((PUNCH_CARD), \
70  a_int8_t*: atomic_check_in_book_8, \
71  a_int16_t*: atomic_check_in_book_16, \
72  a_int32_t*: atomic_check_in_book_32, \
73  a_int64_t*: atomic_check_in_book_64) \
74  (PUNCH_CARD)
75 
76 #define atomic_is_booked(PUNCH_CARD) \
77  _Generic((PUNCH_CARD), \
78  a_int8_t*: atomic_is_booked_8, \
79  a_int16_t*: atomic_is_booked_16, \
80  a_int32_t*: atomic_is_booked_32, \
81  a_int64_t*: atomic_is_booked_64) \
82  (PUNCH_CARD)
83 
84 #define atomic_enter_critical(PUNCH_CARD) \
85  _Generic((PUNCH_CARD), \
86  a_int8_t*: atomic_enter_critical_8, \
87  a_int16_t*: atomic_enter_critical_16, \
88  a_int32_t*: atomic_enter_critical_32, \
89  a_int64_t*: atomic_enter_critical_64) \
90  (PUNCH_CARD)
91 
92 #define atomic_exit_critical(PUNCH_CARD) \
93  _Generic((PUNCH_CARD), \
94  a_int8_t*: atomic_exit_critical_8, \
95  a_int16_t*: atomic_exit_critical_16, \
96  a_int32_t*: atomic_exit_critical_32, \
97  a_int64_t*: atomic_exit_critical_64) \
98  (PUNCH_CARD)
99 
100 #define atomic_exit_check_out(PUNCH_CARD) \
101  _Generic((PUNCH_CARD), \
102  a_int8_t*: atomic_exit_check_out_8, \
103  a_int16_t*: atomic_exit_check_out_16, \
104  a_int32_t*: atomic_exit_check_out_32, \
105  a_int64_t*: atomic_exit_check_out_64) \
106  (PUNCH_CARD)
107 
108 static inline bool
109 atomic_check_in_8(a_int8_t* punch_card)
110 {
111  int8_t val = atomic_load_explicit(punch_card,
112  memory_order_relaxed);
113  do
114  {
115  if (val < 0)
116  return false;
117  }
118  while (!atomic_compare_exchange_weak_explicit
119  (punch_card, &val, val + 1,
120  memory_order_acquire,
121  memory_order_relaxed));
122  return true;
123 }
124 
125 static inline bool
126 atomic_check_in_16(a_int16_t* punch_card)
127 {
128  int16_t val = atomic_load_explicit(punch_card,
129  memory_order_relaxed);
130  do
131  {
132  if (val < 0)
133  return false;
134  }
135  while (!atomic_compare_exchange_weak_explicit
136  (punch_card, &val, val + 1,
137  memory_order_acquire,
138  memory_order_relaxed));
139  return true;
140 }
141 
142 static inline bool
143 atomic_check_in_32(a_int32_t* punch_card)
144 {
145  int32_t val = atomic_load_explicit(punch_card,
146  memory_order_relaxed);
147  do
148  {
149  if (val < 0)
150  return false;
151  }
152  while (!atomic_compare_exchange_weak_explicit
153  (punch_card, &val, val + 1,
154  memory_order_acquire,
155  memory_order_relaxed));
156  return true;
157 }
158 
159 static inline bool
160 atomic_check_in_64(a_int64_t* punch_card)
161 {
162  int64_t val = atomic_load_explicit(punch_card,
163  memory_order_relaxed);
164  do
165  {
166  if (val < 0)
167  return false;
168  }
169  while (!atomic_compare_exchange_weak_explicit
170  (punch_card, &val, val + 1,
171  memory_order_acquire,
172  memory_order_relaxed));
173  return true;
174 }
175 
176 static inline void
177 atomic_check_out_8(a_int8_t* punch_card)
178 {
179  atomic_fetch_sub_explicit(punch_card,
180  1,
181  memory_order_release);
182 }
183 
184 static inline void
185 atomic_check_out_16(a_int16_t* punch_card)
186 {
187  atomic_fetch_sub_explicit(punch_card,
188  1,
189  memory_order_release);
190 }
191 
192 static inline void
193 atomic_check_out_32(a_int32_t* punch_card)
194 {
195  atomic_fetch_sub_explicit(punch_card,
196  1,
197  memory_order_release);
198 }
199 
200 static inline void
201 atomic_check_out_64(a_int64_t* punch_card)
202 {
203  atomic_fetch_sub_explicit(punch_card,
204  1,
205  memory_order_release);
206 }
207 
208 static inline bool
209 atomic_book_critical_8(a_int8_t* punch_card)
210 {
211  return atomic_fetch_or_explicit
212  (punch_card, 1<<7, memory_order_acq_rel) > 0;
213 }
214 
215 static inline bool
216 atomic_book_critical_16(a_int16_t* punch_card)
217 {
218  return atomic_fetch_or_explicit
219  (punch_card, 1<<15, memory_order_acq_rel) > 0;
220 }
221 
222 static inline bool
223 atomic_book_critical_32(a_int32_t* punch_card)
224 {
225  return atomic_fetch_or_explicit
226  (punch_card, 1<<31, memory_order_acq_rel) > 0;
227 }
228 
229 static inline bool
230 atomic_book_critical_64(a_int64_t* punch_card)
231 {
232  return atomic_fetch_or_explicit
233  (punch_card, 1L<<63, memory_order_acq_rel) > 0;
234 }
235 
236 static inline bool
237 atomic_check_in_book_8(a_int8_t* punch_card)
238 {
239  int8_t val = atomic_load_explicit(punch_card,
240  memory_order_relaxed);
241  do
242  {
243  if (val < 0)
244  return false;
245  }
246  while (!atomic_compare_exchange_weak_explicit
247  (punch_card, &val, (val + 1) | (1<<7),
248  memory_order_acquire,
249  memory_order_relaxed));
250  return true;
251 }
252 
253 static inline bool
254 atomic_check_in_book_16(a_int16_t* punch_card)
255 {
256  int16_t val = atomic_load_explicit(punch_card,
257  memory_order_relaxed);
258  do
259  {
260  if (val < 0)
261  return false;
262  }
263  while (!atomic_compare_exchange_weak_explicit
264  (punch_card, &val, (val + 1) | (1<<15),
265  memory_order_acquire,
266  memory_order_relaxed));
267  return true;
268 }
269 
270 static inline bool
271 atomic_check_in_book_32(a_int32_t* punch_card)
272 {
273  int32_t val = atomic_load_explicit(punch_card,
274  memory_order_relaxed);
275  do
276  {
277  if (val < 0)
278  return false;
279  }
280  while (!atomic_compare_exchange_weak_explicit
281  (punch_card, &val, (val + 1) | (1<<31),
282  memory_order_acquire,
283  memory_order_relaxed));
284  return true;
285 }
286 
287 static inline bool
288 atomic_check_in_book_64(a_int64_t* punch_card)
289 {
290  int64_t val = atomic_load_explicit(punch_card,
291  memory_order_relaxed);
292  do
293  {
294  if (val < 0)
295  return false;
296  }
297  while (!atomic_compare_exchange_weak_explicit
298  (punch_card, &val, (val + 1) | (1UL<<63),
299  memory_order_acquire,
300  memory_order_relaxed));
301  return true;
302 }
303 
304 static inline bool
305 atomic_is_booked_8(a_int8_t* punch_card)
306 {
307  return atomic_load_explicit(punch_card, memory_order_acquire) < 0;
308 }
309 
310 static inline bool
311 atomic_is_booked_16(a_int16_t* punch_card)
312 {
313  return atomic_load_explicit(punch_card, memory_order_acquire) < 0;
314 }
315 
316 static inline bool
317 atomic_is_booked_32(a_int32_t* punch_card)
318 {
319  return atomic_load_explicit(punch_card, memory_order_acquire) < 0;
320 }
321 
322 static inline bool
323 atomic_is_booked_64(a_int64_t* punch_card)
324 {
325  return atomic_load_explicit(punch_card, memory_order_acquire) < 0;
326 }
327 
328 static inline void
329 atomic_enter_critical_8(a_int8_t* punch_card)
330 {
331  while (atomic_load_explicit(punch_card, memory_order_relaxed)
332  > INT8_MIN + 1)
333  ;
334  atomic_fetch_sub_explicit(punch_card, 1, memory_order_acq_rel);
335 }
336 
337 static inline void
338 atomic_enter_critical_16(a_int16_t* punch_card)
339 {
340  while (atomic_load_explicit(punch_card, memory_order_relaxed)
341  > INT16_MIN + 1)
342  ;
343  atomic_fetch_sub_explicit(punch_card, 1, memory_order_acq_rel);
344 }
345 
346 static inline void
347 atomic_enter_critical_32(a_int32_t* punch_card)
348 {
349  while (atomic_load_explicit(punch_card, memory_order_relaxed)
350  > INT32_MIN + 1)
351  ;
352  atomic_fetch_sub_explicit(punch_card, 1, memory_order_acq_rel);
353 }
354 
355 static inline void
356 atomic_enter_critical_64(a_int64_t* punch_card)
357 {
358  while (atomic_load_explicit(punch_card, memory_order_relaxed)
359  > INT64_MIN + 1)
360  ;
361  atomic_fetch_sub_explicit(punch_card, 1, memory_order_acq_rel);
362 }
363 
364 static inline void
365 atomic_exit_critical_8(a_int8_t* punch_card)
366 {
367  atomic_store_explicit(punch_card, 1, memory_order_release);
368 }
369 
370 static inline void
371 atomic_exit_critical_16(a_int16_t* punch_card)
372 {
373  atomic_store_explicit(punch_card, 1, memory_order_release);
374 }
375 
376 static inline void
377 atomic_exit_critical_32(a_int32_t* punch_card)
378 {
379  atomic_store_explicit(punch_card, 1, memory_order_release);
380 }
381 
382 static inline void
383 atomic_exit_critical_64(a_int64_t* punch_card)
384 {
385  atomic_store_explicit(punch_card, 1, memory_order_release);
386 }
387 
388 static inline void
389 atomic_exit_check_out_8(a_int8_t* punch_card)
390 {
391  atomic_store_explicit(punch_card, 0, memory_order_release);
392 }
393 
394 static inline void
395 atomic_exit_check_out_16(a_int16_t* punch_card)
396 {
397  atomic_store_explicit(punch_card, 0, memory_order_release);
398 }
399 
400 static inline void
401 atomic_exit_check_out_32(a_int32_t* punch_card)
402 {
403  atomic_store_explicit(punch_card, 0, memory_order_release);
404 }
405 
406 static inline void
407 atomic_exit_check_out_64(a_int64_t* punch_card)
408 {
409  atomic_store_explicit(punch_card, 0, memory_order_release);
410 }
411 
412 OP_END_DECLS
413 #endif
414 /* op_atomic.h ends here */