aboutsummaryrefslogtreecommitdiff
path: root/src/platform
diff options
context:
space:
mode:
authorGarrett D'Amore <garrett@damore.org>2021-07-11 13:03:54 -0700
committerGarrett D'Amore <garrett@damore.org>2021-07-11 13:04:28 -0700
commitca41e1c52a2264a63dcf6604a49e29b1d4a221c6 (patch)
tree4972c47d609594c596c2383b8ad2aaa2615a6962 /src/platform
parent9fcf039b573d153ba9bbc2beb5f11259ddacdcff (diff)
downloadnng-ca41e1c52a2264a63dcf6604a49e29b1d4a221c6.tar.gz
nng-ca41e1c52a2264a63dcf6604a49e29b1d4a221c6.tar.bz2
nng-ca41e1c52a2264a63dcf6604a49e29b1d4a221c6.zip
fixes #1409 reader/writer lock desired
This provides the initial implementation, and converts the transport lookup routines to use it. This is probably of limited performance benefit, but rwlock's may be useful in further future work.
Diffstat (limited to 'src/platform')
-rw-r--r--src/platform/posix/posix_impl.h6
-rw-r--r--src/platform/posix/posix_thread.c56
-rw-r--r--src/platform/windows/win_impl.h5
-rw-r--r--src/platform/windows/win_thread.c74
4 files changed, 115 insertions, 26 deletions
diff --git a/src/platform/posix/posix_impl.h b/src/platform/posix/posix_impl.h
index 978afc01..851c80dc 100644
--- a/src/platform/posix/posix_impl.h
+++ b/src/platform/posix/posix_impl.h
@@ -1,5 +1,5 @@
//
-// Copyright 2020 Staysail Systems, Inc. <info@staysail.tech>
+// Copyright 2021 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
@@ -58,6 +58,10 @@ struct nni_plat_mtx {
pthread_mutex_t mtx;
};
+struct nni_rwlock {
+ pthread_rwlock_t rwl;
+};
+
struct nni_plat_cv {
pthread_cond_t cv;
nni_plat_mtx * mtx;
diff --git a/src/platform/posix/posix_thread.c b/src/platform/posix/posix_thread.c
index ed4ec031..c47bcec6 100644
--- a/src/platform/posix/posix_thread.c
+++ b/src/platform/posix/posix_thread.c
@@ -1,5 +1,5 @@
//
-// Copyright 2020 Staysail Systems, Inc. <info@staysail.tech>
+// Copyright 2021 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
@@ -81,7 +81,6 @@ static void
nni_pthread_mutex_lock(pthread_mutex_t *m)
{
int rv;
-
if ((rv = pthread_mutex_lock(m)) != 0) {
nni_panic("pthread_mutex_lock: %s", strerror(rv));
}
@@ -91,7 +90,6 @@ static void
nni_pthread_mutex_unlock(pthread_mutex_t *m)
{
int rv;
-
if ((rv = pthread_mutex_unlock(m)) != 0) {
nni_panic("pthread_mutex_unlock: %s", strerror(rv));
}
@@ -101,7 +99,6 @@ static void
nni_pthread_cond_broadcast(pthread_cond_t *c)
{
int rv;
-
if ((rv = pthread_cond_broadcast(c)) != 0) {
nni_panic("pthread_cond_broadcast: %s", strerror(rv));
}
@@ -156,6 +153,53 @@ nni_plat_mtx_unlock(nni_plat_mtx *mtx)
}
void
+nni_rwlock_init(nni_rwlock *rwl)
+{
+ while (pthread_rwlock_init(&rwl->rwl, NULL) != 0) {
+ // We must have memory exhaustion -- ENOMEM, or
+ // in some cases EAGAIN. Wait a bit before we try to
+ // give things a chance to settle down.
+ nni_msleep(10);
+ }
+}
+
+void
+nni_rwlock_fini(nni_rwlock *rwl)
+{
+ int rv;
+ if ((rv = pthread_rwlock_destroy(&rwl->rwl)) != 0) {
+ nni_panic("pthread_rwlock_destroy: %s", strerror(rv));
+ }
+}
+
+void
+nni_rwlock_rdlock(nni_rwlock *rwl)
+{
+ int rv;
+ if ((rv = pthread_rwlock_rdlock(&rwl->rwl)) != 0) {
+ nni_panic("pthread_rwlock_rdlock: %s", strerror(rv));
+ }
+}
+
+void
+nni_rwlock_wrlock(nni_rwlock *rwl)
+{
+ int rv;
+ if ((rv = pthread_rwlock_wrlock(&rwl->rwl)) != 0) {
+ nni_panic("pthread_rwlock_wrlock: %s", strerror(rv));
+ }
+}
+
+void
+nni_rwlock_unlock(nni_rwlock *rwl)
+{
+ int rv;
+ if ((rv = pthread_rwlock_unlock(&rwl->rwl)) != 0) {
+ nni_panic("pthread_rwlock_unlock: %s", strerror(rv));
+ }
+}
+
+void
nni_plat_cv_init(nni_plat_cv *cv, nni_plat_mtx *mtx)
{
// See the comments in nni_plat_mtx_init. Almost everywhere this
@@ -264,7 +308,7 @@ nni_plat_thr_set_name(nni_plat_thr *thr, const char *name)
#if defined(__APPLE__)
// Darwin is weird, it can only set the name of pthread_self.
if ((thr == NULL) || (pthread_self() == thr->tid)) {
- pthread_setname_np(name);
+ pthread_setname_np(name);
}
#elif defined(__NetBSD__)
if (thr == NULL) {
@@ -283,7 +327,7 @@ nni_plat_thr_set_name(nni_plat_thr *thr, const char *name)
if (thr == NULL) {
pthread_set_name_np(pthread_self(), name);
} else {
- pthread_set_name_np(thr->tid, name);
+ pthread_set_name_np(thr->tid, name);
}
#endif
}
diff --git a/src/platform/windows/win_impl.h b/src/platform/windows/win_impl.h
index 17260676..de4f8e5b 100644
--- a/src/platform/windows/win_impl.h
+++ b/src/platform/windows/win_impl.h
@@ -41,6 +41,11 @@ struct nni_plat_mtx {
int init;
};
+struct nni_rwlock {
+ SRWLOCK rwl;
+ BOOLEAN exclusive;
+};
+
struct nni_plat_cv {
CONDITION_VARIABLE cv;
PSRWLOCK srl;
diff --git a/src/platform/windows/win_thread.c b/src/platform/windows/win_thread.c
index 7cc87eb3..c069d3c9 100644
--- a/src/platform/windows/win_thread.c
+++ b/src/platform/windows/win_thread.c
@@ -77,6 +77,42 @@ nni_plat_mtx_unlock(nni_plat_mtx *mtx)
}
void
+nni_rwlock_init(nni_rwlock *rwl)
+{
+ InitializeSRWLock(&rwl->rwl);
+}
+
+void
+nni_rwlock_fini(nni_rwlock *rwl)
+{
+ rwl->exclusive = FALSE;
+}
+
+void
+nni_rwlock_rdlock(nni_rwlock *rwl)
+{
+ AcquireSRWLockShared(&rwl->rwl);
+}
+
+void
+nni_rwlock_wrlock(nni_rwlock *rwl)
+{
+ AcquireSRWLockExclusive(&rwl->rwl);
+ rwl->exclusive = TRUE;
+}
+
+void
+nni_rwlock_unlock(nni_rwlock *rwl)
+{
+ if (rwl->exclusive) {
+ rwl->exclusive = FALSE;
+ ReleaseSRWLockExclusive(&rwl->rwl);
+ } else {
+ ReleaseSRWLockShared(&rwl->rwl);
+ }
+}
+
+void
nni_plat_cv_init(nni_plat_cv *cv, nni_plat_mtx *mtx)
{
InitializeConditionVariable(&cv->cv);
@@ -112,7 +148,7 @@ nni_plat_cv_until(nni_plat_cv *cv, nni_time until)
if (now > until) {
msec = 0;
} else {
- msec = (DWORD)(until - now);
+ msec = (DWORD) (until - now);
}
ok = SleepConditionVariableSRW(&cv->cv, cv->srl, msec, 0);
@@ -178,7 +214,7 @@ uint64_t
nni_atomic_get64(nni_atomic_u64 *v)
{
- return ((uint64_t)(InterlockedExchangeAdd64(&v->v, 0)));
+ return ((uint64_t) (InterlockedExchangeAdd64(&v->v, 0)));
}
void
@@ -190,7 +226,7 @@ nni_atomic_set64(nni_atomic_u64 *v, uint64_t u)
uint64_t
nni_atomic_swap64(nni_atomic_u64 *v, uint64_t u)
{
- return ((uint64_t)(InterlockedExchange64(&v->v, (LONGLONG) u)));
+ return ((uint64_t) (InterlockedExchange64(&v->v, (LONGLONG) u)));
}
void
@@ -213,9 +249,9 @@ uint64_t
nni_atomic_dec64_nv(nni_atomic_u64 *v)
{
#ifdef _WIN64
- return ((uint64_t)(InterlockedDecrementRelease64(&v->v)));
+ return ((uint64_t) (InterlockedDecrementRelease64(&v->v)));
#else
- return ((uint64_t)(InterlockedDecrement64(&v->v)));
+ return ((uint64_t) (InterlockedDecrement64(&v->v)));
#endif
}
@@ -331,9 +367,9 @@ void
nni_plat_thr_set_name(nni_plat_thr *thr, const char *name)
{
if (set_thread_desc != NULL) {
- wchar_t *wcs;
- size_t len;
- HANDLE h;
+ wchar_t *wcs;
+ size_t len;
+ HANDLE h;
if (thr == NULL) {
h = GetCurrentThread();
@@ -341,7 +377,7 @@ nni_plat_thr_set_name(nni_plat_thr *thr, const char *name)
h = thr->handle;
}
- len = strlen(name) + 1;
+ len = strlen(name) + 1;
if ((wcs = nni_alloc(len * 2)) == NULL) {
return;
}
@@ -372,18 +408,18 @@ nni_plat_init(int (*helper)(void))
return (0); // fast path
}
-
- AcquireSRWLockExclusive(&lock);
+ AcquireSRWLockExclusive(&lock);
if (!plat_inited) {
- // Let's look up the function to set thread descriptions.
- hKernel32 = LoadLibrary(TEXT("kernel32.dll"));
- if (hKernel32 != NULL) {
- set_thread_desc = (pfnSetThreadDescription)
- GetProcAddress(hKernel32, "SetThreadDescription");
- }
-
- if (((rv = nni_win_io_sysinit()) != 0) ||
+ // Let's look up the function to set thread descriptions.
+ hKernel32 = LoadLibrary(TEXT("kernel32.dll"));
+ if (hKernel32 != NULL) {
+ set_thread_desc =
+ (pfnSetThreadDescription) GetProcAddress(
+ hKernel32, "SetThreadDescription");
+ }
+
+ if (((rv = nni_win_io_sysinit()) != 0) ||
((rv = nni_win_ipc_sysinit()) != 0) ||
((rv = nni_win_tcp_sysinit()) != 0) ||
((rv = nni_win_udp_sysinit()) != 0) ||