summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--plugins/Dbx_mdbx/src/libmdbx/src/bits.h2
-rw-r--r--plugins/Dbx_mdbx/src/libmdbx/src/lck-windows.c70
-rw-r--r--plugins/Dbx_mdbx/src/libmdbx/src/mdbx.c6
-rw-r--r--plugins/Dbx_mdbx/src/libmdbx/src/osal.h12
4 files changed, 84 insertions, 6 deletions
diff --git a/plugins/Dbx_mdbx/src/libmdbx/src/bits.h b/plugins/Dbx_mdbx/src/libmdbx/src/bits.h
index 293de7f80c..6915202ae6 100644
--- a/plugins/Dbx_mdbx/src/libmdbx/src/bits.h
+++ b/plugins/Dbx_mdbx/src/libmdbx/src/bits.h
@@ -742,7 +742,7 @@ struct MDBX_env {
} me_dbgeo; /* */
#if defined(_WIN32) || defined(_WIN64)
- SRWLOCK me_remap_guard;
+ MDBX_shlock me_remap_guard;
#else
mdbx_fastmutex_t me_remap_guard;
#endif
diff --git a/plugins/Dbx_mdbx/src/libmdbx/src/lck-windows.c b/plugins/Dbx_mdbx/src/libmdbx/src/lck-windows.c
index c7ce8a17b3..0cd28d3bd4 100644
--- a/plugins/Dbx_mdbx/src/libmdbx/src/lck-windows.c
+++ b/plugins/Dbx_mdbx/src/libmdbx/src/lck-windows.c
@@ -152,7 +152,7 @@ void mdbx_txn_unlock(MDBX_env *env) {
#define LCK_UPPER LCK_UP_OFFSET, LCK_UP_LEN
int mdbx_rdt_lock(MDBX_env *env) {
- AcquireSRWLockShared(&env->me_remap_guard);
+ mdbx_shlock_acquireShared(&env->me_remap_guard);
if (env->me_lfd == INVALID_HANDLE_VALUE)
return MDBX_SUCCESS; /* readonly database in readonly filesystem */
@@ -168,7 +168,7 @@ void mdbx_rdt_unlock(MDBX_env *env) {
if (!funlock(env->me_lfd, LCK_UPPER))
mdbx_panic("%s failed: errcode %u", mdbx_func_, GetLastError());
}
- ReleaseSRWLockShared(&env->me_remap_guard);
+ mdbx_shlock_releaseShared(&env->me_remap_guard);
}
static int suspend_and_append(mdbx_handle_array_t **array,
@@ -564,3 +564,69 @@ int mdbx_rpid_check(MDBX_env *env, mdbx_pid_t pid) {
return rc;
}
}
+
+/*----------------------------------------------------------------------------*/
+/* shared lock
+ Copyright (C) 1995-2002 Brad Wilson
+*/
+
+void mdbx_shlock_init(MDBX_shlock *lck)
+{
+ lck->readerCount = lck->writerCount = 0;
+}
+
+void mdbx_shlock_acquireShared(MDBX_shlock *lck)
+{
+ while (1) {
+ // If there's a writer already, spin without unnecessarily
+ // interlocking the CPUs
+
+ if (lck->writerCount != 0) {
+ YieldProcessor();
+ continue;
+ }
+
+ // Add to the readers list
+
+ _InterlockedIncrement((long*)&lck->readerCount);
+
+ // Check for writers again (we may have been pre-empted). If
+ // there are no writers writing or waiting, then we're done.
+
+ if (lck->writerCount == 0)
+ break;
+
+ // Remove from the readers list, spin, try again
+
+ _InterlockedDecrement((long*)&lck->readerCount);
+ YieldProcessor();
+ }
+}
+
+void mdbx_shlock_releaseShared(MDBX_shlock *lck)
+{
+ _InterlockedDecrement((long*)&lck->readerCount);
+}
+
+void mdbx_shlock_acquireExclusive(MDBX_shlock *lck)
+{
+ // See if we can become the writer (expensive, because it inter-
+ // locks the CPUs, so writing should be an infrequent process)
+
+ while (_InterlockedExchange((long*)&lck->writerCount, 1) == 1) {
+ YieldProcessor();
+ }
+
+ // Now we're the writer, but there may be outstanding readers.
+ // Spin until there aren't any more; new readers will wait now
+ // that we're the writer.
+
+ while (lck->readerCount != 0) {
+ YieldProcessor();
+ }
+}
+
+void mdbx_shlock_releaseExclusive(MDBX_shlock *lck)
+{
+ lck->writerCount = 0;
+}
diff --git a/plugins/Dbx_mdbx/src/libmdbx/src/mdbx.c b/plugins/Dbx_mdbx/src/libmdbx/src/mdbx.c
index 4cb1645ba9..2eafad6155 100644
--- a/plugins/Dbx_mdbx/src/libmdbx/src/mdbx.c
+++ b/plugins/Dbx_mdbx/src/libmdbx/src/mdbx.c
@@ -1637,7 +1637,7 @@ static int mdbx_mapresize(MDBX_env *env, const pgno_t size_pgno,
/* Acquire guard in exclusive mode for:
* - to avoid collision between read and write txns around env->me_dbgeo;
* - to avoid attachment of new reading threads (see mdbx_rdt_lock); */
- AcquireSRWLockExclusive(&env->me_remap_guard);
+ mdbx_shlock_acquireExclusive(&env->me_remap_guard);
mdbx_handle_array_t *suspended = NULL;
mdbx_handle_array_t array_onstack;
int rc = MDBX_SUCCESS;
@@ -1712,7 +1712,7 @@ bailout:
#if defined(_WIN32) || defined(_WIN64)
int err = MDBX_SUCCESS;
- ReleaseSRWLockExclusive(&env->me_remap_guard);
+ mdbx_shlock_releaseExclusive(&env->me_remap_guard);
if (suspended) {
err = mdbx_resume_threads_after_remap(suspended);
if (suspended != &array_onstack)
@@ -4436,7 +4436,7 @@ int __cold mdbx_env_create(MDBX_env **penv) {
goto bailout;
#if defined(_WIN32) || defined(_WIN64)
- InitializeSRWLock(&env->me_remap_guard);
+ mdbx_shlock_init(&env->me_remap_guard);
#else
rc = mdbx_fastmutex_init(&env->me_remap_guard);
if (unlikely(rc != MDBX_SUCCESS)) {
diff --git a/plugins/Dbx_mdbx/src/libmdbx/src/osal.h b/plugins/Dbx_mdbx/src/libmdbx/src/osal.h
index e84d18cad2..eb6cd5ee10 100644
--- a/plugins/Dbx_mdbx/src/libmdbx/src/osal.h
+++ b/plugins/Dbx_mdbx/src/libmdbx/src/osal.h
@@ -522,6 +522,18 @@ void mdbx_txn_unlock(MDBX_env *env);
int mdbx_rpid_set(MDBX_env *env);
int mdbx_rpid_clear(MDBX_env *env);
+typedef struct MDBX_shlock
+{
+ __declspec(align(64)) long volatile readerCount;
+ __declspec(align(64)) long volatile writerCount;
+} MDBX_shlock;
+
+void mdbx_shlock_init(MDBX_shlock *lck);
+void mdbx_shlock_acquireShared(MDBX_shlock *lck);
+void mdbx_shlock_releaseShared(MDBX_shlock *lck);
+void mdbx_shlock_acquireExclusive(MDBX_shlock *lck);
+void mdbx_shlock_releaseExclusive(MDBX_shlock *lck);
+
/* Checks reader by pid.
*
* Returns: