aboutsummaryrefslogtreecommitdiff
path: root/src/platform
diff options
context:
space:
mode:
Diffstat (limited to 'src/platform')
-rw-r--r--src/platform/posix/posix_atomic.c57
-rw-r--r--src/platform/posix/posix_impl.h13
-rw-r--r--src/platform/posix/posix_thread.c1
-rw-r--r--src/platform/windows/win_impl.h4
-rw-r--r--src/platform/windows/win_thread.c12
5 files changed, 87 insertions, 0 deletions
diff --git a/src/platform/posix/posix_atomic.c b/src/platform/posix/posix_atomic.c
new file mode 100644
index 00000000..a8d2579d
--- /dev/null
+++ b/src/platform/posix/posix_atomic.c
@@ -0,0 +1,57 @@
+//
+// Copyright 2018 Staysail Systems, Inc. <info@staysail.tech>
+// Copyright 2018 Capitar IT Group BV <info@capitar.com>
+//
+// This software is supplied under the terms of the MIT License, a
+// copy of which should be located in the distribution where this
+// file was obtained (LICENSE.txt). A copy of the license may also be
+// found online at https://opensource.org/licenses/MIT.
+//
+
+// POSIX atomics.
+
+#include "core/nng_impl.h"
+
+#ifdef NNG_PLATFORM_POSIX
+
+#ifdef NNG_HAVE_STDATOMIC
+
+#include <stdatomic.h>
+bool
+nni_atomic_flag_test_and_set(nni_atomic_flag *f)
+{
+ return (atomic_flag_test_and_set(&f->f));
+}
+
+void
+nni_atomic_flag_reset(nni_atomic_flag *f)
+{
+ atomic_flag_clear(&f->f);
+}
+#else
+
+#include <pthread.h>
+
+static pthread_mutex_t plat_atomic_lock = PTHREAD_MUTEX_INITIALIZER;
+
+bool
+nni_atomic_flag_test_and_set(nni_atomic_flag *f)
+{
+ bool v;
+ pthread_mutex_lock(&plat_atomic_lock);
+ v = f->f;
+ f->f = true;
+ pthread_mutex_unlock(&plat_atomic_lock);
+ return (v);
+}
+
+void
+nni_atomic_flag_reset(nni_atomic_flag *f)
+{
+ pthread_mutex_lock(&plat_atomic_lock);
+ f->f = false;
+ pthread_mutex_unlock(&plat_atomic_lock);
+}
+#endif
+
+#endif // NNG_PLATFORM_POSIX
diff --git a/src/platform/posix/posix_impl.h b/src/platform/posix/posix_impl.h
index 33a9c293..70a3615f 100644
--- a/src/platform/posix/posix_impl.h
+++ b/src/platform/posix/posix_impl.h
@@ -75,6 +75,19 @@ struct nni_plat_flock {
#define NNG_PLATFORM_DIR_SEP "/"
+#ifdef NNG_HAVE_STDATOMIC
+
+#include <stdatomic.h>
+
+struct nni_atomic_flag {
+ atomic_flag f;
+};
+#else // NNG_HAVE_C11_ATOMIC
+struct nni_atomic_flag {
+ bool f;
+};
+#endif
+
#endif
extern int nni_posix_pollq_sysinit(void);
diff --git a/src/platform/posix/posix_thread.c b/src/platform/posix/posix_thread.c
index df2ee9d2..cc2ade6f 100644
--- a/src/platform/posix/posix_thread.c
+++ b/src/platform/posix/posix_thread.c
@@ -348,4 +348,5 @@ nni_plat_ncpu(void)
return (1);
#endif
}
+
#endif // NNG_PLATFORM_POSIX
diff --git a/src/platform/windows/win_impl.h b/src/platform/windows/win_impl.h
index 0bd12b24..73dc3660 100644
--- a/src/platform/windows/win_impl.h
+++ b/src/platform/windows/win_impl.h
@@ -48,6 +48,10 @@ struct nni_plat_cv {
PSRWLOCK srl;
};
+struct nni_atomic_flag {
+ unsigned f;
+};
+
// nni_win_event is used with io completion ports. This allows us to get
// to a specific completion callback without requiring the poller (in the
// completion port) to know anything about the event itself. We also use
diff --git a/src/platform/windows/win_thread.c b/src/platform/windows/win_thread.c
index a3d932aa..243811a0 100644
--- a/src/platform/windows/win_thread.c
+++ b/src/platform/windows/win_thread.c
@@ -103,6 +103,18 @@ nni_plat_cv_fini(nni_plat_cv *cv)
NNI_ARG_UNUSED(cv);
}
+bool
+nni_atomic_flag_test_and_set(nni_atomic_flag *f)
+{
+ return (InterlockedExchange(&f->f, 1) != 0);
+}
+
+void
+nni_atomic_flag_reset(nni_atomic_flag *f)
+{
+ InterlockedExchange(&f->f, 0);
+}
+
static unsigned int __stdcall nni_plat_thr_main(void *arg)
{
nni_plat_thr *thr = arg;