Skip to content

atomic.h: Add C11 implmentation of atomic operations #13799

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jul 17, 2025
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
85 changes: 76 additions & 9 deletions include/ruby/atomic.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,9 @@ typedef unsigned int rb_atomic_t;
typedef LONG rb_atomic_t;
#elif defined(__sun) && defined(HAVE_ATOMIC_H)
typedef unsigned int rb_atomic_t;
#elif defined(HAVE_STDATOMIC_H)
# include <stdatomic.h>
typedef unsigned int rb_atomic_t;
#else
# error No atomic operation found
#endif
Expand Down Expand Up @@ -408,6 +411,9 @@ rbimpl_atomic_fetch_add(volatile rb_atomic_t *ptr, rb_atomic_t val)
RBIMPL_ASSERT_OR_ASSUME(val <= INT_MAX);
return atomic_add_int_nv(ptr, val) - val;

#elif defined(HAVE_STDATOMIC_H)
return atomic_fetch_add((_Atomic volatile rb_atomic_t *)ptr, val);

#else
# error Unsupported platform.
#endif
Expand Down Expand Up @@ -436,12 +442,17 @@ rbimpl_atomic_size_fetch_add(volatile size_t *ptr, size_t val)
RBIMPL_ASSERT_OR_ASSUME(val <= LONG_MAX);
atomic_add_long(ptr, val);

#else
#elif defined(__sun) && defined(HAVE_ATOMIC_H)
RBIMPL_STATIC_ASSERT(size_of_rb_atomic_t, sizeof *ptr == sizeof(rb_atomic_t));

volatile rb_atomic_t *const tmp = RBIMPL_CAST((volatile rb_atomic_t *)ptr);
rbimpl_atomic_fetch_add(tmp, val);

#elif defined(HAVE_STDATOMIC_H)
return atomic_fetch_add((_Atomic volatile size_t *)ptr, val);

#else
# error Unsupported platform.
#endif
}

Expand Down Expand Up @@ -477,6 +488,9 @@ rbimpl_atomic_add(volatile rb_atomic_t *ptr, rb_atomic_t val)
RBIMPL_ASSERT_OR_ASSUME(val <= INT_MAX);
atomic_add_int(ptr, val);

#elif defined(HAVE_STDATOMIC_H)
*(_Atomic volatile rb_atomic_t *)ptr += val;

#else
# error Unsupported platform.
#endif
Expand Down Expand Up @@ -505,12 +519,17 @@ rbimpl_atomic_size_add(volatile size_t *ptr, size_t val)
RBIMPL_ASSERT_OR_ASSUME(val <= LONG_MAX);
atomic_add_long(ptr, val);

#else
#elif defined(_WIN32) || (defined(__sun) && defined(HAVE_ATOMIC_H))
RBIMPL_STATIC_ASSERT(size_of_rb_atomic_t, sizeof *ptr == sizeof(rb_atomic_t));

volatile rb_atomic_t *const tmp = RBIMPL_CAST((volatile rb_atomic_t *)ptr);
rbimpl_atomic_add(tmp, val);

#elif defined(HAVE_STDATOMIC_H)
*(_Atomic volatile size_t *)ptr += val;

#else
# error Unsupported platform.
#endif
}

Expand All @@ -531,9 +550,11 @@ rbimpl_atomic_inc(volatile rb_atomic_t *ptr)
#elif defined(__sun) && defined(HAVE_ATOMIC_H)
atomic_inc_uint(ptr);

#else
#elif defined(HAVE_STDATOMIC_H)
rbimpl_atomic_add(ptr, 1);

#else
# error Unsupported platform.
#endif
}

Expand All @@ -554,11 +575,16 @@ rbimpl_atomic_size_inc(volatile size_t *ptr)
#elif defined(__sun) && defined(HAVE_ATOMIC_H) && (defined(_LP64) || defined(_I32LPx))
atomic_inc_ulong(ptr);

#else
#elif defined(_WIN32) || (defined(__sun) && defined(HAVE_ATOMIC_H))
RBIMPL_STATIC_ASSERT(size_of_size_t, sizeof *ptr == sizeof(rb_atomic_t));

rbimpl_atomic_size_add(ptr, 1);

#elif defined(HAVE_STDATOMIC_H)
rbimpl_atomic_size_add(ptr, 1);

#else
# error Unsupported platform.
#endif
}

Expand Down Expand Up @@ -586,6 +612,9 @@ rbimpl_atomic_fetch_sub(volatile rb_atomic_t *ptr, rb_atomic_t val)
RBIMPL_ASSERT_OR_ASSUME(val <= INT_MAX);
return atomic_add_int_nv(ptr, neg * val) + val;

#elif defined(HAVE_STDATOMIC_H)
return atomic_fetch_sub((_Atomic volatile rb_atomic_t *)ptr, val);

#else
# error Unsupported platform.
#endif
Expand Down Expand Up @@ -613,6 +642,9 @@ rbimpl_atomic_sub(volatile rb_atomic_t *ptr, rb_atomic_t val)
RBIMPL_ASSERT_OR_ASSUME(val <= INT_MAX);
atomic_add_int(ptr, neg * val);

#elif defined(HAVE_STDATOMIC_H)
*(_Atomic volatile rb_atomic_t *)ptr -= val;

