aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/core/platform.h9
-rw-r--r--src/platform/posix/posix_atomic.c89
-rw-r--r--src/platform/posix/posix_impl.h10
-rw-r--r--src/platform/windows/win_impl.h4
-rw-r--r--src/platform/windows/win_thread.c38
5 files changed, 150 insertions, 0 deletions
diff --git a/src/core/platform.h b/src/core/platform.h
index 48f1e1a7..0a0709d1 100644
--- a/src/core/platform.h
+++ b/src/core/platform.h
@@ -163,6 +163,15 @@ typedef struct nni_atomic_flag nni_atomic_flag;
extern bool nni_atomic_flag_test_and_set(nni_atomic_flag *);
extern void nni_atomic_flag_reset(nni_atomic_flag *);
+typedef struct nni_atomic_u64 nni_atomic_u64;
+
+extern void nni_atomic_init64(nni_atomic_u64 *);
+extern void nni_atomic_inc64(nni_atomic_u64 *, uint64_t);
+extern void nni_atomic_dec64(nni_atomic_u64 *, uint64_t);
+extern uint64_t nni_atomic_get64(nni_atomic_u64 *);
+extern void nni_atomic_set64(nni_atomic_u64 *, uint64_t);
+extern uint64_t nni_atomic_swap64(nni_atomic_u64 *, uint64_t);
+
//
// Clock Support
//
diff --git a/src/platform/posix/posix_atomic.c b/src/platform/posix/posix_atomic.c
index a8d2579d..7f735ec0 100644
--- a/src/platform/posix/posix_atomic.c
+++ b/src/platform/posix/posix_atomic.c
@@ -28,6 +28,43 @@ nni_atomic_flag_reset(nni_atomic_flag *f)
{
atomic_flag_clear(&f->f);
}
+
+void
+nni_atomic_inc64(nni_atomic_u64 *v, uint64_t bump)
+{
+ (void) atomic_fetch_add_explicit(&v->v, bump, memory_order_relaxed);
+}
+
+void
+nni_atomic_dec64(nni_atomic_u64 *v, uint64_t bump)
+{
+ (void) atomic_fetch_sub_explicit(&v->v, bump, memory_order_relaxed);
+}
+
+uint64_t
+nni_atomic_get64(nni_atomic_u64 *v)
+{
+ return (atomic_load(&v->v));
+}
+
+void
+nni_atomic_set64(nni_atomic_u64 *v, uint64_t u)
+{
+ atomic_store(&v->v, u);
+}
+
+uint64_t
+nni_atomic_swap64(nni_atomic_u64 *v, uint64_t u)
+{
+ return (atomic_exchange(&v->v, u));
+}
+
+void
+nni_atomic_init64(nni_atomic_u64 *v)
+{
+ atomic_init(&v->v, 0);
+}
+
#else
#include <pthread.h>
@@ -52,6 +89,58 @@ nni_atomic_flag_reset(nni_atomic_flag *f)
f->f = false;
pthread_mutex_unlock(&plat_atomic_lock);
}
+
+void
+nni_atomic_inc64(nni_atomic_u64 *v, uint64_t bump)
+{
+ pthread_mutex_lock(&plat_atomic_lock);
+ v += bump;
+ pthread_mutex_unlock(&plat_atomic_lock);
+}
+
+void
+nni_atomic_dec64(nni_atomic_u64 *v, uint64_t bump)
+{
+ pthread_mutex_lock(&plat_atomic_lock);
+ v -= bump;
+ pthread_mutex_unlock(&plat_atomic_lock);
+}
+
+uint64_t
+nni_atomic_get64(nni_atomic_u64 *v)
+{
+ uint64_t rv;
+ pthread_mutex_lock(&plat_atomic_lock);
+ rv = v->v;
+ pthread_mutex_unlock(&plat_atomic_lock);
+ return (rv);
+}
+
+void
+nni_atomic_set64(nni_atomic_u64 *v, uint64_t u)
+{
+ pthread_mutex_lock(&plat_atomic_lock);
+ v->v = u;
+ pthread_mutex_unlock(&plat_atomic_lock);
+}
+
+uint64_t
+nni_atomic_swap64(nni_atomic_u64 *v, uint64_t u)
+{
+ uint64_t rv;
+ pthread_mutex_lock(&plat_atomic_lock);
+ rv = v->v;
+ v->v = u;
+ pthread_mutex_unlock(&plat_atomic_lock);
+ return (rv);
+}
+
+void
+nni_atomic_init64(nni_atomic_u64 *v)
+{
+ v->v = 0;
+}
+
#endif
#endif // NNG_PLATFORM_POSIX
diff --git a/src/platform/posix/posix_impl.h b/src/platform/posix/posix_impl.h
index 70a3615f..9f3b775b 100644
--- a/src/platform/posix/posix_impl.h
+++ b/src/platform/posix/posix_impl.h
@@ -82,10 +82,20 @@ struct nni_plat_flock {
struct nni_atomic_flag {
atomic_flag f;
};
+
+struct nni_atomic_u64 {
+ _Atomic unsigned long long v;
+};
+
#else // NNG_HAVE_C11_ATOMIC
struct nni_atomic_flag {
bool f;
};
+
+struct nni_atomic_flag {
+ uint64_t v;
+};
+
#endif
#endif
diff --git a/src/platform/windows/win_impl.h b/src/platform/windows/win_impl.h
index 2cdff1c0..462e1707 100644
--- a/src/platform/windows/win_impl.h
+++ b/src/platform/windows/win_impl.h
@@ -52,6 +52,10 @@ struct nni_atomic_flag {
unsigned f;
};
+struct nni_atomic_u64 {
+ LONGLONG v;
+};
+
// nni_win_io 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.
diff --git a/src/platform/windows/win_thread.c b/src/platform/windows/win_thread.c
index b9743c5e..f80c8e3f 100644
--- a/src/platform/windows/win_thread.c
+++ b/src/platform/windows/win_thread.c
@@ -121,6 +121,44 @@ nni_atomic_flag_reset(nni_atomic_flag *f)
InterlockedExchange(&f->f, 0);
}
+void
+nni_atomic_inc64(nni_atomic_u64 *v, uint64_t bump)
+{
+ InterlockedAddNoFence64(&v->v, (LONGLONG) bump);
+}
+
+void
+nni_atomic_dec64(nni_atomic_u64 *v, uint64_t bump)
+{
+ // Windows lacks a sub, so we add the negative.
+ InterlockedAddNoFence64(&v->v, (0ll - (LONGLONG) bump));
+}
+
+uint64_t
+nni_atomic_get64(nni_atomic_u64 *v)
+{
+
+ return ((uint64_t)(InterlockedExchangeAdd64(&v->v, 0)));
+}
+
+void
+nni_atomic_set64(nni_atomic_u64 *v, uint64_t u)
+{
+ return (InterlockedExchange64(&v->v, (LONGLONG) u));
+}
+
+uint64_t
+nni_atomic_swap64(nni_atomic_u64 *v, uint64_t u)
+{
+ return ((uint64_t)(InterlockedExchange64(&v->v, (LONGLONG) u)));
+}
+
+void
+nni_atomic_init64(nni_atomic_u64 *v)
+{
+ InterlockedExchange64(&v->v, 0);
+}
+
static unsigned int __stdcall nni_plat_thr_main(void *arg)
{
nni_plat_thr *thr = arg;