mdbx: use POSIX.1 IPC semaphores on systems without shared mutexes.

Change-Id: I5e398257e65c355d1028167f2719232fc55d093a
This commit is contained in:
Leonid Yuriev 2019-11-06 23:53:53 +03:00
parent 1f82b4ff21
commit 3e7944f732
5 changed files with 207 additions and 132 deletions

View File

@ -603,7 +603,7 @@ static __inline void atomic_yield(void) {
static __inline bool atomic_cas64(volatile uint64_t *p, uint64_t c,
uint64_t v) {
#if defined(ATOMIC_VAR_INIT) || defined(ATOMIC_LLONG_LOCK_FREE)
STATIC_ASSERT(sizeof(long long int) == 8);
STATIC_ASSERT(sizeof(long long) >= sizeof(uint64_t));
STATIC_ASSERT(atomic_is_lock_free(p));
return atomic_compare_exchange_strong((_Atomic uint64_t *)p, &c, v);
#elif defined(__GNUC__) || defined(__clang__)
@ -621,8 +621,8 @@ static __inline bool atomic_cas64(volatile uint64_t *p, uint64_t c,
static __inline bool atomic_cas32(volatile uint32_t *p, uint32_t c,
uint32_t v) {
#if defined(ATOMIC_VAR_INIT) || defined(ATOMIC_LONG_LOCK_FREE)
STATIC_ASSERT(sizeof(long int) >= 4);
#if defined(ATOMIC_VAR_INIT) || defined(ATOMIC_INT_LOCK_FREE)
STATIC_ASSERT(sizeof(int) >= sizeof(uint32_t));
STATIC_ASSERT(atomic_is_lock_free(p));
return atomic_compare_exchange_strong((_Atomic uint32_t *)p, &c, v);
#elif defined(__GNUC__) || defined(__clang__)
@ -638,8 +638,8 @@ static __inline bool atomic_cas32(volatile uint32_t *p, uint32_t c,
}
static __inline uint32_t atomic_add32(volatile uint32_t *p, uint32_t v) {
#if defined(ATOMIC_VAR_INIT) || defined(ATOMIC_LONG_LOCK_FREE)
STATIC_ASSERT(sizeof(long int) >= 4);
#if defined(ATOMIC_VAR_INIT) || defined(ATOMIC_INT_LOCK_FREE)
STATIC_ASSERT(sizeof(int) >= sizeof(uint32_t));
STATIC_ASSERT(atomic_is_lock_free(p));
return atomic_fetch_add((_Atomic uint32_t *)p, v);
#elif defined(__GNUC__) || defined(__clang__)
@ -4606,14 +4606,14 @@ static int mdbx_txn_renew0(MDBX_txn *txn, unsigned flags) {
#endif /* MDBX_TXN_CHECKPID */
STATIC_ASSERT(sizeof(MDBX_reader) == 32);
#ifdef MDBX_OSAL_LOCK
STATIC_ASSERT(offsetof(MDBX_lockinfo, mti_wmutex) % MDBX_CACHELINE_SIZE == 0);
STATIC_ASSERT(offsetof(MDBX_lockinfo, mti_rmutex) % MDBX_CACHELINE_SIZE == 0);
#else
#if MDBX_USE_MUTEXES < 0
STATIC_ASSERT(
offsetof(MDBX_lockinfo, mti_oldest_reader) % MDBX_CACHELINE_SIZE == 0);
STATIC_ASSERT(offsetof(MDBX_lockinfo, mti_numreaders) % MDBX_CACHELINE_SIZE ==
0);
#else
STATIC_ASSERT(offsetof(MDBX_lockinfo, mti_wlock) % MDBX_CACHELINE_SIZE == 0);
STATIC_ASSERT(offsetof(MDBX_lockinfo, mti_rlock) % MDBX_CACHELINE_SIZE == 0);
#endif
STATIC_ASSERT(offsetof(MDBX_lockinfo, mti_readers) % MDBX_CACHELINE_SIZE ==
0);
@ -7480,7 +7480,12 @@ int __cold mdbx_env_create(MDBX_env **penv) {
mdbx_fastmutex_destroy(&env->me_dbi_lock);
goto bailout;
}
rc = mdbx_fastmutex_init(&env->me_lckless_stub.wmutex);
#if MDBX_USE_MUTEXES == 0
rc = sem_init(&env->me_lckless_stub.wlock, false, 1) ? errno : MDBX_SUCCESS;
#elif MDBX_USE_MUTEXES > 0
rc = pthread_mutex_init(&env->me_lckless_stub.wlock, nullptr);
#endif
if (unlikely(rc != MDBX_SUCCESS)) {
mdbx_fastmutex_destroy(&env->me_remap_guard);
mdbx_fastmutex_destroy(&env->me_dbi_lock);
@ -8293,8 +8298,8 @@ static int __cold mdbx_setup_lck(MDBX_env *env, char *lck_pathname,
env->me_discarded_tail = &env->me_lckless_stub.discarded_tail;
env->me_meta_sync_txnid = &env->me_lckless_stub.meta_sync_txnid;
env->me_maxreaders = UINT_MAX;
#ifdef MDBX_OSAL_LOCK
env->me_wmutex = &env->me_lckless_stub.wmutex;
#if MDBX_USE_MUTEXES >= 0
env->me_wlock = &env->me_lckless_stub.wlock;
#endif
mdbx_debug("lck-setup:%s%s%s", " lck-less",
(env->me_flags & MDBX_RDONLY) ? " readonly" : "",
@ -8428,8 +8433,8 @@ static int __cold mdbx_setup_lck(MDBX_env *env, char *lck_pathname,
env->me_autosync_threshold = &env->me_lck->mti_autosync_threshold;
env->me_discarded_tail = &env->me_lck->mti_discarded_tail;
env->me_meta_sync_txnid = &env->me_lck->mti_meta_sync_txnid;
#ifdef MDBX_OSAL_LOCK
env->me_wmutex = &env->me_lck->mti_wmutex;
#if MDBX_USE_MUTEXES >= 0
env->me_wlock = &env->me_lck->mti_wlock;
#endif
return lck_seize_rc;
}
@ -8888,9 +8893,10 @@ int __cold mdbx_env_close_ex(MDBX_env *env, int dont_sync) {
mdbx_fastmutex_destroy(&env->me_remap_guard) == MDBX_SUCCESS);
#endif /* Windows */
#ifdef MDBX_OSAL_LOCK
mdbx_ensure(env, mdbx_fastmutex_destroy(&env->me_lckless_stub.wmutex) ==
MDBX_SUCCESS);
#if MDBX_USE_MUTEXES == 0
mdbx_ensure(env, sem_destroy(&env->me_lckless_stub.wlock) == 0);
#elif MDBX_USE_MUTEXES > 0
mdbx_ensure(env, pthread_mutex_destroy(&env->me_lckless_stub.wlock) == 0);
#endif
mdbx_ensure(env, env->me_lcklist_next == nullptr);
@ -16518,7 +16524,7 @@ __dll_export
"FreeBSD"
#elif defined(__DragonFly__)
"DragonFlyBSD"
#elif defined(__NetBSD__) || defined(__NETBSD__)
#elif defined(__NetBSD__)
"NetBSD"
#elif defined(__OpenBSD__)
"OpenBSD"
@ -16632,12 +16638,9 @@ __dll_export
" MDBX_BUILD_SHARED_LIBRARY=" STRINGIFY(MDBX_BUILD_SHARED_LIBRARY)
" WINVER=" STRINGIFY(WINVER)
#else /* Windows */
" MDBX_USE_ROBUST=" MDBX_USE_ROBUST_CONFIG
" MDBX_USE_MUTEXES=" MDBX_USE_MUTEXES_CONFIG
" MDBX_USE_OFDLOCKS=" MDBX_USE_OFDLOCKS_CONFIG
#endif /* !Windows */
#ifdef MDBX_OSAL_LOCK
" MDBX_OSAL_LOCK=" STRINGIFY(MDBX_OSAL_LOCK)
#endif
" MDBX_CACHELINE_SIZE=" STRINGIFY(MDBX_CACHELINE_SIZE)
" MDBX_CPU_WRITEBACK_IS_COHERENT=" STRINGIFY(MDBX_CPU_WRITEBACK_IS_COHERENT)
" MDBX_UNALIGNED_OK=" STRINGIFY(MDBX_UNALIGNED_OK)

View File

@ -203,24 +203,36 @@
#define MDBX_64BIT_CAS_CONFIG STRINGIFY(MDBX_64BIT_CAS)
#endif /* MDBX_64BIT_CAS */
#if defined(_WIN32) || defined(_WIN64)
#define MDBX_USE_MUTEXES -1 /* Windows don't support POSIX */
#else
#ifndef MDBX_USE_MUTEXES
#if defined(__linux__) || defined(__gnu_linux__) || defined(__FreeBSD__) || \
defined(__APPLE__) || \
(defined(_POSIX_THREAD_PROCESS_SHARED) && \
_POSIX_THREAD_PROCESS_SHARED > 0)
/* Some platforms define the EOWNERDEAD error code even though they
* don't support Robust Mutexes. Compile with -DMDBX_USE_ROBUST=0. */
#ifndef MDBX_USE_ROBUST
/* Howard Chu: Android currently lacks Robust Mutex support */
#if defined(EOWNERDEAD) && !defined(__ANDROID__) && !defined(__APPLE__) && \
(!defined(__GLIBC__) || \
__GLIBC_PREREQ( \
2, \
10) /* LY: glibc before 2.10 has a troubles with Robust Mutex too. */ \
|| _POSIX_C_SOURCE >= 200809L)
#define MDBX_USE_ROBUST 1
* don't support Robust Mutexes. If doubt compile with -MDBX_USE_MUTEXES=1. */
#if defined(EOWNERDEAD) && _POSIX_C_SOURCE >= 200809L && \
(!defined(__GLIBC__) || /* LY: glibc before 2.10 has a troubles with \
Robust mutexes. */ \
__GLIBC_PREREQ(2, 10)) && \
(defined(PTHREAD_MUTEX_ROBUST) || defined(PTHREAD_MUTEX_ROBUST_NP) || \
defined(PTHREAD_MUTEX_STALLED_NP) || defined(__GLIBC__) || \
(!defined(__ANDROID__) && !defined(__APPLE__)))
#define MDBX_USE_MUTEXES 2 /* use robust shared pthread mutexes */
#else
#define MDBX_USE_ROBUST 0
#define MDBX_USE_MUTEXES 1 /* use shared pthread mutexes */
#endif
#define MDBX_USE_ROBUST_CONFIG "AUTO=" STRINGIFY(MDBX_USE_ROBUST)
#else
#define MDBX_USE_ROBUST_CONFIG STRINGIFY(MDBX_USE_ROBUST)
#endif /* MDBX_USE_ROBUST */
#define MDBX_USE_MUTEXES 0 /* use unnamed shared semaphores */
#endif
#define MDBX_USE_MUTEXES_CONFIG "AUTO=" STRINGIFY(MDBX_USE_MUTEXES)
#else
#define MDBX_USE_MUTEXES_CONFIG STRINGIFY(MDBX_USE_MUTEXES)
#endif /* MDBX_USE_MUTEXES */
#endif /* !Windows */
#ifndef MDBX_USE_OFDLOCKS
#if defined(F_OFD_SETLK) && defined(F_OFD_SETLKW) && defined(F_OFD_GETLK) && \
@ -607,10 +619,16 @@ typedef struct MDBX_lockinfo {
volatile bin128_t mti_bootid;
alignas(MDBX_CACHELINE_SIZE) /* cacheline ---------------------------------*/
#ifdef MDBX_OSAL_LOCK
/* Mutex protecting write-txn. */
MDBX_OSAL_LOCK mti_wmutex;
#endif
/* Write transation lok. */
#if MDBX_USE_MUTEXES > 0
pthread_mutex_t mti_wlock;
#define MDBX_OSAL_LOCK_SIGN UINT32_C(0x8017)
#elif MDBX_USE_MUTEXES == 0
sem_t mti_wlock;
#define MDBX_OSAL_LOCK_SIGN UINT32_C(0xFC29)
#else
#define MDBX_OSAL_LOCK_SIGN UINT32_C(0xF10C)
#endif /* MDBX_USE_MUTEXES */
volatile txnid_t mti_oldest_reader;
@ -630,10 +648,12 @@ typedef struct MDBX_lockinfo {
alignas(MDBX_CACHELINE_SIZE) /* cacheline ---------------------------------*/
#ifdef MDBX_OSAL_LOCK
/* Mutex protecting readers registration access to this table. */
MDBX_OSAL_LOCK mti_rmutex;
#endif
/* Readeaders registration lock. */
#if MDBX_USE_MUTEXES > 0
pthread_mutex_t mti_rlock;
#elif MDBX_USE_MUTEXES == 0
sem_t mti_rlock;
#endif /* MDBX_USE_MUTEXES */
/* The number of slots that have been used in the reader table.
* This always records the maximum count, it is not decremented
@ -983,9 +1003,14 @@ struct MDBX_env {
void *me_pbuf; /* scratch area for DUPSORT put() */
MDBX_txn *me_txn; /* current write transaction */
MDBX_txn *me_txn0; /* prealloc'd write transaction */
#ifdef MDBX_OSAL_LOCK
MDBX_OSAL_LOCK *me_wmutex; /* write-txn mutex */
#endif
/* write-txn lock */
#if MDBX_USE_MUTEXES > 0
pthread_mutex_t *me_wlock;
#elif MDBX_USE_MUTEXES == 0
sem_t *me_wlock;
#endif /* MDBX_USE_MUTEXES */
MDBX_dbx *me_dbxs; /* array of static DB info */
uint16_t *me_dbflags; /* array of flags from MDBX_db.md_flags */
unsigned *me_dbiseqs; /* array of dbi sequence numbers */
@ -1010,9 +1035,11 @@ struct MDBX_env {
volatile uint32_t *me_meta_sync_txnid;
MDBX_oom_func *me_oom_func; /* Callback for kicking laggard readers */
struct {
#ifdef MDBX_OSAL_LOCK
MDBX_OSAL_LOCK wmutex;
#endif
#if MDBX_USE_MUTEXES > 0
pthread_mutex_t wlock;
#elif MDBX_USE_MUTEXES == 0
sem_t wlock;
#endif /* MDBX_USE_MUTEXES */
txnid_t oldest;
uint64_t sync_timestamp;
uint64_t autosync_period;

View File

@ -318,9 +318,15 @@ MDBX_INTERNAL_FUNC int __cold mdbx_lck_destroy(MDBX_env *env,
lck_op(env->me_fd, op_setlk,
(env->me_flags & MDBX_RDONLY) ? F_RDLCK : F_WRLCK, 0, OFF_T_MAX)) {
mdbx_verbose("%s: got exclusive, drown mutexes", __func__);
rc = pthread_mutex_destroy(&env->me_lck->mti_rmutex);
#if MDBX_USE_MUTEXES > 0
rc = pthread_mutex_destroy(&env->me_lck->mti_rlock);
if (rc == 0)
rc = pthread_mutex_destroy(&env->me_lck->mti_wmutex);
rc = pthread_mutex_destroy(&env->me_lck->mti_wlock);
#else
rc = sem_destroy(&env->me_lck->mti_rlock) ? errno : 0;
if (rc == 0)
rc = sem_destroy(&env->me_lck->mti_wlock) ? errno : 0;
#endif /* MDBX_USE_MUTEXES */
mdbx_assert(env, rc == 0);
if (rc == 0) {
memset(env->me_lck, 0x81, sizeof(MDBX_lockinfo));
@ -373,9 +379,6 @@ MDBX_INTERNAL_FUNC int __cold mdbx_lck_destroy(MDBX_env *env,
/*---------------------------------------------------------------------------*/
static int mdbx_mutex_failed(MDBX_env *env, pthread_mutex_t *mutex,
const int rc);
MDBX_INTERNAL_FUNC int __cold mdbx_lck_init(MDBX_env *env,
MDBX_env *inprocess_neighbor,
int global_uniqueness_flag) {
@ -384,6 +387,19 @@ MDBX_INTERNAL_FUNC int __cold mdbx_lck_init(MDBX_env *env,
if LCK already opened/used inside current process */
;
#if MDBX_USE_MUTEXES == 0
/* don't initialize semaphores twice */
if (global_uniqueness_flag == MDBX_RESULT_TRUE) {
if (sem_init(&env->me_lck->mti_rlock, true, 1))
return errno;
if (sem_init(&env->me_lck->mti_wlock, true, 1))
return errno;
}
return MDBX_SUCCESS;
#else
/* FIXME: Unfortunately, there is no other reliable way but to long testing
* on each platform. On the other hand, behavior like FreeBSD is incorrect
* and we can expect it to be rare. Moreover, even on FreeBSD without
@ -413,18 +429,24 @@ MDBX_INTERNAL_FUNC int __cold mdbx_lck_init(MDBX_env *env,
if (rc)
goto bailout;
#if MDBX_USE_ROBUST
#if defined(__GLIBC__) && !__GLIBC_PREREQ(2, 12) && \
!defined(pthread_mutex_consistent) && _POSIX_C_SOURCE < 200809L
#if MDBX_USE_MUTEXES > 1
#if defined(PTHREAD_MUTEX_ROBUST)
rc = pthread_mutexattr_setrobust(&ma, PTHREAD_MUTEX_ROBUST);
#elif defined(PTHREAD_MUTEX_ROBUST_NP)
rc = pthread_mutexattr_setrobust_np(&ma, PTHREAD_MUTEX_ROBUST_NP);
#elif /* defined(__GLIBC__) && !__GLIBC_PREREQ(2, 12) && \
!defined(pthread_mutex_consistent) && */ \
_POSIX_C_SOURCE < 200809L
rc = pthread_mutexattr_setrobust_np(&ma, PTHREAD_MUTEX_ROBUST_NP);
#else
rc = pthread_mutexattr_setrobust(&ma, PTHREAD_MUTEX_ROBUST);
#endif
if (rc)
goto bailout;
#endif /* MDBX_USE_ROBUST */
#endif /* MDBX_USE_MUTEXES > 1 (USE_ROBUST) */
#if _POSIX_C_SOURCE >= 199506L && !defined(MDBX_SAFE4QEMU)
#if defined(_POSIX_THREAD_PRIO_INHERIT) && _POSIX_THREAD_PRIO_INHERIT > 0 && \
!defined(MDBX_SAFE4QEMU)
rc = pthread_mutexattr_setprotocol(&ma, PTHREAD_PRIO_INHERIT);
if (rc == ENOTSUP)
rc = pthread_mutexattr_setprotocol(&ma, PTHREAD_PRIO_NONE);
@ -436,79 +458,26 @@ MDBX_INTERNAL_FUNC int __cold mdbx_lck_init(MDBX_env *env,
if (rc)
goto bailout;
rc = pthread_mutex_init(&env->me_lck->mti_rmutex, &ma);
rc = pthread_mutex_init(&env->me_lck->mti_rlock, &ma);
if (rc)
goto bailout;
rc = pthread_mutex_init(&env->me_lck->mti_wmutex, &ma);
rc = pthread_mutex_init(&env->me_lck->mti_wlock, &ma);
bailout:
pthread_mutexattr_destroy(&ma);
return rc;
#endif /* MDBX_USE_MUTEXES */
}
static int mdbx_robust_lock(MDBX_env *env, pthread_mutex_t *mutex) {
mdbx_jitter4testing(true);
int rc = pthread_mutex_lock(mutex);
if (unlikely(rc != 0))
rc = mdbx_mutex_failed(env, mutex, rc);
return rc;
}
static int mdbx_robust_trylock(MDBX_env *env, pthread_mutex_t *mutex) {
mdbx_jitter4testing(true);
int rc = pthread_mutex_trylock(mutex);
if (unlikely(rc != 0 && rc != EBUSY))
rc = mdbx_mutex_failed(env, mutex, rc);
return (rc != EBUSY) ? rc : MDBX_BUSY;
}
static int mdbx_robust_unlock(MDBX_env *env, pthread_mutex_t *mutex) {
int rc = pthread_mutex_unlock(mutex);
mdbx_jitter4testing(true);
if (unlikely(rc != 0))
env->me_flags |= MDBX_FATAL_ERROR;
return rc;
}
MDBX_INTERNAL_FUNC int mdbx_rdt_lock(MDBX_env *env) {
mdbx_trace("%s", ">>");
int rc = mdbx_robust_lock(env, &env->me_lck->mti_rmutex);
mdbx_trace("<< rc %d", rc);
return rc;
}
MDBX_INTERNAL_FUNC void mdbx_rdt_unlock(MDBX_env *env) {
mdbx_trace("%s", ">>");
int rc = mdbx_robust_unlock(env, &env->me_lck->mti_rmutex);
mdbx_trace("<< rc %d", rc);
if (unlikely(MDBX_IS_ERROR(rc)))
mdbx_panic("%s() failed: errcode %d\n", __func__, rc);
}
int mdbx_txn_lock(MDBX_env *env, bool dontwait) {
mdbx_trace("%s", ">>");
int rc = dontwait ? mdbx_robust_trylock(env, env->me_wmutex)
: mdbx_robust_lock(env, env->me_wmutex);
mdbx_trace("<< rc %d", rc);
return MDBX_IS_ERROR(rc) ? rc : MDBX_SUCCESS;
}
void mdbx_txn_unlock(MDBX_env *env) {
mdbx_trace("%s", ">>");
int rc = mdbx_robust_unlock(env, env->me_wmutex);
mdbx_trace("<< rc %d", rc);
if (unlikely(MDBX_IS_ERROR(rc)))
mdbx_panic("%s() failed: errcode %d\n", __func__, rc);
}
#if MDBX_USE_MUTEXES > 0
static int __cold mdbx_mutex_failed(MDBX_env *env, pthread_mutex_t *mutex,
const int err) {
int rc = err;
#if MDBX_USE_ROBUST
#if MDBX_USE_MUTEXES > 1
if (err == EOWNERDEAD) {
/* We own the mutex. Clean up after dead previous owner. */
int rlocked = (env->me_lck && mutex == &env->me_lck->mti_rmutex);
int rlocked = (env->me_lck && mutex == &env->me_lck->mti_rlock);
rc = MDBX_SUCCESS;
if (!rlocked) {
if (unlikely(env->me_txn)) {
@ -542,10 +511,93 @@ static int __cold mdbx_mutex_failed(MDBX_env *env, pthread_mutex_t *mutex,
}
#else
(void)mutex;
#endif /* MDBX_USE_ROBUST */
#endif /* MDBX_USE_MUTEXES > 1 (USE_ROBUST) */
mdbx_error("mutex (un)lock failed, %s", mdbx_strerror(err));
if (rc != EDEADLK)
env->me_flags |= MDBX_FATAL_ERROR;
return rc;
}
static int mdbx_robust_lock(MDBX_env *env, pthread_mutex_t *mutex) {
int rc = pthread_mutex_lock(mutex);
if (unlikely(rc != 0))
rc = mdbx_mutex_failed(env, mutex, rc);
return rc;
}
static int mdbx_robust_trylock(MDBX_env *env, pthread_mutex_t *mutex) {
int rc = pthread_mutex_trylock(mutex);
if (unlikely(rc != 0 && rc != EBUSY))
rc = mdbx_mutex_failed(env, mutex, rc);
return (rc != EBUSY) ? rc : MDBX_BUSY;
}
static int mdbx_robust_unlock(MDBX_env *env, pthread_mutex_t *mutex) {
int rc = pthread_mutex_unlock(mutex);
if (unlikely(rc != 0))
env->me_flags |= MDBX_FATAL_ERROR;
return rc;
}
#endif /* MDBX_USE_MUTEXES */
MDBX_INTERNAL_FUNC int mdbx_rdt_lock(MDBX_env *env) {
mdbx_trace("%s", ">>");
mdbx_jitter4testing(true);
#if MDBX_USE_MUTEXES > 0
int rc = mdbx_robust_lock(env, &env->me_lck->mti_rlock);
#else
int rc = sem_wait(&env->me_lck->mti_rlock) ? errno : MDBX_SUCCESS;
#endif /* MDBX_USE_MUTEXES */
mdbx_trace("<< rc %d", rc);
return rc;
}
MDBX_INTERNAL_FUNC void mdbx_rdt_unlock(MDBX_env *env) {
mdbx_trace("%s", ">>");
#if MDBX_USE_MUTEXES > 0
int rc = mdbx_robust_unlock(env, &env->me_lck->mti_rlock);
#else
int rc = sem_post(&env->me_lck->mti_rlock) ? errno : MDBX_SUCCESS;
#endif /* MDBX_USE_MUTEXES */
mdbx_trace("<< rc %d", rc);
if (unlikely(MDBX_IS_ERROR(rc)))
mdbx_panic("%s() failed: errcode %d\n", __func__, rc);
else
mdbx_jitter4testing(true);
}
int mdbx_txn_lock(MDBX_env *env, bool dontwait) {
mdbx_trace("%s", ">>");
mdbx_jitter4testing(true);
#if MDBX_USE_MUTEXES > 0
int rc = dontwait ? mdbx_robust_trylock(env, env->me_wlock)
: mdbx_robust_lock(env, env->me_wlock);
#else
int rc = MDBX_SUCCESS;
if (dontwait) {
if (sem_trywait(&env->me_lck->mti_wlock)) {
rc = errno;
if (rc == EAGAIN)
rc = MDBX_BUSY;
}
} else if (sem_wait(&env->me_lck->mti_wlock))
rc = errno;
#endif /* MDBX_USE_MUTEXES */
mdbx_trace("<< rc %d", rc);
return MDBX_IS_ERROR(rc) ? rc : MDBX_SUCCESS;
}
void mdbx_txn_unlock(MDBX_env *env) {
mdbx_trace("%s", ">>");
#if MDBX_USE_MUTEXES > 0
int rc = mdbx_robust_unlock(env, env->me_wlock);
#else
int rc = sem_post(&env->me_lck->mti_wlock) ? errno : MDBX_SUCCESS;
#endif /* MDBX_USE_MUTEXES */
mdbx_trace("<< rc %d", rc);
if (unlikely(MDBX_IS_ERROR(rc)))
mdbx_panic("%s() failed: errcode %d\n", __func__, rc);
else
mdbx_jitter4testing(true);
}

View File

@ -71,8 +71,8 @@
/* Systems includes */
#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || \
defined(__BSD__) || defined(__NETBSD__) || defined(__bsdi__) || \
defined(__DragonFly__) || defined(__APPLE__) || defined(__MACH__)
defined(__BSD__) || defined(__bsdi__) || defined(__DragonFly__) || \
defined(__APPLE__) || defined(__MACH__)
#include <sys/cdefs.h>
#include <sys/mount.h>
#include <sys/sysctl.h>
@ -196,6 +196,7 @@ static inline void *mdbx_realloc(void *ptr, size_t bytes) {
#else /*----------------------------------------------------------------------*/
#include <pthread.h>
#include <semaphore.h>
#include <signal.h>
#include <sys/file.h>
#include <sys/mman.h>
@ -702,14 +703,6 @@ MDBX_INTERNAL_FUNC bin128_t mdbx_osal_bootid(void);
/*----------------------------------------------------------------------------*/
/* lck stuff */
#if defined(_WIN32) || defined(_WIN64)
#undef MDBX_OSAL_LOCK
#define MDBX_OSAL_LOCK_SIGN UINT32_C(0xF10C)
#else
#define MDBX_OSAL_LOCK pthread_mutex_t
#define MDBX_OSAL_LOCK_SIGN UINT32_C(0x8017)
#endif /* MDBX_OSAL_LOCK */
/// \brief Initialization of synchronization primitives linked with MDBX_env
/// instance both in LCK-file and within the current process.
/// \param

View File

@ -602,8 +602,8 @@ int main(int argc, char *const argv[]) {
spent.ru_stime.tv_sec + spent.ru_stime.tv_usec * 1e-6);
#if defined(__linux__) || defined(__gnu_linux__) || defined(__FreeBSD__) || \
defined(__NetBSD__) || defined(__OpenBSD__) || defined(__BSD__) || \
defined(__NETBSD__) || defined(__bsdi__) || defined(__DragonFly__) || \
defined(__APPLE__) || defined(__MACH__)
defined(__bsdi__) || defined(__DragonFly__) || defined(__APPLE__) || \
defined(__MACH__)
log_notice("%6s: read %ld, write %ld", "IOPs", spent.ru_inblock,
spent.ru_oublock);
log_notice("%6s: %ld Kb", "RAM", spent.ru_maxrss);