Skip to content

Commit 98aa2a6

Browse files
fuhsnnnobu
authored andcommitted
atomic.h: Add C11 <stdatomic.h> implementation
The implementation is only active if `HAVE_STDATOMIC_H` is defined, and only after the compiler fails to match all currently supported systems.
1 parent a799240 commit 98aa2a6

File tree

1 file changed

+55
-0
lines changed

1 file changed

+55
-0
lines changed

include/ruby/atomic.h

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,9 @@ typedef unsigned int rb_atomic_t;
7777
typedef LONG rb_atomic_t;
7878
#elif defined(__sun) && defined(HAVE_ATOMIC_H)
7979
typedef unsigned int rb_atomic_t;
80+
#elif defined(HAVE_STDATOMIC_H)
81+
# include <stdatomic.h>
82+
typedef unsigned int rb_atomic_t;
8083
#else
8184
# error No atomic operation found
8285
#endif
@@ -408,6 +411,9 @@ rbimpl_atomic_fetch_add(volatile rb_atomic_t *ptr, rb_atomic_t val)
408411
RBIMPL_ASSERT_OR_ASSUME(val <= INT_MAX);
409412
return atomic_add_int_nv(ptr, val) - val;
410413

414+
#elif defined(HAVE_STDATOMIC_H)
415+
return atomic_fetch_add((_Atomic volatile rb_atomic_t *)ptr, val);
416+
411417
#else
412418
# error Unsupported platform.
413419
#endif
@@ -442,6 +448,9 @@ rbimpl_atomic_size_fetch_add(volatile size_t *ptr, size_t val)
442448
volatile rb_atomic_t *const tmp = RBIMPL_CAST((volatile rb_atomic_t *)ptr);
443449
rbimpl_atomic_fetch_add(tmp, val);
444450

451+
#elif defined(HAVE_STDATOMIC_H)
452+
return atomic_fetch_add((_Atomic volatile size_t *)ptr, val);
453+
445454
#else
446455
# error Unsupported platform.
447456
#endif
@@ -479,6 +488,9 @@ rbimpl_atomic_add(volatile rb_atomic_t *ptr, rb_atomic_t val)
479488
RBIMPL_ASSERT_OR_ASSUME(val <= INT_MAX);
480489
atomic_add_int(ptr, val);
481490

491+
#elif defined(HAVE_STDATOMIC_H)
492+
*(_Atomic volatile rb_atomic_t *)ptr += val;
493+
482494
#else
483495
# error Unsupported platform.
484496
#endif
@@ -513,6 +525,9 @@ rbimpl_atomic_size_add(volatile size_t *ptr, size_t val)
513525
volatile rb_atomic_t *const tmp = RBIMPL_CAST((volatile rb_atomic_t *)ptr);
514526
rbimpl_atomic_add(tmp, val);
515527

528+
#elif defined(HAVE_STDATOMIC_H)
529+
*(_Atomic volatile size_t *)ptr += val;
530+
516531
#else
517532
# error Unsupported platform.
518533
#endif
@@ -535,6 +550,9 @@ rbimpl_atomic_inc(volatile rb_atomic_t *ptr)
535550
#elif defined(__sun) && defined(HAVE_ATOMIC_H)
536551
atomic_inc_uint(ptr);
537552

553+
#elif defined(HAVE_STDATOMIC_H)
554+
rbimpl_atomic_add(ptr, 1);
555+
538556
#else
539557
# error Unsupported platform.
540558
#endif
@@ -562,6 +580,9 @@ rbimpl_atomic_size_inc(volatile size_t *ptr)
562580

563581
rbimpl_atomic_size_add(ptr, 1);
564582

583+
#elif defined(HAVE_STDATOMIC_H)
584+
rbimpl_atomic_size_add(ptr, 1);
585+
565586
#else
566587
# error Unsupported platform.
567588
#endif
@@ -591,6 +612,9 @@ rbimpl_atomic_fetch_sub(volatile rb_atomic_t *ptr, rb_atomic_t val)
591612
RBIMPL_ASSERT_OR_ASSUME(val <= INT_MAX);
592613
return atomic_add_int_nv(ptr, neg * val) + val;
593614

615+
#elif defined(HAVE_STDATOMIC_H)
616+
return atomic_fetch_sub((_Atomic volatile rb_atomic_t *)ptr, val);
617+
594618
#else
595619
# error Unsupported platform.
596620
#endif
@@ -618,6 +642,9 @@ rbimpl_atomic_sub(volatile rb_atomic_t *ptr, rb_atomic_t val)
618642
RBIMPL_ASSERT_OR_ASSUME(val <= INT_MAX);
619643
atomic_add_int(ptr, neg * val);
620644

