diff --git a/src/libstrongswan/utils/utils/atomics.c b/src/libstrongswan/utils/utils/atomics.c index bc0b9bbaf..427d15ec8 100644 --- a/src/libstrongswan/utils/utils/atomics.c +++ b/src/libstrongswan/utils/utils/atomics.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008-2014 Tobias Brunner + * Copyright (C) 2008-2026 Tobias Brunner * Copyright (C) 2005-2008 Martin Willi * * Copyright (C) secunet Security Networks AG @@ -68,7 +68,7 @@ refcount_t ref_cur(refcount_t *ref) } /** - * Spinlock for all compare and swap operations. + * Spinlock for all compare, swap and get/set operations. */ static spinlock_t *cas_lock; @@ -88,6 +88,23 @@ bool cas_##name(type *ptr, type oldval, type newval) \ _cas_impl(bool, bool) _cas_impl(ptr, void*) +bool atomic_get_bool(bool *ptr) +{ + bool val; + + cas_lock->lock(cas_lock); + val = *ptr; + cas_lock->unlock(cas_lock); + return val; +} + +void atomic_set_bool(bool *ptr, bool val) +{ + cas_lock->lock(cas_lock); + *ptr = val; + cas_lock->unlock(cas_lock); +} + #endif /* !HAVE_GCC_ATOMIC_OPERATIONS && !HAVE_GCC_SYNC_OPERATIONS */ /** diff --git a/src/libstrongswan/utils/utils/atomics.h b/src/libstrongswan/utils/utils/atomics.h index 63aec7571..c3521daa2 100644 --- a/src/libstrongswan/utils/utils/atomics.h +++ b/src/libstrongswan/utils/utils/atomics.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008-2014 Tobias Brunner + * Copyright (C) 2008-2026 Tobias Brunner * Copyright (C) 2008 Martin Willi * * Copyright (C) secunet Security Networks AG @@ -62,6 +62,9 @@ typedef u_int refcount_t; #define cas_bool(ptr, oldval, newval) _cas_impl(ptr, oldval, newval) #define cas_ptr(ptr, oldval, newval) _cas_impl(ptr, oldval, newval) +#define atomic_get_bool(ptr) __atomic_load_n(ptr, __ATOMIC_ACQUIRE) +#define atomic_set_bool(ptr, val) __atomic_store_n(ptr, val, __ATOMIC_RELEASE) + #elif defined(HAVE_GCC_SYNC_OPERATIONS) #define ref_get(ref) __sync_add_and_fetch(ref, 1) @@ -73,6 +76,9 @@ typedef u_int refcount_t; #define cas_ptr(ptr, oldval, newval) \ (__sync_bool_compare_and_swap(ptr, oldval, newval)) +#define atomic_get_bool(ptr) ({ bool _v = *(ptr); __sync_synchronize(); _v; }) +#define atomic_set_bool(ptr, val) (__sync_synchronize(), *(ptr) = (val)) + #else /* !HAVE_GCC_ATOMIC_OPERATIONS && !HAVE_GCC_SYNC_OPERATIONS */ /** @@ -124,6 +130,22 @@ bool cas_bool(bool *ptr, bool oldval, bool newval); */ bool cas_ptr(void **ptr, void *oldval, void *newval); +/** + * Atomically read value of ptr. + * + * @param ptr pointer to variable + * @return current value + */ +bool atomic_get_bool(bool *ptr); + +/** + * Atomically set value of ptr to val. + * + * @param ptr pointer to variable + * @param val new value + */ +void atomic_set_bool(bool *ptr, bool val); + #endif /* HAVE_GCC_ATOMIC_OPERATIONS */ /**