summaryrefslogtreecommitdiff
path: root/libs/libmdbx/src/mdbx_chk.c
diff options
context:
space:
mode:
Diffstat (limited to 'libs/libmdbx/src/mdbx_chk.c')
-rw-r--r--libs/libmdbx/src/mdbx_chk.c170
1 files changed, 85 insertions, 85 deletions
diff --git a/libs/libmdbx/src/mdbx_chk.c b/libs/libmdbx/src/mdbx_chk.c
index 906c187347..a30003be28 100644
--- a/libs/libmdbx/src/mdbx_chk.c
+++ b/libs/libmdbx/src/mdbx_chk.c
@@ -1,7 +1,7 @@
/* mdbx_chk.c - memory-mapped database check tool */
/*
- * Copyright 2015-2020 Leonid Yuriev <leo@yuriev.ru>
+ * Copyright 2015-2021 Leonid Yuriev <leo@yuriev.ru>
* and other libmdbx authors: please see AUTHORS file.
* All rights reserved.
*
@@ -22,7 +22,7 @@
#define MDBX_TOOLS /* Avoid using internal mdbx_assert() */
/*
- * Copyright 2015-2020 Leonid Yuriev <leo@yuriev.ru>
+ * Copyright 2015-2021 Leonid Yuriev <leo@yuriev.ru>
* and other libmdbx authors: please see AUTHORS file.
* All rights reserved.
*
@@ -34,7 +34,7 @@
* top-level directory of the distribution or, alternatively, at
* <http://www.OpenLDAP.org/license.html>. */
-#define MDBX_BUILD_SOURCERY 69c11536d7625297e4095e26adca038aaec4105753b20848ae5dfd8bc130d747_v0_9_2_110_g4e13d12
+#define MDBX_BUILD_SOURCERY 37ec6726f69ef69c4e52fcfb87d700f44f37246b1b635f455d2a429776a8eec6_v0_9_2_136_g9f0ff86
#ifdef MDBX_CONFIG_H
#include MDBX_CONFIG_H
#endif
@@ -126,7 +126,7 @@
#include "mdbx.h"
/*
- * Copyright 2015-2020 Leonid Yuriev <leo@yuriev.ru>
+ * Copyright 2015-2021 Leonid Yuriev <leo@yuriev.ru>
* and other libmdbx authors: please see AUTHORS file.
* All rights reserved.
*
@@ -558,7 +558,7 @@ extern "C" {
/* https://en.wikipedia.org/wiki/Operating_system_abstraction_layer */
/*
- * Copyright 2015-2020 Leonid Yuriev <leo@yuriev.ru>
+ * Copyright 2015-2021 Leonid Yuriev <leo@yuriev.ru>
* and other libmdbx authors: please see AUTHORS file.
* All rights reserved.
*
@@ -1021,15 +1021,17 @@ extern void mdbx_osal_jitter(bool tiny);
/*----------------------------------------------------------------------------*/
/* Atomics */
-#if defined(__cplusplus) && !defined(__STDC_NO_ATOMICS__) && __has_include(<cstdatomic>)
+#if defined(__cplusplus) && !defined(__STDC_NO_ATOMICS__) && (__has_include(<cstdatomic>) || __has_extension(cxx_atomic))
#include <cstdatomic>
-#elif !defined(__cplusplus) && (__STDC_VERSION__ >= 201112L) && \
+#define MDBX_HAVE_C11ATOMICS
+#elif !defined(__cplusplus) && \
+ (__STDC_VERSION__ >= 201112L || __has_extension(c_atomic)) && \
!defined(__STDC_NO_ATOMICS__) && \
(__GNUC_PREREQ(4, 9) || __CLANG_PREREQ(3, 8) || \
!(defined(__GNUC__) || defined(__clang__)))
#include <stdatomic.h>
+#define MDBX_HAVE_C11ATOMICS
#elif defined(__GNUC__) || defined(__clang__)
-/* LY: nothing required */
#elif defined(_MSC_VER)
#pragma warning(disable : 4163) /* 'xyz': not available as an intrinsic */
#pragma warning(disable : 4133) /* 'function': incompatible types - from \
@@ -1065,14 +1067,6 @@ static __maybe_unused __inline void mdbx_compiler_barrier(void) {
_ReadWriteBarrier();
#elif defined(__INTEL_COMPILER) /* LY: Intel Compiler may mimic GCC and MSC */
__memory_barrier();
- if (type > MDBX_BARRIER_COMPILER)
-#if defined(__ia64__) || defined(__ia64) || defined(_M_IA64)
- __mf();
-#elif defined(__i386__) || defined(__x86_64__)
- _mm_mfence();
-#else
-#error "Unknown target for Intel Compiler, please report to us."
-#endif
#elif defined(__SUNPRO_C) || defined(__sun) || defined(sun)
__compiler_barrier();
#elif (defined(_HPUX_SOURCE) || defined(__hpux) || defined(__HP_aCC)) && \
@@ -1087,21 +1081,23 @@ static __maybe_unused __inline void mdbx_compiler_barrier(void) {
}
static __maybe_unused __inline void mdbx_memory_barrier(void) {
-#if __has_extension(c_atomic) && !defined(__STDC_NO_ATOMICS__)
- atomic_thread_fence(__ATOMIC_SEQ_CST);
+#ifdef MDBX_HAVE_C11ATOMICS
+ atomic_thread_fence(memory_order_seq_cst);
#elif defined(__ATOMIC_SEQ_CST)
+#ifdef __clang__
+ __c11_atomic_thread_fence(__ATOMIC_SEQ_CST);
+#else
__atomic_thread_fence(__ATOMIC_SEQ_CST);
+#endif
#elif defined(__clang__) || defined(__GNUC__)
__sync_synchronize();
-#elif defined(_MSC_VER)
+#elif defined(_WIN32) || defined(_WIN64)
MemoryBarrier();
#elif defined(__INTEL_COMPILER) /* LY: Intel Compiler may mimic GCC and MSC */
-#if defined(__ia64__) || defined(__ia64) || defined(_M_IA64)
- __mf();
-#elif defined(__i386__) || defined(__x86_64__)
+#if defined(__ia32__)
_mm_mfence();
#else
-#error "Unknown target for Intel Compiler, please report to us."
+ __mf();
#endif
#elif defined(__SUNPRO_C) || defined(__sun) || defined(sun)
__machine_rw_barrier();
@@ -1831,6 +1827,31 @@ extern LIBMDBX_API const char *const mdbx_sourcery_anchor;
/*----------------------------------------------------------------------------*/
/* Basic constants and types */
+typedef union {
+ volatile uint32_t weak;
+#ifdef MDBX_HAVE_C11ATOMICS
+ volatile _Atomic uint32_t c11a;
+#endif /* MDBX_HAVE_C11ATOMICS */
+} MDBX_atomic_uint32_t;
+
+typedef union {
+ volatile uint64_t weak;
+#if defined(MDBX_HAVE_C11ATOMICS) && (MDBX_64BIT_CAS || MDBX_64BIT_ATOMIC)
+ volatile _Atomic uint64_t c11a;
+#endif
+#if !defined(MDBX_HAVE_C11ATOMICS) || !MDBX_64BIT_CAS || !MDBX_64BIT_ATOMIC
+ __anonymous_struct_extension__ struct {
+#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+ MDBX_atomic_uint32_t low, high;
+#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
+ MDBX_atomic_uint32_t high, low;
+#else
+#error "FIXME: Unsupported byte order"
+#endif /* __BYTE_ORDER__ */
+ };
+#endif
+} MDBX_atomic_uint64_t;
+
/* The minimum number of keys required in a database page.
* Setting this to a larger value will place a smaller bound on the
* maximum size of a data item. Data items larger than this size will
@@ -1869,6 +1890,7 @@ extern LIBMDBX_API const char *const mdbx_sourcery_anchor;
* MDBX uses 32 bit for page numbers. This limits database
* size up to 2^44 bytes, in case of 4K pages. */
typedef uint32_t pgno_t;
+typedef MDBX_atomic_uint32_t atomic_pgno_t;
#define PRIaPGNO PRIu32
#define MAX_PAGENO UINT32_C(0x7FFFffff)
#define MIN_PAGENO NUM_METAS
@@ -1877,6 +1899,7 @@ typedef uint32_t pgno_t;
/* A transaction ID. */
typedef uint64_t txnid_t;
+typedef MDBX_atomic_uint64_t atomic_txnid_t;
#define PRIaTXN PRIi64
#define MIN_TXNID UINT64_C(1)
#define MAX_TXNID (SAFE64_INVALID_THRESHOLD - 1)
@@ -1903,24 +1926,6 @@ typedef uint16_t indx_t;
/* Core structures for database and shared memory (i.e. format definition) */
#pragma pack(push, 1)
-typedef union mdbx_safe64 {
- volatile uint64_t inconsistent;
-#if MDBX_64BIT_ATOMIC
- volatile uint64_t atomic;
-#endif /* MDBX_64BIT_ATOMIC */
- __anonymous_struct_extension__ struct {
-#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
- volatile uint32_t low;
- volatile uint32_t high;
-#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
- volatile uint32_t high;
- volatile uint32_t low;
-#else
-#error "FIXME: Unsupported byte order"
-#endif /* __BYTE_ORDER__ */
- };
-} mdbx_safe64_t;
-
/* Information about a single database in the environment. */
typedef struct MDBX_db {
uint16_t md_flags; /* see mdbx_dbi_open */
@@ -2123,7 +2128,7 @@ typedef struct MDBX_reader {
* anything; all we need to know is which version of the DB they
* started from so we can avoid overwriting any data used in that
* particular version. */
- mdbx_safe64_t /* txnid_t */ mr_txnid;
+ MDBX_atomic_uint64_t /* txnid_t */ mr_txnid;
/* The information we store in a single slot of the reader table.
* In addition to a transaction ID, we also record the process and
@@ -2135,23 +2140,18 @@ typedef struct MDBX_reader {
* opening the lock file. */
/* The thread ID of the thread owning this txn. */
-#if MDBX_WORDBITS >= 64
- volatile uint64_t mr_tid;
-#else
- volatile uint32_t mr_tid;
- volatile uint32_t mr_aba_curer; /* CSN to resolve ABA_problems on 32-bit arch,
- unused for now */
-#endif
+ MDBX_atomic_uint64_t mr_tid;
+
/* The process ID of the process owning this reader txn. */
- volatile uint32_t mr_pid;
+ MDBX_atomic_uint32_t mr_pid;
/* The number of pages used in the reader's MVCC snapshot,
* i.e. the value of meta->mm_geo.next and txn->mt_next_pgno */
- volatile pgno_t mr_snapshot_pages_used;
+ atomic_pgno_t mr_snapshot_pages_used;
/* Number of retired pages at the time this reader starts transaction. So,
* at any time the difference mm_pages_retired - mr_snapshot_pages_retired
* will give the number of pages which this reader restraining from reuse. */
- volatile uint64_t mr_snapshot_pages_retired;
+ MDBX_atomic_uint64_t mr_snapshot_pages_retired;
} MDBX_reader;
/* The header for the reader table (a memory-mapped lock file). */
@@ -2164,25 +2164,25 @@ typedef struct MDBX_lockinfo {
uint32_t mti_os_and_format;
/* Flags which environment was opened. */
- volatile uint32_t mti_envmode;
+ MDBX_atomic_uint32_t mti_envmode;
/* Threshold of un-synced-with-disk pages for auto-sync feature,
* zero means no-threshold, i.e. auto-sync is disabled. */
- volatile pgno_t mti_autosync_threshold;
+ atomic_pgno_t mti_autosync_threshold;
/* Low 32-bit of txnid with which meta-pages was synced,
* i.e. for sync-polling in the MDBX_NOMETASYNC mode. */
- volatile uint32_t mti_meta_sync_txnid;
+ MDBX_atomic_uint32_t mti_meta_sync_txnid;
/* Period for timed auto-sync feature, i.e. at the every steady checkpoint
* the mti_unsynced_timeout sets to the current_time + mti_autosync_period.
* The time value is represented in a suitable system-dependent form, for
* example clock_gettime(CLOCK_BOOTTIME) or clock_gettime(CLOCK_MONOTONIC).
* Zero means timed auto-sync is disabled. */
- volatile uint64_t mti_autosync_period;
+ MDBX_atomic_uint64_t mti_autosync_period;
/* Marker to distinguish uniqueness of DB/CLK.*/
- volatile uint64_t mti_bait_uniqueness;
+ MDBX_atomic_uint64_t mti_bait_uniqueness;
alignas(MDBX_CACHELINE_SIZE) /* cacheline ---------------------------------*/
@@ -2191,21 +2191,21 @@ typedef struct MDBX_lockinfo {
mdbx_ipclock_t mti_wlock;
#endif /* MDBX_LOCKING > 0 */
- volatile txnid_t mti_oldest_reader;
+ atomic_txnid_t mti_oldest_reader;
/* Timestamp of the last steady sync. Value is represented in a suitable
* system-dependent form, for example clock_gettime(CLOCK_BOOTTIME) or
* clock_gettime(CLOCK_MONOTONIC). */
- volatile uint64_t mti_sync_timestamp;
+ MDBX_atomic_uint64_t mti_sync_timestamp;
/* Number un-synced-with-disk pages for auto-sync feature. */
- volatile pgno_t mti_unsynced_pages;
+ atomic_pgno_t mti_unsynced_pages;
/* Number of page which was discarded last time by madvise(MADV_FREE). */
- volatile pgno_t mti_discarded_tail;
+ atomic_pgno_t mti_discarded_tail;
/* Timestamp of the last readers check. */
- volatile uint64_t mti_reader_check_timestamp;
+ MDBX_atomic_uint64_t mti_reader_check_timestamp;
alignas(MDBX_CACHELINE_SIZE) /* cacheline ---------------------------------*/
@@ -2217,8 +2217,8 @@ typedef struct MDBX_lockinfo {
/* The number of slots that have been used in the reader table.
* This always records the maximum count, it is not decremented
* when readers release their slots. */
- volatile unsigned mti_numreaders;
- volatile unsigned mti_readers_refresh_flag;
+ MDBX_atomic_uint32_t mti_numreaders;
+ MDBX_atomic_uint32_t mti_readers_refresh_flag;
#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || \
(!defined(__cplusplus) && defined(_MSC_VER))
@@ -2273,7 +2273,7 @@ typedef struct MDBX_lockinfo {
#if MDBX_WORDBITS >= 64
#define MAX_MAPSIZE MAX_MAPSIZE64
#define MDBX_READERS_LIMIT \
- ((65536 - sizeof(MDBX_lockinfo)) / sizeof(MDBX_reader))
+ ((MAX_PAGESIZE - sizeof(MDBX_lockinfo)) / sizeof(MDBX_reader))
#define MDBX_PGL_LIMIT MAX_PAGENO
#else
#define MDBX_READERS_LIMIT 1024
@@ -2557,7 +2557,7 @@ typedef struct MDBX_cursor_couple {
/* The database environment. */
struct MDBX_env {
#define MDBX_ME_SIGNATURE UINT32_C(0x9A899641)
- uint32_t me_signature;
+ MDBX_atomic_uint32_t me_signature;
/* Failed to update the meta page. Probably an I/O error. */
#define MDBX_FATAL_ERROR UINT32_C(0x80000000)
/* Some fields are initialized. */
@@ -2603,11 +2603,11 @@ struct MDBX_env {
mdbx_ipclock_t *me_wlock;
#endif /* MDBX_LOCKING > 0 */
- 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 */
- volatile txnid_t *me_oldest; /* ID of oldest reader last time we looked */
- MDBX_page *me_dp_reserve; /* list of malloc'd blocks for re-use */
+ 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 */
+ atomic_txnid_t *me_oldest; /* ID of oldest reader last time we looked */
+ MDBX_page *me_dp_reserve; /* list of malloc'd blocks for re-use */
/* PNL of pages that became unused in a write txn */
MDBX_PNL me_retired_pages;
/* Number of freelist items that can fit in a single overflow page */
@@ -2615,12 +2615,12 @@ struct MDBX_env {
unsigned me_branch_nodemax; /* max size of a branch-node */
uint32_t me_live_reader; /* have liveness lock in reader table */
void *me_userctx; /* User-settable context */
- volatile uint64_t *me_sync_timestamp;
- volatile uint64_t *me_autosync_period;
- volatile pgno_t *me_unsynced_pages;
- volatile pgno_t *me_autosync_threshold;
- volatile pgno_t *me_discarded_tail;
- volatile uint32_t *me_meta_sync_txnid;
+ MDBX_atomic_uint64_t *me_sync_timestamp;
+ MDBX_atomic_uint64_t *me_autosync_period;
+ atomic_pgno_t *me_unsynced_pages;
+ atomic_pgno_t *me_autosync_threshold;
+ atomic_pgno_t *me_discarded_tail;
+ MDBX_atomic_uint32_t *me_meta_sync_txnid;
MDBX_hsr_func *me_hsr_callback; /* Callback for kicking laggard readers */
unsigned me_dp_reserve_len;
struct {
@@ -2637,13 +2637,13 @@ struct MDBX_env {
#if MDBX_LOCKING > 0
mdbx_ipclock_t wlock;
#endif /* MDBX_LOCKING > 0 */
- txnid_t oldest;
- uint64_t sync_timestamp;
- uint64_t autosync_period;
- pgno_t autosync_pending;
- pgno_t autosync_threshold;
- pgno_t discarded_tail;
- uint32_t meta_sync_txnid;
+ atomic_txnid_t oldest;
+ MDBX_atomic_uint64_t sync_timestamp;
+ MDBX_atomic_uint64_t autosync_period;
+ atomic_pgno_t autosync_pending;
+ atomic_pgno_t autosync_threshold;
+ atomic_pgno_t discarded_tail;
+ MDBX_atomic_uint32_t meta_sync_txnid;
} me_lckless_stub;
#if MDBX_DEBUG
MDBX_assert_func *me_assert_func; /* Callback for assertion failures */
@@ -4695,7 +4695,7 @@ int main(int argc, char *argv[]) {
value = envinfo.mi_mapsize / envstat.ms_psize - alloc_pages;
print(", remained %" PRIu64 " (%.1f%%)", value, value / percent);
- value = alloc_pages - gc_pages;
+ value = dont_traversal ? alloc_pages - gc_pages : walk.pgcount;
print(", used %" PRIu64 " (%.1f%%)", value, value / percent);
print(", gc %" PRIu64 " (%.1f%%)", gc_pages, gc_pages / percent);