mirror of
https://github.com/isar/libmdbx.git
synced 2024-10-29 23:19:20 +08:00
mdbx: переделка page_alloc_slowpath()
с добавлением профилирования GC.
This commit is contained in:
parent
acaa1d82d9
commit
f680c99116
81
mdbx.h
81
mdbx.h
@ -2561,9 +2561,6 @@ struct MDBX_envinfo {
|
|||||||
msync; /**< Number of explicit msync-to-disk operations (not a pages) */
|
msync; /**< Number of explicit msync-to-disk operations (not a pages) */
|
||||||
uint64_t
|
uint64_t
|
||||||
fsync; /**< Number of explicit fsync-to-disk operations (not a pages) */
|
fsync; /**< Number of explicit fsync-to-disk operations (not a pages) */
|
||||||
uint64_t
|
|
||||||
gcrtime_seconds16dot16; /**< Time spent loading and searching inside
|
|
||||||
GC (aka FreeDB) in 1/65536 of second */
|
|
||||||
} mi_pgop_stat;
|
} mi_pgop_stat;
|
||||||
};
|
};
|
||||||
#ifndef __cplusplus
|
#ifndef __cplusplus
|
||||||
@ -3713,8 +3710,8 @@ struct MDBX_commit_latency {
|
|||||||
/** \brief Duration of preparation (commit child transactions, update
|
/** \brief Duration of preparation (commit child transactions, update
|
||||||
* sub-databases records and cursors destroying). */
|
* sub-databases records and cursors destroying). */
|
||||||
uint32_t preparation;
|
uint32_t preparation;
|
||||||
/** \brief Duration of GC/freeDB handling & updation. */
|
/** \brief Duration of GC update by wall clock. */
|
||||||
uint32_t gc;
|
uint32_t gc_wallclock;
|
||||||
/** \brief Duration of internal audit if enabled. */
|
/** \brief Duration of internal audit if enabled. */
|
||||||
uint32_t audit;
|
uint32_t audit;
|
||||||
/** \brief Duration of writing dirty/modified data pages to a filesystem,
|
/** \brief Duration of writing dirty/modified data pages to a filesystem,
|
||||||
@ -3727,6 +3724,80 @@ struct MDBX_commit_latency {
|
|||||||
uint32_t ending;
|
uint32_t ending;
|
||||||
/** \brief The total duration of a commit. */
|
/** \brief The total duration of a commit. */
|
||||||
uint32_t whole;
|
uint32_t whole;
|
||||||
|
/** \brief User-mode CPU time spent on GC update. */
|
||||||
|
uint32_t gc_cputime;
|
||||||
|
|
||||||
|
/** \brief Информация для профилирования работы GC.
|
||||||
|
* \note Статистика является общей для всех процессов работающих с одним
|
||||||
|
* файлом БД и хранится в LCK-файле. Данные аккумулируются при фиксации всех
|
||||||
|
* транзакций, но только в сборках libmdbx c установленной опцией
|
||||||
|
* \ref MDBX_ENABLE_PROFGC. Собранная статистика возвращаются любому процессу
|
||||||
|
* при использовании \ref mdbx_txn_commit_ex() и одновременно обнуляется
|
||||||
|
* при завершении транзакций верхнего уровня (не вложенных). */
|
||||||
|
struct {
|
||||||
|
/** \brief Количество итераций обновления GC,
|
||||||
|
* больше 1 если были повторы/перезапуски. */
|
||||||
|
uint32_t wloops;
|
||||||
|
/** \brief Количество итераций слияния записей GC. */
|
||||||
|
uint32_t coalescences;
|
||||||
|
/** \brief Количество уничтожений предыдущих надежных/устойчивых
|
||||||
|
* точек фиксации при работе в режиме \ref MDBX_UTTERLY_NOSYNC. */
|
||||||
|
uint32_t wipes;
|
||||||
|
/** \brief Количество принудительных фиксаций на диск
|
||||||
|
* во избежания приращения БД при работе вне режима
|
||||||
|
* \ref MDBX_UTTERLY_NOSYNC. */
|
||||||
|
uint32_t flushes;
|
||||||
|
/** \brief Количество обращений к механизму Handle-Slow-Readers
|
||||||
|
* во избежания приращения БД.
|
||||||
|
* \see MDBX_hsr_func */
|
||||||
|
uint32_t kicks;
|
||||||
|
|
||||||
|
/** \brief Счетчик выполнения по медленному пути (slow path execution count)
|
||||||
|
* GC ради данных пользователя. */
|
||||||
|
uint32_t work_counter;
|
||||||
|
/** \brief Время "по настенным часам" затраченное на чтение и поиск внутри
|
||||||
|
* GC ради данных пользователя. */
|
||||||
|
uint32_t work_rtime_monotonic;
|
||||||
|
/** \brief Монотонное время по "настенным часам" затраченное
|
||||||
|
* на подготовку страниц извлекаемых из GC для данных пользователя,
|
||||||
|
* включая подкачку с диска. */
|
||||||
|
uint32_t work_xtime_monotonic;
|
||||||
|
/** \brief Время ЦПУ в режиме пользователе затраченное на чтение и поиск
|
||||||
|
* внтури GC ради данных пользователя. */
|
||||||
|
uint32_t work_rtime_cpu;
|
||||||
|
/** \brief Количество итераций поиска внутри GC при выделении страниц
|
||||||
|
* ради данных пользователя. */
|
||||||
|
uint32_t work_rsteps;
|
||||||
|
/** \brief Количество запросов на выделение последовательностей страниц
|
||||||
|
* ради данных пользователя. */
|
||||||
|
uint32_t work_xpages;
|
||||||
|
/** \brief Количество страничных промахов (page faults) внутри GC
|
||||||
|
* при выделении и подготовки страниц для данных пользователя. */
|
||||||
|
uint32_t work_majflt;
|
||||||
|
|
||||||
|
/** \brief Счетчик выполнения по медленному пути (slow path execution count)
|
||||||
|
* GC для целей поддержки и обновления самой GC. */
|
||||||
|
uint32_t self_counter;
|
||||||
|
/** \brief Время "по настенным часам" затраченное на чтение и поиск внутри
|
||||||
|
* GC для целей поддержки и обновления самой GC. */
|
||||||
|
uint32_t self_rtime_monotonic;
|
||||||
|
/** \brief Монотонное время по "настенным часам" затраченное на подготовку
|
||||||
|
* страниц извлекаемых из GC для целей поддержки и обновления самой GC,
|
||||||
|
* включая подкачку с диска. */
|
||||||
|
uint32_t self_xtime_monotonic;
|
||||||
|
/** \brief Время ЦПУ в режиме пользователе затраченное на чтение и поиск
|
||||||
|
* внтури GC для целей поддержки и обновления самой GC. */
|
||||||
|
uint32_t self_rtime_cpu;
|
||||||
|
/** \brief Количество итераций поиска внутри GC при выделении страниц
|
||||||
|
* для целей поддержки и обновления самой GC. */
|
||||||
|
uint32_t self_rsteps;
|
||||||
|
/** \brief Количество запросов на выделение последовательностей страниц
|
||||||
|
* для самой GC. */
|
||||||
|
uint32_t self_xpages;
|
||||||
|
/** \brief Количество страничных промахов (page faults) внутри GC
|
||||||
|
* при выделении и подготовки страниц для самой GC. */
|
||||||
|
uint32_t self_majflt;
|
||||||
|
} gc_prof;
|
||||||
};
|
};
|
||||||
#ifndef __cplusplus
|
#ifndef __cplusplus
|
||||||
/** \ingroup c_statinfo */
|
/** \ingroup c_statinfo */
|
||||||
|
@ -5,8 +5,8 @@ N | MASK | ENV | TXN | DB | PUT | DBI | NOD
|
|||||||
2 |0000 0004|ALLOC_NEW |TXN_DIRTY |DUPSORT | |DBI_FRESH |F_DUPDATA|P_OVERFLOW| |
|
2 |0000 0004|ALLOC_NEW |TXN_DIRTY |DUPSORT | |DBI_FRESH |F_DUPDATA|P_OVERFLOW| |
|
||||||
3 |0000 0008|ALLOC_SLOT |TXN_SPILLS |INTEGERKEY| |DBI_CREAT | |P_META | |
|
3 |0000 0008|ALLOC_SLOT |TXN_SPILLS |INTEGERKEY| |DBI_CREAT | |P_META | |
|
||||||
4 |0000 0010|ALLOC_FAKE |TXN_HAS_CHILD |DUPFIXED |NOOVERWRITE|DBI_VALID | |P_BAD | |
|
4 |0000 0010|ALLOC_FAKE |TXN_HAS_CHILD |DUPFIXED |NOOVERWRITE|DBI_VALID | |P_BAD | |
|
||||||
5 |0000 0020| | |INTEGERDUP|NODUPDATA |DBI_USRVALID| |P_LEAF2 | |
|
5 |0000 0020| |TXN_UPDATE_GC |INTEGERDUP|NODUPDATA |DBI_USRVALID| |P_LEAF2 | |
|
||||||
6 |0000 0040| | |REVERSEDUP|CURRENT |DBI_DUPDATA | |P_SUBP | |
|
6 |0000 0040| |TXN_FROZEN_RE |REVERSEDUP|CURRENT |DBI_DUPDATA | |P_SUBP | |
|
||||||
7 |0000 0080| | | |ALLDUPS |DBI_AUDITED | | | |
|
7 |0000 0080| | | |ALLDUPS |DBI_AUDITED | | | |
|
||||||
8 |0000 0100| _MAY_MOVE | | | | | | | <= |
|
8 |0000 0100| _MAY_MOVE | | | | | | | <= |
|
||||||
9 |0000 0200| _MAY_UNMAP| | | | | | | <= |
|
9 |0000 0200| _MAY_UNMAP| | | | | | | <= |
|
||||||
|
1189
src/core.c
1189
src/core.c
File diff suppressed because it is too large
Load Diff
@ -578,10 +578,30 @@ typedef struct MDBX_page {
|
|||||||
|
|
||||||
#pragma pack(pop)
|
#pragma pack(pop)
|
||||||
|
|
||||||
#if MDBX_ENABLE_PGOP_STAT
|
typedef struct profgc_stat {
|
||||||
|
/* Монотонное время по "настенным часам"
|
||||||
|
* затраченное на чтение и поиск внутри GC */
|
||||||
|
uint64_t rtime_monotonic;
|
||||||
|
/* Монотонное время по "настенным часам" затраченное
|
||||||
|
* на подготовку страниц извлекаемых из GC, включая подкачку с диска. */
|
||||||
|
uint64_t xtime_monotonic;
|
||||||
|
/* Процессорное время в режим пользователя
|
||||||
|
* затраченное на чтение и поиск внутри GC */
|
||||||
|
uint64_t rtime_cpu;
|
||||||
|
/* Количество итераций чтения-поиска внутри GC при выделении страниц */
|
||||||
|
uint32_t rsteps;
|
||||||
|
/* Количество запросов на выделение последовательностей страниц,
|
||||||
|
* т.е. когда запрашивает выделение больше одной страницы */
|
||||||
|
uint32_t xpages;
|
||||||
|
/* Счетчик выполнения по медленному пути (slow path execution count) */
|
||||||
|
uint32_t spe_counter;
|
||||||
|
/* page faults (hard page faults) */
|
||||||
|
uint32_t majflt;
|
||||||
|
} profgc_stat_t;
|
||||||
|
|
||||||
/* Statistics of page operations overall of all (running, completed and aborted)
|
/* Statistics of page operations overall of all (running, completed and aborted)
|
||||||
* transactions */
|
* transactions */
|
||||||
typedef struct {
|
typedef struct pgop_stat {
|
||||||
MDBX_atomic_uint64_t newly; /* Quantity of a new pages added */
|
MDBX_atomic_uint64_t newly; /* Quantity of a new pages added */
|
||||||
MDBX_atomic_uint64_t cow; /* Quantity of pages copied for update */
|
MDBX_atomic_uint64_t cow; /* Quantity of pages copied for update */
|
||||||
MDBX_atomic_uint64_t clone; /* Quantity of parent's dirty pages clones
|
MDBX_atomic_uint64_t clone; /* Quantity of parent's dirty pages clones
|
||||||
@ -592,15 +612,32 @@ typedef struct {
|
|||||||
MDBX_atomic_uint64_t unspill; /* Quantity of unspilled/reloaded pages */
|
MDBX_atomic_uint64_t unspill; /* Quantity of unspilled/reloaded pages */
|
||||||
MDBX_atomic_uint64_t
|
MDBX_atomic_uint64_t
|
||||||
wops; /* Number of explicit write operations (not a pages) to a disk */
|
wops; /* Number of explicit write operations (not a pages) to a disk */
|
||||||
MDBX_atomic_uint64_t
|
|
||||||
gcrtime; /* Time spending for reading/searching GC (aka FreeDB). The
|
|
||||||
unit/scale is platform-depended, see osal_monotime(). */
|
|
||||||
MDBX_atomic_uint64_t
|
MDBX_atomic_uint64_t
|
||||||
msync; /* Number of explicit msync/flush-to-disk operations */
|
msync; /* Number of explicit msync/flush-to-disk operations */
|
||||||
MDBX_atomic_uint64_t
|
MDBX_atomic_uint64_t
|
||||||
fsync; /* Number of explicit fsync/flush-to-disk operations */
|
fsync; /* Number of explicit fsync/flush-to-disk operations */
|
||||||
} MDBX_pgop_stat_t;
|
|
||||||
#endif /* MDBX_ENABLE_PGOP_STAT */
|
/* Статистика для профилирования GC.
|
||||||
|
* Логически эти данные может быть стоит вынести в другую структуру,
|
||||||
|
* но разница будет сугубо косметическая. */
|
||||||
|
struct {
|
||||||
|
/* Затраты на поддержку данных пользователя */
|
||||||
|
profgc_stat_t work;
|
||||||
|
/* Затраты на поддержку и обновления самой GC */
|
||||||
|
profgc_stat_t self;
|
||||||
|
/* Итераций обновления GC,
|
||||||
|
* больше 1 если были повторы/перезапуски */
|
||||||
|
uint32_t wloops;
|
||||||
|
/* Итерации слияния записей GC */
|
||||||
|
uint32_t coalescences;
|
||||||
|
/* Уничтожения steady-точек фиксации в MDBX_UTTERLY_NOSYNC */
|
||||||
|
uint32_t wipes;
|
||||||
|
/* Сбросы данные на диск вне MDBX_UTTERLY_NOSYNC */
|
||||||
|
uint32_t flushes;
|
||||||
|
/* Попытки пнуть тормозящих читателей */
|
||||||
|
uint32_t kicks;
|
||||||
|
} gc_prof;
|
||||||
|
} pgop_stat_t;
|
||||||
|
|
||||||
#if MDBX_LOCKING == MDBX_LOCKING_WIN32FILES
|
#if MDBX_LOCKING == MDBX_LOCKING_WIN32FILES
|
||||||
#define MDBX_CLOCK_SIGN UINT32_C(0xF10C)
|
#define MDBX_CLOCK_SIGN UINT32_C(0xF10C)
|
||||||
@ -738,11 +775,9 @@ typedef struct MDBX_lockinfo {
|
|||||||
|
|
||||||
MDBX_ALIGNAS(MDBX_CACHELINE_SIZE) /* cacheline ----------------------------*/
|
MDBX_ALIGNAS(MDBX_CACHELINE_SIZE) /* cacheline ----------------------------*/
|
||||||
|
|
||||||
#if MDBX_ENABLE_PGOP_STAT
|
|
||||||
/* Statistics of costly ops of all (running, completed and aborted)
|
/* Statistics of costly ops of all (running, completed and aborted)
|
||||||
* transactions */
|
* transactions */
|
||||||
MDBX_pgop_stat_t mti_pgop_stat;
|
pgop_stat_t mti_pgop_stat;
|
||||||
#endif /* MDBX_ENABLE_PGOP_STAT*/
|
|
||||||
|
|
||||||
MDBX_ALIGNAS(MDBX_CACHELINE_SIZE) /* cacheline ----------------------------*/
|
MDBX_ALIGNAS(MDBX_CACHELINE_SIZE) /* cacheline ----------------------------*/
|
||||||
|
|
||||||
@ -962,9 +997,13 @@ struct MDBX_txn {
|
|||||||
/* Additional flag for sync_locked() */
|
/* Additional flag for sync_locked() */
|
||||||
#define MDBX_SHRINK_ALLOWED UINT32_C(0x40000000)
|
#define MDBX_SHRINK_ALLOWED UINT32_C(0x40000000)
|
||||||
|
|
||||||
|
#define MDBX_TXN_UPDATE_GC 0x20 /* GC is being updated */
|
||||||
|
#define MDBX_TXN_FROZEN_RE 0x40 /* list of reclaimed-pgno must not altered */
|
||||||
|
|
||||||
#define TXN_FLAGS \
|
#define TXN_FLAGS \
|
||||||
(MDBX_TXN_FINISHED | MDBX_TXN_ERROR | MDBX_TXN_DIRTY | MDBX_TXN_SPILLS | \
|
(MDBX_TXN_FINISHED | MDBX_TXN_ERROR | MDBX_TXN_DIRTY | MDBX_TXN_SPILLS | \
|
||||||
MDBX_TXN_HAS_CHILD | MDBX_TXN_INVALID)
|
MDBX_TXN_HAS_CHILD | MDBX_TXN_INVALID | MDBX_TXN_UPDATE_GC | \
|
||||||
|
MDBX_TXN_FROZEN_RE)
|
||||||
|
|
||||||
#if (TXN_FLAGS & (MDBX_TXN_RW_BEGIN_FLAGS | MDBX_TXN_RO_BEGIN_FLAGS)) || \
|
#if (TXN_FLAGS & (MDBX_TXN_RW_BEGIN_FLAGS | MDBX_TXN_RO_BEGIN_FLAGS)) || \
|
||||||
((MDBX_TXN_RW_BEGIN_FLAGS | MDBX_TXN_RO_BEGIN_FLAGS | TXN_FLAGS) & \
|
((MDBX_TXN_RW_BEGIN_FLAGS | MDBX_TXN_RO_BEGIN_FLAGS | TXN_FLAGS) & \
|
||||||
@ -1023,8 +1062,8 @@ struct MDBX_txn {
|
|||||||
struct {
|
struct {
|
||||||
meta_troika_t troika;
|
meta_troika_t troika;
|
||||||
/* In write txns, array of cursors for each DB */
|
/* In write txns, array of cursors for each DB */
|
||||||
pgno_t *reclaimed_pglist; /* Reclaimed GC pages */
|
pgno_t *relist; /* Reclaimed GC pages */
|
||||||
txnid_t last_reclaimed; /* ID of last used record */
|
txnid_t last_reclaimed; /* ID of last used record */
|
||||||
#if MDBX_ENABLE_REFUND
|
#if MDBX_ENABLE_REFUND
|
||||||
pgno_t loose_refund_wl /* FIXME: describe */;
|
pgno_t loose_refund_wl /* FIXME: describe */;
|
||||||
#endif /* MDBX_ENABLE_REFUND */
|
#endif /* MDBX_ENABLE_REFUND */
|
||||||
@ -1100,9 +1139,7 @@ struct MDBX_cursor {
|
|||||||
#define C_SUB 0x04 /* Cursor is a sub-cursor */
|
#define C_SUB 0x04 /* Cursor is a sub-cursor */
|
||||||
#define C_DEL 0x08 /* last op was a cursor_del */
|
#define C_DEL 0x08 /* last op was a cursor_del */
|
||||||
#define C_UNTRACK 0x10 /* Un-track cursor when closing */
|
#define C_UNTRACK 0x10 /* Un-track cursor when closing */
|
||||||
#define C_RECLAIMING 0x20 /* GC lookup is prohibited */
|
uint8_t mc_flags;
|
||||||
#define C_GCFREEZE 0x40 /* reclaimed_pglist must not be updated */
|
|
||||||
uint8_t mc_flags; /* see mdbx_cursor */
|
|
||||||
|
|
||||||
/* Cursor checking flags. */
|
/* Cursor checking flags. */
|
||||||
#define CC_BRANCH 0x01 /* same as P_BRANCH for CHECK_LEAF_TYPE() */
|
#define CC_BRANCH 0x01 /* same as P_BRANCH for CHECK_LEAF_TYPE() */
|
||||||
@ -1113,7 +1150,7 @@ struct MDBX_cursor {
|
|||||||
#define CC_LEAF2 0x20 /* same as P_LEAF2 for CHECK_LEAF_TYPE() */
|
#define CC_LEAF2 0x20 /* same as P_LEAF2 for CHECK_LEAF_TYPE() */
|
||||||
#define CC_RETIRING 0x40 /* refs to child pages may be invalid */
|
#define CC_RETIRING 0x40 /* refs to child pages may be invalid */
|
||||||
#define CC_PAGECHECK 0x80 /* perform page checking, see MDBX_VALIDATION */
|
#define CC_PAGECHECK 0x80 /* perform page checking, see MDBX_VALIDATION */
|
||||||
uint8_t mc_checking; /* page checking level */
|
uint8_t mc_checking;
|
||||||
|
|
||||||
MDBX_page *mc_pg[CURSOR_STACK]; /* stack of pushed pages */
|
MDBX_page *mc_pg[CURSOR_STACK]; /* stack of pushed pages */
|
||||||
indx_t mc_ki[CURSOR_STACK]; /* stack of page indices */
|
indx_t mc_ki[CURSOR_STACK]; /* stack of page indices */
|
||||||
|
@ -73,6 +73,13 @@
|
|||||||
#error MDBX_ENABLE_REFUND must be defined as 0 or 1
|
#error MDBX_ENABLE_REFUND must be defined as 0 or 1
|
||||||
#endif /* MDBX_ENABLE_REFUND */
|
#endif /* MDBX_ENABLE_REFUND */
|
||||||
|
|
||||||
|
/** Controls profiling of GC search and updates. */
|
||||||
|
#ifndef MDBX_ENABLE_PROFGC
|
||||||
|
#define MDBX_ENABLE_PROFGC 0
|
||||||
|
#elif !(MDBX_ENABLE_PROFGC == 0 || MDBX_ENABLE_PROFGC == 1)
|
||||||
|
#error MDBX_ENABLE_PROFGC must be defined as 0 or 1
|
||||||
|
#endif /* MDBX_ENABLE_PROFGC */
|
||||||
|
|
||||||
/** Controls gathering statistics for page operations. */
|
/** Controls gathering statistics for page operations. */
|
||||||
#ifndef MDBX_ENABLE_PGOP_STAT
|
#ifndef MDBX_ENABLE_PGOP_STAT
|
||||||
#define MDBX_ENABLE_PGOP_STAT 1
|
#define MDBX_ENABLE_PGOP_STAT 1
|
||||||
|
55
src/osal.c
55
src/osal.c
@ -18,6 +18,7 @@
|
|||||||
|
|
||||||
#if defined(_WIN32) || defined(_WIN64)
|
#if defined(_WIN32) || defined(_WIN64)
|
||||||
|
|
||||||
|
#include <psapi.h>
|
||||||
#include <winioctl.h>
|
#include <winioctl.h>
|
||||||
|
|
||||||
#if !MDBX_WITHOUT_MSVC_CRT && defined(_DEBUG)
|
#if !MDBX_WITHOUT_MSVC_CRT && defined(_DEBUG)
|
||||||
@ -2700,6 +2701,60 @@ MDBX_INTERNAL_FUNC uint64_t osal_monotime(void) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MDBX_INTERNAL_FUNC uint64_t osal_cputime(size_t *optional_page_faults) {
|
||||||
|
#if defined(_WIN32) || defined(_WIN64)
|
||||||
|
if (optional_page_faults) {
|
||||||
|
PROCESS_MEMORY_COUNTERS pmc;
|
||||||
|
*optional_page_faults =
|
||||||
|
GetProcessMemoryInfo(GetCurrentProcess(), &pmc, sizeof(pmc))
|
||||||
|
? pmc.PageFaultCount
|
||||||
|
: 0;
|
||||||
|
}
|
||||||
|
FILETIME unused, usermode;
|
||||||
|
if (GetThreadTimes(GetCurrentThread(),
|
||||||
|
/* CreationTime */ &unused,
|
||||||
|
/* ExitTime */ &unused,
|
||||||
|
/* KernelTime */ &unused,
|
||||||
|
/* UserTime */ &usermode)) {
|
||||||
|
/* one second = 10_000_000 * 100ns = 78125 * (1 << 7) * 100ns;
|
||||||
|
* result = (h * f / 10_000_000) << 32) + l * f / 10_000_000 =
|
||||||
|
* = ((h * f) >> 7) / 78125) << 32) + ((l * f) >> 7) / 78125;
|
||||||
|
* 1) {h, l} *= f;
|
||||||
|
* 2) {h, l} >>= 7;
|
||||||
|
* 3) result = ((h / 78125) << 32) + l / 78125; */
|
||||||
|
uint64_t l = usermode.dwLowDateTime * performance_frequency.QuadPart;
|
||||||
|
uint64_t h = usermode.dwHighDateTime * performance_frequency.QuadPart;
|
||||||
|
l = h << (64 - 7) | l >> 7;
|
||||||
|
h = h >> 7;
|
||||||
|
return ((h / 78125) << 32) + l / 78125;
|
||||||
|
}
|
||||||
|
#elif defined(RUSAGE_THREAD) || defined(RUSAGE_LWP)
|
||||||
|
#ifndef RUSAGE_THREAD
|
||||||
|
#define RUSAGE_THREAD RUSAGE_LWP /* Solaris */
|
||||||
|
#endif
|
||||||
|
struct rusage usage;
|
||||||
|
if (getrusage(RUSAGE_THREAD, &usage) == 0) {
|
||||||
|
if (optional_page_faults)
|
||||||
|
*optional_page_faults = usage.ru_majflt;
|
||||||
|
return usage.ru_utime.tv_sec * UINT64_C(1000000000) +
|
||||||
|
usage.ru_utime.tv_usec * 1000u;
|
||||||
|
}
|
||||||
|
if (optional_page_faults)
|
||||||
|
*optional_page_faults = 0;
|
||||||
|
#elif defined(CLOCK_THREAD_CPUTIME_ID)
|
||||||
|
if (optional_page_faults)
|
||||||
|
*optional_page_faults = 0;
|
||||||
|
struct timespec ts;
|
||||||
|
if (likely(clock_gettime(CLOCK_THREAD_CPUTIME_ID, &ts) == 0))
|
||||||
|
return ts.tv_sec * UINT64_C(1000000000) + ts.tv_nsec;
|
||||||
|
#else
|
||||||
|
/* FIXME */
|
||||||
|
if (optional_page_faults)
|
||||||
|
*optional_page_faults = 0;
|
||||||
|
#endif
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------*/
|
/*----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
static void bootid_shake(bin128_t *p) {
|
static void bootid_shake(bin128_t *p) {
|
||||||
|
@ -620,6 +620,7 @@ osal_pthread_mutex_lock(pthread_mutex_t *mutex) {
|
|||||||
#endif /* !Windows */
|
#endif /* !Windows */
|
||||||
|
|
||||||
MDBX_INTERNAL_FUNC uint64_t osal_monotime(void);
|
MDBX_INTERNAL_FUNC uint64_t osal_monotime(void);
|
||||||
|
MDBX_INTERNAL_FUNC uint64_t osal_cputime(size_t *optional_page_faults);
|
||||||
MDBX_INTERNAL_FUNC uint64_t osal_16dot16_to_monotime(uint32_t seconds_16dot16);
|
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);
|
MDBX_INTERNAL_FUNC uint32_t osal_monotime_to_16dot16(uint64_t monotime);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user