aboutsummaryrefslogtreecommitdiff
path: root/src/platform/posix/posix_atomic.c
diff options
context:
space:
mode:
authorGarrett D'Amore <garrett@damore.org>2021-12-08 12:01:32 -0500
committerGarrett D'Amore <garrett@damore.org>2021-12-08 20:08:47 -0500
commitdc91bed46dd12fdc843b9e2c4ed9f3e570914ba3 (patch)
tree7bc1d46d7a4edeee347f3b3c6daca9c832e7a341 /src/platform/posix/posix_atomic.c
parent317fdb2ff02c98d88a3950791e938b1db3cca1cd (diff)
downloadnng-dc91bed46dd12fdc843b9e2c4ed9f3e570914ba3.tar.gz
nng-dc91bed46dd12fdc843b9e2c4ed9f3e570914ba3.tar.bz2
nng-dc91bed46dd12fdc843b9e2c4ed9f3e570914ba3.zip
Could use GCC atomics for older versions of GCC.
This should help greatly with performance on older systems such as CentOS 7 and GCC 4.8. Though, such folks really should update to newer compilers. Folks running version of GCC earlier than 4.7 will still pay a rather significant performance penalty, as they still implement atomics with a global mutex.
Diffstat (limited to 'src/platform/posix/posix_atomic.c')
-rw-r--r--src/platform/posix/posix_atomic.c155
1 files changed, 154 insertions, 1 deletions
diff --git a/src/platform/posix/posix_atomic.c b/src/platform/posix/posix_atomic.c
index b75bbfd7..0f904ae1 100644
--- a/src/platform/posix/posix_atomic.c
+++ b/src/platform/posix/posix_atomic.c
@@ -81,7 +81,7 @@ nni_atomic_get(nni_atomic_int *v)
void
nni_atomic_set(nni_atomic_int *v, int i)
{
- atomic_store(&v->v, i);
+ atomic_store(&v->v, i);
}
void *
@@ -190,6 +190,159 @@ nni_atomic_cas64(nni_atomic_u64 *v, uint64_t comp, uint64_t new)
return (atomic_compare_exchange_strong(&v->v, &cv, nv));
}
+#elif NNI_GCC_VERSION >= 40700 || \
+ defined(__clang__) // we have "new" GCC __atomic builtins
+bool
+nni_atomic_flag_test_and_set(nni_atomic_flag *f)
+{
+ return (__atomic_test_and_set(&f->f, __ATOMIC_SEQ_CST));
+}
+
+void
+nni_atomic_flag_reset(nni_atomic_flag *f)
+{
+ __atomic_clear(&f->f, __ATOMIC_SEQ_CST);
+}
+
+void
+nni_atomic_set_bool(nni_atomic_bool *b, bool n)
+{
+ __atomic_store_n(&b->b, n, __ATOMIC_SEQ_CST);
+}
+
+bool
+nni_atomic_get_bool(nni_atomic_bool *b)
+{
+ return (__atomic_load_n(&b->b, __ATOMIC_SEQ_CST));
+}
+
+bool
+nni_atomic_swap_bool(nni_atomic_bool *b, bool n)
+{
+ return (__atomic_exchange_n(&b->b, n, __ATOMIC_SEQ_CST));
+}
+
+void
+nni_atomic_init_bool(nni_atomic_bool *b)
+{
+ __atomic_store_n(&b->b, false, __ATOMIC_SEQ_CST);
+}
+
+void
+nni_atomic_add64(nni_atomic_u64 *v, uint64_t bump)
+{
+ __atomic_add_fetch(&v->v, bump, __ATOMIC_RELAXED);
+}
+
+void
+nni_atomic_sub64(nni_atomic_u64 *v, uint64_t bump)
+{
+ __atomic_sub_fetch(&v->v, bump, __ATOMIC_RELAXED);
+}
+
+uint64_t
+nni_atomic_get64(nni_atomic_u64 *v)
+{
+ return (__atomic_load_n(&v->v, __ATOMIC_SEQ_CST));
+}
+
+void
+nni_atomic_set64(nni_atomic_u64 *v, uint64_t u)
+{
+ __atomic_store_n(&v->v, u, __ATOMIC_SEQ_CST);
+}
+
+uint64_t
+nni_atomic_swap64(nni_atomic_u64 *v, uint64_t u)
+{
+ return (__atomic_exchange_n(&v->v, u, __ATOMIC_SEQ_CST));
+}
+
+void
+nni_atomic_init64(nni_atomic_u64 *v)
+{
+ __atomic_store_n(&v->v, 0, __ATOMIC_SEQ_CST);
+}
+
+void
+nni_atomic_inc64(nni_atomic_u64 *v)
+{
+ __atomic_add_fetch(&v->v, 1, __ATOMIC_SEQ_CST);
+}
+
+uint64_t
+nni_atomic_dec64_nv(nni_atomic_u64 *v)
+{
+ return (__atomic_sub_fetch(&v->v, 1, __ATOMIC_SEQ_CST));
+}
+
+bool
+nni_atomic_cas64(nni_atomic_u64 *v, uint64_t comp, uint64_t new)
+{
+
+ return (__atomic_compare_exchange_n(
+ &v->v, &comp, new, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST));
+}
+
+void
+nni_atomic_init(nni_atomic_int *v)
+{
+ __atomic_store_n(&v->v, 0, __ATOMIC_SEQ_CST);
+}
+
+void
+nni_atomic_add(nni_atomic_int *v, int bump)
+{
+ __atomic_add_fetch(&v->v, bump, __ATOMIC_RELAXED);
+}
+
+void
+nni_atomic_sub(nni_atomic_int *v, int bump)
+{
+ __atomic_sub_fetch(&v->v, bump, __ATOMIC_RELAXED);
+}
+
+void
+nni_atomic_set(nni_atomic_int *v, int val)
+{
+ __atomic_store_n(&v->v, val, __ATOMIC_SEQ_CST);
+}
+
+int
+nni_atomic_get(nni_atomic_int *v)
+{
+ return (__atomic_load_n(&v->v, __ATOMIC_SEQ_CST));
+}
+void
+nni_atomic_inc(nni_atomic_int *v)
+{
+ __atomic_add_fetch(&v->v, 1, __ATOMIC_SEQ_CST);
+}
+
+void
+nni_atomic_dec(nni_atomic_int *v)
+{
+ __atomic_sub_fetch(&v->v, 1, __ATOMIC_SEQ_CST);
+}
+
+int
+nni_atomic_dec_nv(nni_atomic_int *v)
+{
+ return (__atomic_sub_fetch(&v->v, 1, __ATOMIC_SEQ_CST));
+}
+
+void *
+nni_atomic_get_ptr(nni_atomic_ptr *v)
+{
+ return (__atomic_load_n(&v->v, __ATOMIC_SEQ_CST));
+}
+
+void
+nni_atomic_set_ptr(nni_atomic_ptr *v, void *p)
+{
+ __atomic_store_n(&v->v, p, __ATOMIC_SEQ_CST);
+}
+
#else
#include <pthread.h>