mdbx: add mdbx_osal_monotime_to_16dot16().

Change-Id: Ia65057def67cebf67252a77665efde4223b14d10
This commit is contained in:
Leonid Yuriev 2019-10-01 13:53:52 +03:00
parent 22f6e53520
commit 5693fad51d
3 changed files with 45 additions and 5 deletions

View File

@ -505,6 +505,20 @@ __cold void mdbx_rthc_global_init(void) {
mdbx_trace("pid %d, &mdbx_rthc_key = %p, value 0x%x", mdbx_getpid(),
&rthc_key, (unsigned)rthc_key);
#endif
/* checking time conversion, this also avoids racing on 32-bit architectures
* during writing calculated 64-bit ratio(s) into memory. */
uint32_t proba = UINT32_MAX;
while (true) {
unsigned time_conversion_checkup =
mdbx_osal_monotime_to_16dot16(mdbx_osal_16dot16_to_monotime(proba));
unsigned one_more = (proba < UINT32_MAX) ? proba + 1 : proba;
unsigned one_less = (proba > 0) ? proba - 1 : proba;
mdbx_ensure(nullptr, time_conversion_checkup >= one_less &&
time_conversion_checkup <= one_more);
if (proba == 0)
break;
proba >>= 1;
}
}
/* dtor called for thread, i.e. for all mdbx's environment objects */

View File

@ -1344,26 +1344,51 @@ static __cold clockid_t choice_monoclock() {
}
#endif
/*----------------------------------------------------------------------------*/
#if defined(_WIN32) || defined(_WIN64)
static LARGE_INTEGER performance_frequency;
#elif defined(__APPLE__) || defined(__MACH__)
static uint64_t ratio_16dot16_to_monotine;
#endif
MDBX_INTERNAL_FUNC uint64_t
mdbx_osal_16dot16_to_monotime(uint32_t seconds_16dot16) {
#if defined(_WIN32) || defined(_WIN64)
static LARGE_INTEGER performance_frequency;
if (performance_frequency.QuadPart == 0)
if (unlikely(performance_frequency.QuadPart == 0))
QueryPerformanceFrequency(&performance_frequency);
const uint64_t ratio = performance_frequency.QuadPart;
#elif defined(__APPLE__) || defined(__MACH__)
static uint64_t ratio;
if (!ratio) {
if (unlikely(ratio_16dot16_to_monotine == 0)) {
mach_timebase_info_data_t ti;
mach_timebase_info(&ti);
ratio = UINT64_C(1000000000) * ti.denom / ti.numer;
ratio_16dot16_to_monotine = UINT64_C(1000000000) * ti.denom / ti.numer;
}
const uint64_t ratio = ratio_16dot16_to_monotine;
#else
const uint64_t ratio = UINT64_C(1000000000);
#endif
return (ratio * seconds_16dot16 + 32768) >> 16;
}
MDBX_INTERNAL_FUNC uint32_t mdbx_osal_monotime_to_16dot16(uint64_t monotime) {
static uint64_t limit;
if (unlikely(monotime > limit)) {
if (limit != 0)
return UINT32_MAX;
limit = mdbx_osal_16dot16_to_monotime(UINT32_MAX - 1);
if (monotime > limit)
return UINT32_MAX;
}
#if defined(_WIN32) || defined(_WIN64)
return (uint32_t)((monotime << 16) / performance_frequency.QuadPart);
#elif defined(__APPLE__) || defined(__MACH__)
return (uint32_t)((monotime << 16) / ratio_16dot16_to_monotine);
#else
return (uint32_t)(monotime * 128 / 1953125);
#endif
}
MDBX_INTERNAL_FUNC uint64_t mdbx_osal_monotime(void) {
#if defined(_WIN32) || defined(_WIN64)
LARGE_INTEGER counter;

View File

@ -646,6 +646,7 @@ MDBX_INTERNAL_FUNC void __maybe_unused mdbx_osal_jitter(bool tiny);
MDBX_INTERNAL_FUNC uint64_t mdbx_osal_monotime(void);
MDBX_INTERNAL_FUNC uint64_t
mdbx_osal_16dot16_to_monotime(uint32_t seconds_16dot16);
MDBX_INTERNAL_FUNC uint32_t mdbx_osal_monotime_to_16dot16(uint64_t monotime);
/*----------------------------------------------------------------------------*/
/* lck stuff */