diff options
| author | Garrett D'Amore <garrett@damore.org> | 2017-07-07 18:41:56 -0700 |
|---|---|---|
| committer | Garrett D'Amore <garrett@damore.org> | 2017-07-07 18:41:56 -0700 |
| commit | 3cedf14c3586b0770cb9ee62c75f922ab2006153 (patch) | |
| tree | 2fd6422cd97f91330896a47ba5e68c20705f2c28 /src/platform/windows | |
| parent | 021d09af1375834fe9aaca916e60dcd2ad3be845 (diff) | |
| download | nng-3cedf14c3586b0770cb9ee62c75f922ab2006153.tar.gz nng-3cedf14c3586b0770cb9ee62c75f922ab2006153.tar.bz2 nng-3cedf14c3586b0770cb9ee62c75f922ab2006153.zip | |
SRWLocks FTW!
Modern Windows (Vista and later) have light weight Slim Read/Write locks
which only occupy 64 bits, and don't require any memory allocation to
create.
While here clean up a few more unreferenced variables found with the
Microsoft compilers.
Diffstat (limited to 'src/platform/windows')
| -rw-r--r-- | src/platform/windows/win_debug.c | 1 | ||||
| -rw-r--r-- | src/platform/windows/win_impl.h | 10 | ||||
| -rw-r--r-- | src/platform/windows/win_thread.c | 33 |
3 files changed, 17 insertions, 27 deletions
diff --git a/src/platform/windows/win_debug.c b/src/platform/windows/win_debug.c index a4edef0d..43db0505 100644 --- a/src/platform/windows/win_debug.c +++ b/src/platform/windows/win_debug.c @@ -77,6 +77,7 @@ nni_plat_errno(int errnum) return (NNG_ESYSERR + errnum); } + // Windows has infinite numbers of error codes it seems. We only bother // with the ones that are relevant to us (we think). Note that there is // no overlap between errnos and GetLastError values. diff --git a/src/platform/windows/win_impl.h b/src/platform/windows/win_impl.h index 85f73bf7..fd8f3f79 100644 --- a/src/platform/windows/win_impl.h +++ b/src/platform/windows/win_impl.h @@ -26,7 +26,7 @@ // These types are provided for here, to permit them to be directly inlined // elsewhere. -typedef struct nni_win_event nni_win_event; +typedef struct nni_win_event nni_win_event; // 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 @@ -60,14 +60,14 @@ struct nni_plat_thr { }; struct nni_plat_mtx { - CRITICAL_SECTION cs; - DWORD owner; - int init; + SRWLOCK srl; + DWORD owner; + int init; }; struct nni_plat_cv { CONDITION_VARIABLE cv; - CRITICAL_SECTION * cs; + PSRWLOCK srl; }; extern int nni_win_error(int); diff --git a/src/platform/windows/win_thread.c b/src/platform/windows/win_thread.c index be94d638..f3103079 100644 --- a/src/platform/windows/win_thread.c +++ b/src/platform/windows/win_thread.c @@ -34,7 +34,7 @@ nni_free(void *b, size_t z) int nni_plat_mtx_init(nni_plat_mtx *mtx) { - InitializeCriticalSection(&mtx->cs); + InitializeSRWLock(&mtx->srl); mtx->init = 1; return (0); } @@ -43,24 +43,21 @@ nni_plat_mtx_init(nni_plat_mtx *mtx) void nni_plat_mtx_fini(nni_plat_mtx *mtx) { - if (mtx->init) { - DeleteCriticalSection(&mtx->cs); - mtx->init = 0; - } + mtx->init = 0; } void nni_plat_mtx_lock(nni_plat_mtx *mtx) { - EnterCriticalSection(&mtx->cs); + AcquireSRWLockExclusive(&mtx->srl); } void nni_plat_mtx_unlock(nni_plat_mtx *mtx) { - LeaveCriticalSection(&mtx->cs); + ReleaseSRWLockExclusive(&mtx->srl); } @@ -68,7 +65,7 @@ int nni_plat_cv_init(nni_plat_cv *cv, nni_plat_mtx *mtx) { InitializeConditionVariable(&cv->cv); - cv->cs = &mtx->cs; + cv->srl = &mtx->srl; return (0); } @@ -83,7 +80,7 @@ nni_plat_cv_wake(nni_plat_cv *cv) void nni_plat_cv_wait(nni_plat_cv *cv) { - (void) SleepConditionVariableCS(&cv->cv, cv->cs, INFINITE); + (void) SleepConditionVariableSRW(&cv->cv, cv->srl, INFINITE, 0); } @@ -102,7 +99,7 @@ nni_plat_cv_until(nni_plat_cv *cv, nni_time until) msec = (DWORD) (((until - now) + 999)/1000); } - ok = SleepConditionVariableCS(&cv->cv, cv->cs, msec); + ok = SleepConditionVariableSRW(&cv->cv, cv->srl, msec, 0); return (ok ? 0 : NNG_ETIMEDOUT); } @@ -156,23 +153,16 @@ nni_plat_thr_fini(nni_plat_thr *thr) int nni_plat_init(int (*helper)(void)) { - LONG old; - static LONG initing = 0; static LONG inited = 0; int rv; + static SRWLOCK lock = SRWLOCK_INIT; if (inited) { return (0); // fast path } - // This logic gets us to initialize the platform just once. - // If two threads enter here together, only one will get to run, - // and the other will be put to sleep briefly so that the first - // can complete. This is a poor man's singleton initializer, since - // we can't statically initialize critical sections. - while ((old = InterlockedCompareExchange(&initing, 0, 1)) != 0) { - Sleep(1); - } + AcquireSRWLockExclusive(&lock); + if (!inited) { WSADATA data; WORD ver; @@ -185,7 +175,6 @@ nni_plat_init(int (*helper)(void)) rv = NNG_EINVAL; goto out; } - printf("STARTING...\n"); if ((rv = nni_win_iocp_sysinit()) != 0) { goto out; } @@ -197,7 +186,7 @@ nni_plat_init(int (*helper)(void)) } out: - InterlockedExchange(&initing, 0); + ReleaseSRWLockExclusive(&lock); return (rv); } |
