Skip to content

Commit a788d53

Browse files
committed
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 dd5ad43 commit a788d53

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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy