From f6eec7195b3aa5317cfa98ac942679bb2b5debe6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9B=D0=B5=D0=BE=D0=BD=D0=B8=D0=B4=20=D0=AE=D1=80=D1=8C?= =?UTF-8?q?=D0=B5=D0=B2=20=28Leonid=20Yuriev=29?= Date: Fri, 7 Oct 2022 14:53:35 +0300 Subject: [PATCH] =?UTF-8?q?mdbx:=20=D0=B7=D0=B0=D1=89=D0=B8=D1=82=D0=B0=20?= =?UTF-8?q?=D0=BE=D1=82=20=D0=BD=D1=83=D0=BB=D1=8F=20=D1=82=D0=BE=D0=BB?= =?UTF-8?q?=D1=8C=D0=BA=D0=BE=20=D0=BE=D0=B1=D1=89=D0=B5=D0=B9=20=D0=B7?= =?UTF-8?q?=D0=B0=D0=B4=D0=B5=D1=80=D0=B6=D0=BA=D0=B8=20=D0=B2=20=D0=BC?= =?UTF-8?q?=D0=B5=D1=82=D1=80=D0=B8=D0=BA=D0=B0=D1=85=20=D1=82=D1=80=D0=B0?= =?UTF-8?q?=D0=BD=D0=B7=D0=B0=D0=BA=D1=86=D0=B8=D0=B8.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Ранее, при конвертации очень коротких интервалов в формат фиксированной точки 16-точка-16, всегда выполнялось замещение нуля единицей. Т.е. если интервал был не нулевым, но меньше 15.259 микросекунд (1/65536 секунды), то вместо 0 возвращалось 1. Это приводило к тому, что сумма длительности отдельных стадий нередко была больше чем общее время фиксации транзакции. Проблема усугублялась, если получаемые значения аккумулировались по серии транзакций. Теперь такая защита от нуля выполняется только для общего времени, но не для отдельных стадий. Было: latency(ms): preparation=72.69 gc=72.69 write=73.04 sync=141.40 ending=72.69 whole=142.14 Аккумулированная сумма длительности этапов ВТРОЕ(!) больше общей длительности. Стало: latency(ms): preparation=0.00 gc=0.02 write=0.79 sync=67.98 ending=0.00 whole=140.81 Аккумулированная сумма длительности этапов меньше общей длительности, так как для каждой транзакции общая длительность возвращается не менее 15.259 микросекунд. --- src/core.c | 11 ++++++----- src/osal.c | 4 +--- src/osal.h | 5 +++++ 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/src/core.c b/src/core.c index 09ecd9b5..a8371188 100644 --- a/src/core.c +++ b/src/core.c @@ -10714,7 +10714,7 @@ provide_latency: latency->sync = (ts_4 && ts_5) ? osal_monotime_to_16dot16(ts_5 - ts_4) : 0; const uint64_t ts_6 = osal_monotime(); latency->ending = ts_5 ? osal_monotime_to_16dot16(ts_6 - ts_5) : 0; - latency->whole = osal_monotime_to_16dot16(ts_6 - ts_0); + latency->whole = osal_monotime_to_16dot16_noUnderflow(ts_6 - ts_0); } return rc; @@ -20775,14 +20775,15 @@ __cold static int fetch_envinfo_ex(const MDBX_env *env, const MDBX_txn *txn, const uint64_t monotime_now = osal_monotime(); uint64_t ts = atomic_load64(&lck->mti_sync_timestamp, mo_Relaxed); arg->mi_since_sync_seconds16dot16 = - ts ? osal_monotime_to_16dot16(monotime_now - ts) : 0; + ts ? osal_monotime_to_16dot16_noUnderflow(monotime_now - ts) : 0; ts = atomic_load64(&lck->mti_reader_check_timestamp, mo_Relaxed); arg->mi_since_reader_check_seconds16dot16 = - ts ? osal_monotime_to_16dot16(monotime_now - ts) : 0; + ts ? osal_monotime_to_16dot16_noUnderflow(monotime_now - ts) : 0; arg->mi_autosync_threshold = pgno2bytes( env, atomic_load32(&lck->mti_autosync_threshold, mo_Relaxed)); - arg->mi_autosync_period_seconds16dot16 = osal_monotime_to_16dot16( - atomic_load64(&lck->mti_autosync_period, mo_Relaxed)); + arg->mi_autosync_period_seconds16dot16 = + osal_monotime_to_16dot16_noUnderflow( + atomic_load64(&lck->mti_autosync_period, mo_Relaxed)); arg->mi_bootid.current.x = bootid.x; arg->mi_bootid.current.y = bootid.y; arg->mi_mode = env->me_lck_mmap.lck ? lck->mti_envmode.weak : env->me_flags; diff --git a/src/osal.c b/src/osal.c index 6a2697fa..79760a12 100644 --- a/src/osal.c +++ b/src/osal.c @@ -2655,9 +2655,7 @@ MDBX_INTERNAL_FUNC uint32_t osal_monotime_to_16dot16(uint64_t monotime) { #else (uint32_t)(monotime * 128 / 1953125); #endif - if (likely(ret > 0)) - return ret; - return monotime > 0 /* fix underflow */; + return ret; } MDBX_INTERNAL_FUNC uint64_t osal_monotime(void) { diff --git a/src/osal.h b/src/osal.h index 7d4b37b3..20842eff 100644 --- a/src/osal.h +++ b/src/osal.h @@ -585,6 +585,11 @@ MDBX_INTERNAL_FUNC uint64_t osal_monotime(void); MDBX_INTERNAL_FUNC uint64_t osal_16dot16_to_monotime(uint32_t seconds_16dot16); MDBX_INTERNAL_FUNC uint32_t osal_monotime_to_16dot16(uint64_t monotime); +static inline uint32_t osal_monotime_to_16dot16_noUnderflow(uint64_t monotime) { + uint32_t seconds_16dot16 = osal_monotime_to_16dot16(monotime); + return seconds_16dot16 ? seconds_16dot16 : /* fix underflow */ (monotime > 0); +} + MDBX_INTERNAL_FUNC bin128_t osal_bootid(void); /*----------------------------------------------------------------------------*/ /* lck stuff */