diff options
Diffstat (limited to 'src/platform')
| -rw-r--r-- | src/platform/posix/posix_atomic.c | 57 | ||||
| -rw-r--r-- | src/platform/posix/posix_impl.h | 13 | ||||
| -rw-r--r-- | src/platform/posix/posix_thread.c | 1 | ||||
| -rw-r--r-- | src/platform/windows/win_impl.h | 4 | ||||
| -rw-r--r-- | src/platform/windows/win_thread.c | 12 |
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; |