645+
#elif defined(HAVE_STDATOMIC_H)
646+
*(_Atomic volatile rb_atomic_t *)ptr -= val;
647+
621648
#else
622649
# error Unsupported platform.
623650
#endif
@@ -652,6 +679,9 @@ rbimpl_atomic_size_sub(volatile size_t *ptr, size_t val)
652679
volatile rb_atomic_t *const tmp = RBIMPL_CAST((volatile rb_atomic_t *)ptr);
653680
rbimpl_atomic_sub(tmp, val);
654681

682+
#elif defined(HAVE_STDATOMIC_H)
683+
*(_Atomic volatile size_t *)ptr -= val;
684+
655685
#else
656686
# error Unsupported platform.
657687
#endif
@@ -674,6 +704,9 @@ rbimpl_atomic_dec(volatile rb_atomic_t *ptr)
674704
#elif defined(__sun) && defined(HAVE_ATOMIC_H)
675705
atomic_dec_uint(ptr);
676706

707+
#elif defined(HAVE_STDATOMIC_H)
708+
rbimpl_atomic_sub(ptr, 1);
709+
677710
#else
678711
# error Unsupported platform.
679712
#endif
@@ -701,6 +734,9 @@ rbimpl_atomic_size_dec(volatile size_t *ptr)
701734

702735
rbimpl_atomic_size_sub(ptr, 1);
703736

737+
#elif defined(HAVE_STDATOMIC_H)
738+
rbimpl_atomic_size_sub(ptr, 1);
739+
704740
#else
705741
# error Unsupported platform.
706742
#endif
@@ -739,6 +775,9 @@ rbimpl_atomic_or(volatile rb_atomic_t *ptr, rb_atomic_t val)
739775
#elif defined(__sun) && defined(HAVE_ATOMIC_H)
740776
atomic_or_uint(ptr, val);
741777

778+
#elif !defined(_WIN32) && defined(HAVE_STDATOMIC_H)
779+
*(_Atomic volatile rb_atomic_t *)ptr |= val;
780+
742781
#else
743782
# error Unsupported platform.
744783
#endif
@@ -773,6 +812,9 @@ rbimpl_atomic_exchange(volatile rb_atomic_t *ptr, rb_atomic_t val)
773812
#elif defined(__sun) && defined(HAVE_ATOMIC_H)
774813
return atomic_swap_uint(ptr, val);
775814

815+
#elif defined(HAVE_STDATOMIC_H)
816+
return atomic_exchange((_Atomic volatile rb_atomic_t *)ptr, val);
817+
776818
#else
777819
# error Unsupported platform.
778820
#endif
@@ -805,6 +847,9 @@ rbimpl_atomic_size_exchange(volatile size_t *ptr, size_t val)
805847
const rb_atomic_t ret = rbimpl_atomic_exchange(tmp, val);
806848
return RBIMPL_CAST((size_t)ret);
807849

850+
#elif defined(HAVE_STDATOMIC_H)
851+
return atomic_exchange((_Atomic volatile size_t *)ptr, val);
852+
808853
#else
809854
# error Unsupported platform.
810855
#endif
@@ -957,6 +1002,11 @@ rbimpl_atomic_cas(volatile rb_atomic_t *ptr, rb_atomic_t oldval, rb_atomic_t new
9571002
#elif defined(__sun) && defined(HAVE_ATOMIC_H)
9581003
return atomic_cas_uint(ptr, oldval, newval);
9591004

1005+
#elif defined(HAVE_STDATOMIC_H)
1006+
atomic_compare_exchange_strong(
1007+
(_Atomic volatile rb_atomic_t *)ptr, &oldval, newval);
1008+
return oldval;
1009+
9601010
#else
9611011
# error Unsupported platform.
9621012
#endif
@@ -999,6 +1049,11 @@ rbimpl_atomic_size_cas(volatile size_t *ptr, size_t oldval, size_t newval)
9991049
volatile rb_atomic_t *tmp = RBIMPL_CAST((volatile rb_atomic_t *)ptr);
10001050
return rbimpl_atomic_cas(tmp, oldval, newval);
10011051

1052+
#elif defined(HAVE_STDATOMIC_H)
1053+
atomic_compare_exchange_strong(
1054+
(_Atomic volatile size_t *)ptr, &oldval, newval);
1055+
return oldval;
1056+
10021057
#else
10031058
# error Unsupported platform.
10041059
#endif

0 commit comments

Comments
 (0)