All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
as_atomic_gcc.h
Go to the documentation of this file.
1 /*
2  * Copyright 2008-2018 Aerospike, Inc.
3  *
4  * Portions may be licensed to Aerospike, Inc. under one or more contributor
5  * license agreements.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
8  * use this file except in compliance with the License. You may obtain a copy of
9  * the License at http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14  * License for the specific language governing permissions and limitations under
15  * the License.
16  */
17 #pragma once
18 
19 #include <aerospike/as_arch.h>
20 #include <aerospike/as_std.h>
21 
22 #ifdef __cplusplus
23 extern "C" {
24 #endif
25 
26 /******************************************************************************
27  * LOAD
28  *****************************************************************************/
29 
30 // type as_load_rlx(const type* target)
31 #define as_load_rlx(_target) __atomic_load_n(_target, __ATOMIC_RELAXED)
32 
33 // type as_load_acq(const type* target)
34 #define as_load_acq(_target) __atomic_load_n(_target, __ATOMIC_ACQUIRE)
35 
36 // type as_load_seq(const type* target)
37 #define as_load_seq(_target) __atomic_load_n(_target, __ATOMIC_SEQ_CST)
38 
39 // "Relaxed" wrappers.
40 
41 static inline void*
42 as_load_ptr(void* const* target)
43 {
44  return as_load_rlx(target);
45 }
46 
47 static inline uint64_t
48 as_load_uint64(const uint64_t* target)
49 {
50  return as_load_rlx(target);
51 }
52 
53 static inline int64_t
54 as_load_int64(const int64_t* target)
55 {
56  return as_load_rlx(target);
57 }
58 
59 static inline uint32_t
60 as_load_uint32(const uint32_t* target)
61 {
62  return as_load_rlx(target);
63 }
64 
65 static inline int32_t
66 as_load_int32(const int32_t* target)
67 {
68  return as_load_rlx(target);
69 }
70 
71 static inline uint16_t
72 as_load_uint16(const uint16_t* target)
73 {
74  return as_load_rlx(target);
75 }
76 
77 static inline int16_t
78 as_load_int16(const int16_t* target)
79 {
80  return as_load_rlx(target);
81 }
82 
83 static inline uint8_t
84 as_load_uint8(const uint8_t* target)
85 {
86  return as_load_rlx(target);
87 }
88 
89 static inline int8_t
90 as_load_int8(const int8_t* target)
91 {
92  return as_load_rlx(target);
93 }
94 
95 // "Acquire" wrappers.
96 
97 static inline void*
98 as_load_ptr_acq(void* const* target)
99 {
100  return as_load_acq(target);
101 }
102 
103 static inline uint64_t
104 as_load_uint64_acq(const uint64_t* target)
105 {
106  return as_load_acq(target);
107 }
108 
109 static inline int64_t
110 as_load_int64_acq(const int64_t* target)
111 {
112  return as_load_acq(target);
113 }
114 
115 static inline uint32_t
116 as_load_uint32_acq(const uint32_t* target)
117 {
118  return as_load_acq(target);
119 }
120 
121 static inline int32_t
122 as_load_int32_acq(const int32_t* target)
123 {
124  return as_load_acq(target);
125 }
126 
127 static inline uint16_t
128 as_load_uint16_acq(const uint16_t* target)
129 {
130  return as_load_acq(target);
131 }
132 
133 static inline int16_t
134 as_load_int16_acq(const int16_t* target)
135 {
136  return as_load_acq(target);
137 }
138 
139 static inline uint8_t
140 as_load_uint8_acq(const uint8_t* target)
141 {
142  return as_load_acq(target);
143 }
144 
145 static inline int8_t
146 as_load_int8_acq(const int8_t* target)
147 {
148  return as_load_acq(target);
149 }
150 
151 /******************************************************************************
152  * STORE
153  *****************************************************************************/
154 
155 // void as_store_rlx(type* target, type value)
156 #define as_store_rlx(_target, _value) __atomic_store_n(_target, _value, __ATOMIC_RELAXED)
157 
158 // void as_store_rls(type* target, type value)
159 #define as_store_rls(_target, _value) __atomic_store_n(_target, _value, __ATOMIC_RELEASE)
160 
161 // void as_store_seq(type* target, type value)
162 #define as_store_seq(_target, _value) __atomic_store_n(_target, _value, __ATOMIC_SEQ_CST)
163 
164 // "Relaxed" wrappers.
165 
166 static inline void
167 as_store_ptr(void** target, void* value)
168 {
169  as_store_rlx(target, value);
170 }
171 
172 static inline void
173 as_store_uint64(uint64_t* target, uint64_t value)
174 {
175  as_store_rlx(target, value);
176 }
177 
178 static inline void
179 as_store_int64(int64_t* target, int64_t value)
180 {
181  as_store_rlx(target, value);
182 }
183 
184 static inline void
185 as_store_uint32(uint32_t* target, uint32_t value)
186 {
187  as_store_rlx(target, value);
188 }
189 
190 static inline void
191 as_store_int32(int32_t* target, int32_t value)
192 {
193  as_store_rlx(target, value);
194 }
195 
196 static inline void
197 as_store_uint16(uint16_t* target, uint16_t value)
198 {
199  as_store_rlx(target, value);
200 }
201 
202 static inline void
203 as_store_int16(int16_t* target, int16_t value)
204 {
205  as_store_rlx(target, value);
206 }
207 
208 static inline void
209 as_store_uint8(uint8_t* target, uint8_t value)
210 {
211  as_store_rlx(target, value);
212 }
213 
214 static inline void
215 as_store_int8(int8_t* target, int8_t value)
216 {
217  as_store_rlx(target, value);
218 }
219 
220 // "Release" wrappers.
221 
222 static inline void
223 as_store_ptr_rls(void** target, void* value)
224 {
225  as_store_rls(target, value);
226 }
227 
228 static inline void
229 as_store_uint64_rls(uint64_t* target, uint64_t value)
230 {
231  as_store_rls(target, value);
232 }
233 
234 static inline void
235 as_store_int64_rls(int64_t* target, int64_t value)
236 {
237  as_store_rls(target, value);
238 }
239 
240 static inline void
241 as_store_uint32_rls(uint32_t* target, uint32_t value)
242 {
243  as_store_rls(target, value);
244 }
245 
246 static inline void
247 as_store_int32_rls(int32_t* target, int32_t value)
248 {
249  as_store_rls(target, value);
250 }
251 
252 static inline void
253 as_store_uint16_rls(uint16_t* target, uint16_t value)
254 {
255  as_store_rls(target, value);
256 }
257 
258 static inline void
259 as_store_int16_rls(int16_t* target, int16_t value)
260 {
261  as_store_rls(target, value);
262 }
263 
264 static inline void
265 as_store_uint8_rls(uint8_t* target, uint8_t value)
266 {
267  as_store_rls(target, value);
268 }
269 
270 static inline void
271 as_store_int8_rls(int8_t* target, int8_t value)
272 {
273  as_store_rls(target, value);
274 }
275 
276 /******************************************************************************
277  * FETCH AND ADD
278  *****************************************************************************/
279 
280 // type as_faa_rlx(type* target, type value)
281 #define as_faa_rlx(_target, _value) __atomic_fetch_add(_target, _value, __ATOMIC_RELAXED)
282 
283 // type as_faa_acq(type* target, type value)
284 #define as_faa_acq(_target, _value) __atomic_fetch_add(_target, _value, __ATOMIC_ACQUIRE)
285 
286 // type as_faa_rls(type* target, type value)
287 #define as_faa_rls(_target, _value) __atomic_fetch_add(_target, _value, __ATOMIC_RELEASE)
288 
289 // type as_faa_seq(type* target, type value)
290 #define as_faa_seq(_target, _value) __atomic_fetch_add(_target, _value, __ATOMIC_SEQ_CST)
291 
292 // "Relaxed" wrappers.
293 
294 static inline uint64_t
295 as_faa_uint64(uint64_t* target, int64_t value)
296 {
297  return as_faa_rlx(target, value);
298 }
299 
300 static inline int64_t
301 as_faa_int64(int64_t* target, int64_t value)
302 {
303  return as_faa_rlx(target, value);
304 }
305 
306 static inline uint32_t
307 as_faa_uint32(uint32_t* target, int32_t value)
308 {
309  return as_faa_rlx(target, value);
310 }
311 
312 static inline int32_t
313 as_faa_int32(int32_t* target, int32_t value)
314 {
315  return as_faa_rlx(target, value);
316 }
317 
318 static inline uint16_t
319 as_faa_uint16(uint16_t* target, int16_t value)
320 {
321  return as_faa_rlx(target, value);
322 }
323 
324 static inline int16_t
325 as_faa_int16(int16_t* target, int16_t value)
326 {
327  return as_faa_rlx(target, value);
328 }
329 
330 /******************************************************************************
331  * ADD AND FETCH
332  *****************************************************************************/
333 
334 // type as_aaf_rlx(type* target, type value)
335 #define as_aaf_rlx(_target, _value) __atomic_add_fetch(_target, _value, __ATOMIC_RELAXED)
336 
337 // type as_aaf_acq(type* target, type value)
338 #define as_aaf_acq(_target, _value) __atomic_add_fetch(_target, _value, __ATOMIC_ACQUIRE)
339 
340 // type as_aaf_rls(type* target, type value)
341 #define as_aaf_rls(_target, _value) __atomic_add_fetch(_target, _value, __ATOMIC_RELEASE)
342 
343 // type as_aaf_seq(type* target, type value)
344 #define as_aaf_seq(_target, _value) __atomic_add_fetch(_target, _value, __ATOMIC_SEQ_CST)
345 
346 // "Relaxed" wrappers.
347 
348 static inline uint64_t
349 as_aaf_uint64(uint64_t* target, int64_t value)
350 {
351  return as_aaf_rlx(target, value);
352 }
353 
354 static inline int64_t
355 as_aaf_int64(int64_t* target, int64_t value)
356 {
357  return as_aaf_rlx(target, value);
358 }
359 
360 static inline uint32_t
361 as_aaf_uint32(uint32_t* target, int32_t value)
362 {
363  return as_aaf_rlx(target, value);
364 }
365 
366 static inline int32_t
367 as_aaf_int32(int32_t* target, int32_t value)
368 {
369  return as_aaf_rlx(target, value);
370 }
371 
372 static inline uint16_t
373 as_aaf_uint16(uint16_t* target, int16_t value)
374 {
375  return as_aaf_rlx(target, value);
376 }
377 
378 static inline int16_t
379 as_aaf_int16(int16_t* target, int16_t value)
380 {
381  return as_aaf_rlx(target, value);
382 }
383 
384 // "Release" wrappers.
385 
386 static inline uint64_t
387 as_aaf_uint64_rls(uint64_t* target, int64_t value)
388 {
389  return as_aaf_rls(target, value);
390 }
391 
392 static inline int64_t
393 as_aaf_int64_rls(int64_t* target, int64_t value)
394 {
395  return as_aaf_rls(target, value);
396 }
397 
398 static inline uint32_t
399 as_aaf_uint32_rls(uint32_t* target, int32_t value)
400 {
401  return as_aaf_rls(target, value);
402 }
403 
404 static inline int32_t
405 as_aaf_int32_rls(int32_t* target, int32_t value)
406 {
407  return as_aaf_rls(target, value);
408 }
409 
410 static inline uint16_t
411 as_aaf_uint16_rls(uint16_t* target, int16_t value)
412 {
413  return as_aaf_rls(target, value);
414 }
415 
416 static inline int16_t
417 as_aaf_int16_rls(int16_t* target, int16_t value)
418 {
419  return as_aaf_rls(target, value);
420 }
421 
422 /******************************************************************************
423  * ADD
424  *****************************************************************************/
425 
426 // "Relaxed" wrappers.
427 
428 static inline void
429 as_add_uint64(uint64_t* target, int64_t value)
430 {
431  as_faa_rlx(target, value);
432 }
433 
434 static inline void
435 as_add_int64(int64_t* target, int64_t value)
436 {
437  as_faa_rlx(target, value);
438 }
439 
440 static inline void
441 as_add_uint32(uint32_t* target, int32_t value)
442 {
443  as_faa_rlx(target, value);
444 }
445 
446 static inline void
447 as_add_int32(int32_t* target, int32_t value)
448 {
449  as_faa_rlx(target, value);
450 }
451 
452 static inline void
453 as_add_uint16(uint16_t* target, int16_t value)
454 {
455  as_faa_rlx(target, value);
456 }
457 
458 static inline void
459 as_add_int16(int16_t* target, int16_t value)
460 {
461  as_faa_rlx(target, value);
462 }
463 
464 /******************************************************************************
465  * INCREMENT
466  *****************************************************************************/
467 
468 // "Relaxed" wrappers.
469 
470 static inline void
471 as_incr_uint64(uint64_t* target)
472 {
473  as_faa_rlx(target, 1);
474 }
475 
476 static inline void
477 as_incr_int64(int64_t* target)
478 {
479  as_faa_rlx(target, 1);
480 }
481 
482 static inline void
483 as_incr_uint32(uint32_t* target)
484 {
485  as_faa_rlx(target, 1);
486 }
487 
488 static inline void
489 as_incr_int32(int32_t* target)
490 {
491  as_faa_rlx(target, 1);
492 }
493 
494 static inline void
495 as_incr_uint16(uint16_t* target)
496 {
497  as_faa_rlx(target, 1);
498 }
499 
500 static inline void
501 as_incr_int16(int16_t* target)
502 {
503  as_faa_rlx(target, 1);
504 }
505 
506 // "Release" wrappers.
507 
508 static inline void
509 as_incr_uint64_rls(uint64_t* target)
510 {
511  as_faa_rls(target, 1);
512 }
513 
514 static inline void
515 as_incr_int64_rls(int64_t* target)
516 {
517  as_faa_rls(target, 1);
518 }
519 
520 static inline void
521 as_incr_uint32_rls(uint32_t* target)
522 {
523  as_faa_rls(target, 1);
524 }
525 
526 static inline void
527 as_incr_int32_rls(int32_t* target)
528 {
529  as_faa_rls(target, 1);
530 }
531 
532 static inline void
533 as_incr_uint16_rls(uint16_t* target)
534 {
535  as_faa_rls(target, 1);
536 }
537 
538 static inline void
539 as_incr_int16_rls(int16_t* target)
540 {
541  as_faa_rls(target, 1);
542 }
543 
544 /******************************************************************************
545  * DECREMENT
546  *****************************************************************************/
547 
548 // "Relaxed" wrappers.
549 
550 static inline void
551 as_decr_uint64(uint64_t* target)
552 {
553  as_faa_rlx(target, -1);
554 }
555 
556 static inline void
557 as_decr_int64(int64_t* target)
558 {
559  as_faa_rlx(target, -1);
560 }
561 
562 static inline void
563 as_decr_uint32(uint32_t* target)
564 {
565  as_faa_rlx(target, -1);
566 }
567 
568 static inline void
569 as_decr_int32(int32_t* target)
570 {
571  as_faa_rlx(target, -1);
572 }
573 
574 static inline void
575 as_decr_uint16(uint16_t* target)
576 {
577  as_faa_rlx(target, -1);
578 }
579 
580 static inline void
581 as_decr_int16(int16_t* target)
582 {
583  as_faa_rlx(target, -1);
584 }
585 
586 // "Release" wrappers.
587 
588 static inline void
589 as_decr_uint64_rls(uint64_t* target)
590 {
591  as_faa_rls(target, -1);
592 }
593 
594 static inline void
595 as_decr_int64_rls(int64_t* target)
596 {
597  as_faa_rls(target, -1);
598 }
599 
600 static inline void
601 as_decr_uint32_rls(uint32_t* target)
602 {
603  as_faa_rls(target, -1);
604 }
605 
606 static inline void
607 as_decr_int32_rls(int32_t* target)
608 {
609  as_faa_rls(target, -1);
610 }
611 
612 static inline void
613 as_decr_uint16_rls(uint16_t* target)
614 {
615  as_faa_rls(target, -1);
616 }
617 
618 static inline void
619 as_decr_int16_rls(int16_t* target)
620 {
621  as_faa_rls(target, -1);
622 }
623 
624 /******************************************************************************
625  * FETCH AND SWAP
626  *****************************************************************************/
627 
628 // type as_fas_rlx(type* target, type value)
629 #define as_fas_rlx(_target, _value) __atomic_exchange_n(_target, _value, __ATOMIC_RELAXED)
630 
631 // type as_fas_acq(type* target, type value)
632 #define as_fas_acq(_target, _value) __atomic_exchange_n(_target, _value, __ATOMIC_ACQUIRE)
633 
634 // type as_fas_rls(type* target, type value)
635 #define as_fas_rls(_target, _value) __atomic_exchange_n(_target, _value, __ATOMIC_RELEASE)
636 
637 // type as_fas_seq(type* target, type value)
638 #define as_fas_seq(_target, _value) __atomic_exchange_n(_target, _value, __ATOMIC_SEQ_CST)
639 
640 // "Relaxed" wrappers.
641 
642 static inline uint64_t
643 as_fas_uint64(uint64_t* target, uint64_t value)
644 {
645  return as_fas_rlx(target, value);
646 }
647 
648 static inline int64_t
649 as_fas_int64(int64_t* target, int64_t value)
650 {
651  return as_fas_rlx(target, value);
652 }
653 
654 static inline uint32_t
655 as_fas_uint32(uint32_t* target, uint32_t value)
656 {
657  return as_fas_rlx(target, value);
658 }
659 
660 static inline int32_t
661 as_fas_int32(int32_t* target, int32_t value)
662 {
663  return as_fas_rlx(target, value);
664 }
665 
666 static inline uint16_t
667 as_fas_uint16(uint16_t* target, uint16_t value)
668 {
669  return as_fas_rlx(target, value);
670 }
671 
672 static inline int16_t
673 as_fas_int16(int16_t* target, int16_t value)
674 {
675  return as_fas_rlx(target, value);
676 }
677 
678 /******************************************************************************
679  * COMPARE AND SWAP
680  *****************************************************************************/
681 
682 // bool as_cas_rlx(type* target, type* old_value, type new_value)
683 // Note - old_value is returned by pointer.
684 #define as_cas_rlx(_target, _old_value, _new_value) __atomic_compare_exchange_n(_target, _old_value, _new_value, false, __ATOMIC_RELAXED, __ATOMIC_RELAXED)
685 
686 // bool as_cas_acq(type* target, type* old_value, type new_value)
687 // Note - old_value is returned by pointer.
688 #define as_cas_acq(_target, _old_value, _new_value) __atomic_compare_exchange_n(_target, _old_value, _new_value, false, __ATOMIC_ACQUIRE, __ATOMIC_RELAXED)
689 
690 // bool as_cas_rls(type* target, type* old_value, type new_value)
691 // Note - old_value is returned by pointer.
692 #define as_cas_rls(_target, _old_value, _new_value) __atomic_compare_exchange_n(_target, _old_value, _new_value, false, __ATOMIC_RELEASE, __ATOMIC_RELAXED)
693 
694 // bool as_cas_seq(type* target, type* old_value, type new_value)
695 // Note - old_value is returned by pointer.
696 #define as_cas_seq(_target, _old_value, _new_value) __atomic_compare_exchange_n(_target, _old_value, _new_value, false, __ATOMIC_SEQ_CST, __ATOMIC_RELAXED)
697 
698 // "Relaxed" wrappers.
699 
700 static inline bool
701 as_cas_uint64(uint64_t* target, uint64_t old_value, uint64_t new_value)
702 {
703  return as_cas_rlx(target, &old_value, new_value);
704 }
705 
706 static inline bool
707 as_cas_int64(int64_t* target, int64_t old_value, int64_t new_value)
708 {
709  return as_cas_rlx(target, &old_value, new_value);
710 }
711 
712 static inline bool
713 as_cas_uint32(uint32_t* target, uint32_t old_value, uint32_t new_value)
714 {
715  return as_cas_rlx(target, &old_value, new_value);
716 }
717 
718 static inline bool
719 as_cas_int32(int32_t* target, int32_t old_value, int32_t new_value)
720 {
721  return as_cas_rlx(target, &old_value, new_value);
722 }
723 
724 static inline bool
725 as_cas_uint16(uint16_t* target, uint16_t old_value, uint16_t new_value)
726 {
727  return as_cas_rlx(target, &old_value, new_value);
728 }
729 
730 static inline bool
731 as_cas_int16(int16_t* target, int16_t old_value, int16_t new_value)
732 {
733  return as_cas_rlx(target, &old_value, new_value);
734 }
735 
736 static inline bool
737 as_cas_uint8(uint8_t* target, uint8_t old_value, uint8_t new_value)
738 {
739  return as_cas_rlx(target, &old_value, new_value);
740 }
741 
742 static inline bool
743 as_cas_int8(int8_t* target, int8_t old_value, int8_t new_value)
744 {
745  return as_cas_rlx(target, &old_value, new_value);
746 }
747 
748 /******************************************************************************
749  * MEMORY FENCE
750  *****************************************************************************/
751 
752 // void as_fence_acq()
753 #define as_fence_acq() __atomic_thread_fence(__ATOMIC_ACQUIRE)
754 
755 // void as_fence_rls()
756 #define as_fence_rls() __atomic_thread_fence(__ATOMIC_RELEASE)
757 
758 // void as_fence_rlx()
759 // Note - can be used as a compiler barrier, emits no code.
760 #define as_fence_rlx() __atomic_thread_fence(__ATOMIC_RELAXED)
761 
762 // void as_fence_seq()
763 #define as_fence_seq() __atomic_thread_fence(__ATOMIC_SEQ_CST)
764 
765 /******************************************************************************
766  * SPIN LOCK
767  *****************************************************************************/
768 
769 typedef struct as_spinlock_s {
770  uint32_t u32;
771 } as_spinlock;
772 
773 #define AS_SPINLOCK_INIT { 0 }
774 #define as_spinlock_init(_s) (_s)->u32 = 0
775 #define as_spinlock_destroy(_s) ((void)_s) // no-op
776 
777 static inline void
779 {
780  while (as_fas_acq(&s->u32, 1) == 1) {
781  // Spin on load to avoid hammering cache with write.
782  while (s->u32 == 1) {
783  as_arch_pause();
784  }
785  }
786 }
787 
788 static inline void
790 {
791  as_store_rls(&s->u32, 0);
792 }
793 
794 /******************************************************************************
795  * SPIN WRITER/READERS LOCK
796  *****************************************************************************/
797 
798 typedef struct as_swlock_s {
799  uint32_t u32;
800 } as_swlock;
801 
802 #define AS_SWLOCK_INIT { 0 }
803 #define as_swlock_init(_s) (_s)->u32 = 0
804 #define as_swlock_destroy(_s) ((void)_s) // no-op
805 
806 #define AS_SWLOCK_WRITER_BIT ((uint32_t)1 << 31)
807 #define AS_SWLOCK_LATCH_BIT ((uint32_t)1 << 30)
808 #define AS_SWLOCK_WRITER_MASK (AS_SWLOCK_LATCH_BIT | AS_SWLOCK_WRITER_BIT)
809 #define AS_SWLOCK_READER_MASK (UINT32_MAX ^ AS_SWLOCK_WRITER_MASK)
810 
811 static inline void
813 {
814  __atomic_fetch_or(&rw->u32, AS_SWLOCK_WRITER_BIT, __ATOMIC_RELAXED);
815 
816  while ((as_load_acq(&rw->u32) & AS_SWLOCK_READER_MASK) != 0) {
817  as_arch_pause();
818  }
819 }
820 
821 static inline void
823 {
824  __atomic_fetch_and(&rw->u32, AS_SWLOCK_READER_MASK, __ATOMIC_RELEASE);
825 }
826 
827 static inline void
829 {
830  while (true) {
831  while ((as_load_acq(&rw->u32) & AS_SWLOCK_WRITER_BIT) != 0) {
832  as_arch_pause();
833  }
834 
835  uint32_t l = as_faa_uint32(&rw->u32, 1) & AS_SWLOCK_WRITER_MASK;
836 
837  if (l == 0) {
838  break;
839  }
840 
841  // If latch bit has not been set, then writer would have observed reader
842  // and will wait to completion of read-side critical section.
843  if (l == AS_SWLOCK_WRITER_BIT) {
844  as_decr_uint32(&rw->u32);
845  }
846  }
847 }
848 
849 static inline void
851 {
852  as_faa_rls(&rw->u32, -1);
853 }
854 
855 /******************************************************************************
856  * SET MAX
857  *****************************************************************************/
858 
859 static inline bool
860 as_setmax_uint64(uint64_t* target, uint64_t x)
861 {
862  // Get the current value of the atomic integer.
863  uint64_t cur = as_load_uint64(target);
864 
865  while (x > cur) {
866  // Proposed value is larger than current - attempt compare-and-swap.
867 
868  // Note - can't use as_cas_uint64() since we need cur to change.
869  if (as_cas_rlx(target, &cur, x)) {
870  return true;
871  }
872  }
873 
874  // Proposed value not swapped in as new maximum.
875  return false;
876 }
877 
878 static inline bool
879 as_setmax_uint32(uint32_t* target, uint32_t x)
880 {
881  // Get the current value of the atomic integer.
882  uint32_t cur = as_load_uint32(target);
883 
884  while (x > cur) {
885  // Proposed value is larger than current - attempt compare-and-swap.
886 
887  // Note - can't use as_cas_uint32() since we need cur to change.
888  if (as_cas_rlx(target, &cur, x)) {
889  return true;
890  }
891  }
892 
893  // Proposed value not swapped in as new maximum.
894  return false;
895 }
896 
897 #ifdef __cplusplus
898 } // end extern "C"
899 #endif
static void as_store_uint16_rls(uint16_t *target, uint16_t value)
static int32_t as_fas_int32(int32_t *target, int32_t value)
static uint32_t as_fas_uint32(uint32_t *target, uint32_t value)
static int64_t as_load_int64(const int64_t *target)
Definition: as_atomic_gcc.h:54
static uint16_t as_load_uint16_acq(const uint16_t *target)
static int64_t as_aaf_int64(int64_t *target, int64_t value)
static void as_store_int16(int16_t *target, int16_t value)
static void as_incr_int16_rls(int16_t *target)
static uint32_t as_aaf_uint32(uint32_t *target, int32_t value)
static void as_store_int32(int32_t *target, int32_t value)
uint32_t u32
static void as_decr_uint16(uint16_t *target)
static int16_t as_load_int16(const int16_t *target)
Definition: as_atomic_gcc.h:78
static void as_add_uint16(uint16_t *target, int16_t value)
static void as_incr_uint16_rls(uint16_t *target)
static void * as_load_ptr_acq(void *const *target)
Definition: as_atomic_gcc.h:98
static void as_decr_int32(int32_t *target)
static void as_store_uint8(uint8_t *target, uint8_t value)
static void as_store_ptr_rls(void **target, void *value)
#define AS_SWLOCK_WRITER_BIT
static int8_t as_load_int8_acq(const int8_t *target)
static void as_decr_uint32_rls(uint32_t *target)
static uint64_t as_aaf_uint64_rls(uint64_t *target, int64_t value)
static void as_store_int8(int8_t *target, int8_t value)
static void as_store_int32_rls(int32_t *target, int32_t value)
static int64_t as_faa_int64(int64_t *target, int64_t value)
static int8_t as_load_int8(const int8_t *target)
Definition: as_atomic_gcc.h:90
static void as_decr_int64(int64_t *target)
static bool as_cas_uint32(uint32_t *target, uint32_t old_value, uint32_t new_value)
static void as_incr_uint64_rls(uint64_t *target)
#define as_store_rls(_target, _value)
static bool as_cas_uint64(uint64_t *target, uint64_t old_value, uint64_t new_value)
#define as_load_rlx(_target)
Definition: as_atomic_gcc.h:31
static int32_t as_faa_int32(int32_t *target, int32_t value)
static void as_decr_int16(int16_t *target)
uint32_t as_swlock
static void as_add_int16(int16_t *target, int16_t value)
static void as_decr_int16_rls(int16_t *target)
static void as_store_uint32(uint32_t *target, uint32_t value)
static int16_t as_aaf_int16(int16_t *target, int16_t value)
#define as_load_acq(_target)
Definition: as_atomic_gcc.h:34
static void as_store_ptr(void **target, void *value)
static void as_swlock_read_unlock(as_swlock *rw)
static void as_incr_uint32(uint32_t *target)
static void as_add_int32(int32_t *target, int32_t value)
static int64_t as_aaf_int64_rls(int64_t *target, int64_t value)
static void as_store_uint64(uint64_t *target, uint64_t value)
static uint32_t as_faa_uint32(uint32_t *target, int32_t value)
static bool as_cas_int16(int16_t *target, int16_t old_value, int16_t new_value)
static uint64_t as_faa_uint64(uint64_t *target, int64_t value)
static uint64_t as_load_uint64_acq(const uint64_t *target)
static uint32_t as_load_uint32_acq(const uint32_t *target)
#define as_fas_rlx(_target, _value)
static uint32_t as_load_uint32(const uint32_t *target)
Definition: as_atomic_gcc.h:60
static void as_store_int64_rls(int64_t *target, int64_t value)
static int32_t as_aaf_int32_rls(int32_t *target, int32_t value)
static void as_decr_uint16_rls(uint16_t *target)
uint32_t u32
static void as_incr_uint16(uint16_t *target)
static uint32_t as_aaf_uint32_rls(uint32_t *target, int32_t value)
static bool as_cas_int8(int8_t *target, int8_t old_value, int8_t new_value)
#define as_faa_rls(_target, _value)
static bool as_cas_uint8(uint8_t *target, uint8_t old_value, uint8_t new_value)
#define AS_SWLOCK_WRITER_MASK
static int64_t as_load_int64_acq(const int64_t *target)
static bool as_setmax_uint64(uint64_t *target, uint64_t x)
static int16_t as_load_int16_acq(const int16_t *target)
static uint64_t as_aaf_uint64(uint64_t *target, int64_t value)
static void as_add_uint64(uint64_t *target, int64_t value)
static uint64_t as_load_uint64(const uint64_t *target)
Definition: as_atomic_gcc.h:48
static void as_decr_uint64_rls(uint64_t *target)
static uint16_t as_fas_uint16(uint16_t *target, uint16_t value)
#define as_faa_rlx(_target, _value)
static int16_t as_fas_int16(int16_t *target, int16_t value)
static int32_t as_load_int32(const int32_t *target)
Definition: as_atomic_gcc.h:66
static void as_incr_int64(int64_t *target)
static void as_swlock_write_lock(as_swlock *rw)
static bool as_cas_int64(int64_t *target, int64_t old_value, int64_t new_value)
static bool as_cas_uint16(uint16_t *target, uint16_t old_value, uint16_t new_value)
static void as_spinlock_unlock(as_spinlock *s)
#define as_fas_acq(_target, _value)
static void as_add_int64(int64_t *target, int64_t value)
static uint8_t as_load_uint8_acq(const uint8_t *target)
static void as_store_uint16(uint16_t *target, uint16_t value)
static void as_swlock_write_unlock(as_swlock *rw)
static uint16_t as_aaf_uint16(uint16_t *target, int16_t value)
static int16_t as_aaf_int16_rls(int16_t *target, int16_t value)
static void as_swlock_read_lock(as_swlock *rw)
static void as_store_int16_rls(int16_t *target, int16_t value)
static uint8_t as_load_uint8(const uint8_t *target)
Definition: as_atomic_gcc.h:84
static uint16_t as_faa_uint16(uint16_t *target, int16_t value)
static void as_decr_int64_rls(int64_t *target)
uint32_t as_spinlock
static void as_incr_int32_rls(int32_t *target)
static void as_spinlock_lock(as_spinlock *s)
static void as_store_int64(int64_t *target, int64_t value)
static void as_decr_uint32(uint32_t *target)
#define as_cas_rlx(_target, _old_value, _new_value)
static void as_incr_int64_rls(int64_t *target)
static void as_decr_uint64(uint64_t *target)
static bool as_cas_int32(int32_t *target, int32_t old_value, int32_t new_value)
static uint64_t as_fas_uint64(uint64_t *target, uint64_t value)
static int32_t as_load_int32_acq(const int32_t *target)
static void as_decr_int32_rls(int32_t *target)
static uint16_t as_aaf_uint16_rls(uint16_t *target, int16_t value)
static int16_t as_faa_int16(int16_t *target, int16_t value)
#define as_aaf_rlx(_target, _value)
static void as_store_int8_rls(int8_t *target, int8_t value)
static bool as_setmax_uint32(uint32_t *target, uint32_t x)
#define as_store_rlx(_target, _value)
static uint16_t as_load_uint16(const uint16_t *target)
Definition: as_atomic_gcc.h:72
#define as_aaf_rls(_target, _value)
static void as_incr_int16(int16_t *target)
static int32_t as_aaf_int32(int32_t *target, int32_t value)
static void as_incr_uint32_rls(uint32_t *target)
static void as_store_uint64_rls(uint64_t *target, uint64_t value)
static void as_add_uint32(uint32_t *target, int32_t value)
static void as_store_uint8_rls(uint8_t *target, uint8_t value)
static void as_incr_int32(int32_t *target)
static void as_incr_uint64(uint64_t *target)
#define AS_SWLOCK_READER_MASK
static void * as_load_ptr(void *const *target)
Definition: as_atomic_gcc.h:42
static void as_store_uint32_rls(uint32_t *target, uint32_t value)
static int64_t as_fas_int64(int64_t *target, int64_t value)