diff --git a/src/elements/core.c b/src/elements/core.c index fa5483dc..9142cf32 100644 --- a/src/elements/core.c +++ b/src/elements/core.c @@ -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) diff --git a/src/elements/internals.h b/src/elements/internals.h index 6aba3740..7eb3f2eb 100644 --- a/src/elements/internals.h +++ b/src/elements/internals.h @@ -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; diff --git a/src/elements/lck-posix.c b/src/elements/lck-posix.c index 147778da..058698b8 100644 --- a/src/elements/lck-posix.c +++ b/src/elements/lck-posix.c @@ -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); +} diff --git a/src/elements/osal.h b/src/elements/osal.h index 9a42f92c..04af577d 100644 --- a/src/elements/osal.h +++ b/src/elements/osal.h @@ -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 #include #include @@ -196,6 +196,7 @@ static inline void *mdbx_realloc(void *ptr, size_t bytes) { #else /*----------------------------------------------------------------------*/ #include +#include #include #include #include @@ -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 diff --git a/test/main.cc b/test/main.cc index fe5243ec..35ab671f 100644 --- a/test/main.cc +++ b/test/main.cc @@ -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);