#else
# error Unsupported platform.
#endif
Expand Down Expand Up @@ -641,12 +673,17 @@ rbimpl_atomic_size_sub(volatile size_t *ptr, size_t val)
RBIMPL_ASSERT_OR_ASSUME(val <= LONG_MAX);
atomic_add_long(ptr, neg * val);

#else
#elif defined(_WIN32) || (defined(__sun) && defined(HAVE_ATOMIC_H))
RBIMPL_STATIC_ASSERT(size_of_rb_atomic_t, sizeof *ptr == sizeof(rb_atomic_t));

volatile rb_atomic_t *const tmp = RBIMPL_CAST((volatile rb_atomic_t *)ptr);
rbimpl_atomic_sub(tmp, val);

#elif defined(HAVE_STDATOMIC_H)
*(_Atomic volatile size_t *)ptr -= val;

#else
# error Unsupported platform.
#endif
}

Expand All @@ -667,9 +704,11 @@ rbimpl_atomic_dec(volatile rb_atomic_t *ptr)
#elif defined(__sun) && defined(HAVE_ATOMIC_H)
atomic_dec_uint(ptr);

#else
#elif defined(HAVE_STDATOMIC_H)
rbimpl_atomic_sub(ptr, 1);

#else
# error Unsupported platform.
#endif
}

Expand All @@ -690,11 +729,16 @@ rbimpl_atomic_size_dec(volatile size_t *ptr)
#elif defined(__sun) && defined(HAVE_ATOMIC_H) && (defined(_LP64) || defined(_I32LPx))
atomic_dec_ulong(ptr);

#else
#elif defined(_WIN32) || (defined(__sun) && defined(HAVE_ATOMIC_H))
RBIMPL_STATIC_ASSERT(size_of_size_t, sizeof *ptr == sizeof(rb_atomic_t));

rbimpl_atomic_size_sub(ptr, 1);

#elif defined(HAVE_STDATOMIC_H)
rbimpl_atomic_size_sub(ptr, 1);

#else
# error Unsupported platform.
#endif
}

Expand Down Expand Up @@ -731,6 +775,9 @@ rbimpl_atomic_or(volatile rb_atomic_t *ptr, rb_atomic_t val)
#elif defined(__sun) && defined(HAVE_ATOMIC_H)
atomic_or_uint(ptr, val);

#elif !defined(_WIN32) && defined(HAVE_STDATOMIC_H)
*(_Atomic volatile rb_atomic_t *)ptr |= val;

#else
# error Unsupported platform.
#endif
Expand Down Expand Up @@ -765,6 +812,9 @@ rbimpl_atomic_exchange(volatile rb_atomic_t *ptr, rb_atomic_t val)
#elif defined(__sun) && defined(HAVE_ATOMIC_H)
return atomic_swap_uint(ptr, val);

#elif defined(HAVE_STDATOMIC_H)
return atomic_exchange((_Atomic volatile rb_atomic_t *)ptr, val);

#else
# error Unsupported platform.
#endif
Expand All @@ -790,13 +840,18 @@ rbimpl_atomic_size_exchange(volatile size_t *ptr, size_t val)
#elif defined(__sun) && defined(HAVE_ATOMIC_H) && (defined(_LP64) || defined(_I32LPx))
return atomic_swap_ulong(ptr, val);

#else
#elif defined(_WIN32) || (defined(__sun) && defined(HAVE_ATOMIC_H))
RBIMPL_STATIC_ASSERT(size_of_size_t, sizeof *ptr == sizeof(rb_atomic_t));

volatile rb_atomic_t *const tmp = RBIMPL_CAST((volatile rb_atomic_t *)ptr);
const rb_atomic_t ret = rbimpl_atomic_exchange(tmp, val);
return RBIMPL_CAST((size_t)ret);

#elif defined(HAVE_STDATOMIC_H)
return atomic_exchange((_Atomic volatile size_t *)ptr, val);

#else
# error Unsupported platform.
#endif
}

Expand Down Expand Up @@ -947,6 +1002,11 @@ rbimpl_atomic_cas(volatile rb_atomic_t *ptr, rb_atomic_t oldval, rb_atomic_t new
#elif defined(__sun) && defined(HAVE_ATOMIC_H)
return atomic_cas_uint(ptr, oldval, newval);

#elif defined(HAVE_STDATOMIC_H)
atomic_compare_exchange_strong(
(_Atomic volatile rb_atomic_t *)ptr, &oldval, newval);
return oldval;

#else
# error Unsupported platform.
#endif
Expand Down Expand Up @@ -983,12 +1043,19 @@ rbimpl_atomic_size_cas(volatile size_t *ptr, size_t oldval, size_t newval)
#elif defined(__sun) && defined(HAVE_ATOMIC_H) && (defined(_LP64) || defined(_I32LPx))
return atomic_cas_ulong(ptr, oldval, newval);

#else
#elif defined(_WIN32) || (defined(__sun) && defined(HAVE_ATOMIC_H))
RBIMPL_STATIC_ASSERT(size_of_size_t, sizeof *ptr == sizeof(rb_atomic_t));

volatile rb_atomic_t *tmp = RBIMPL_CAST((volatile rb_atomic_t *)ptr);
return rbimpl_atomic_cas(tmp, oldval, newval);

#elif defined(HAVE_STDATOMIC_H)
atomic_compare_exchange_strong(
(_Atomic volatile size_t *)ptr, &oldval, newval);
return oldval;

#else
# error Unsupported platform.
#endif
}

Expand Down
Loading
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