mdbx: Merge branch 'master' into devel.

Change-Id: Ic130cd181097332aa2f49019d75403e18d8cba0d
This commit is contained in:
Leonid Yuriev 2020-09-25 01:13:11 +03:00
commit 860aa017db
26 changed files with 161 additions and 155 deletions

View File

@ -187,11 +187,11 @@ if(SUBPROJECT)
option(BUILD_SHARED_LIBS "Build shared libraries (DLLs)" OFF) option(BUILD_SHARED_LIBS "Build shared libraries (DLLs)" OFF)
endif() endif()
if(NOT DEFINED CMAKE_POSITION_INDEPENDENT_CODE) if(NOT DEFINED CMAKE_POSITION_INDEPENDENT_CODE)
option(CMAKE_POSITION_INDEPENDENT_CODE "Generate position independed (PIC)" ON) option(CMAKE_POSITION_INDEPENDENT_CODE "Generate position independent (PIC)" ON)
endif() endif()
else() else()
option(BUILD_SHARED_LIBS "Build shared libraries (DLLs)" ON) option(BUILD_SHARED_LIBS "Build shared libraries (DLLs)" ON)
option(CMAKE_POSITION_INDEPENDENT_CODE "Generate position independed (PIC)" ON) option(CMAKE_POSITION_INDEPENDENT_CODE "Generate position independent (PIC)" ON)
if (CC_HAS_ARCH_NATIVE) if (CC_HAS_ARCH_NATIVE)
option(BUILD_FOR_NATIVE_CPU "Generate code for the compiling machine CPU" OFF) option(BUILD_FOR_NATIVE_CPU "Generate code for the compiling machine CPU" OFF)
endif() endif()

View File

@ -6,7 +6,7 @@ libmdbx
> Please refer to the online [documentation](https://erthink.github.io/libmdbx/) > Please refer to the online [documentation](https://erthink.github.io/libmdbx/)
> with [`C` API description](https://erthink.github.io/libmdbx/group__c__api.html) > with [`C` API description](https://erthink.github.io/libmdbx/group__c__api.html)
> and pay attention to the preliminary [`C++` API](https://github.com/erthink/libmdbx/blob/c%2B%2B/mdbx.h%2B%2B). > and pay attention to the preliminary [`C++` API](https://github.com/erthink/libmdbx/blob/c%2B%2B/mdbx.h%2B%2B).
> Questions, feedback and suggestions are welcome to the [Telergam' group](https://t.me/libmdbx). > Questions, feedback and suggestions are welcome to the [Telegram' group](https://t.me/libmdbx).
<!-- section-begin overview --> <!-- section-begin overview -->
_libmdbx_ is an extremely fast, compact, powerful, embedded, _libmdbx_ is an extremely fast, compact, powerful, embedded,
@ -224,7 +224,7 @@ the user's point of view.
> _libmdbx_ database format depends only on the [endianness](https://en.wikipedia.org/wiki/Endianness) but not on the [bitness](https://en.wiktionary.org/wiki/bitness). > _libmdbx_ database format depends only on the [endianness](https://en.wikipedia.org/wiki/Endianness) but not on the [bitness](https://en.wiktionary.org/wiki/bitness).
6. LIFO policy for Garbage Collection recycling. This can significantly increase write performance due write-back disk cache up to several times in a best case scenario. 6. LIFO policy for Garbage Collection recycling. This can significantly increase write performance due write-back disk cache up to several times in a best case scenario.
> LIFO means that for reuse will be taken the latest becames unused pages. > LIFO means that for reuse will be taken the latest becomes unused pages.
> Therefore the loop of database pages circulation becomes as short as possible. > Therefore the loop of database pages circulation becomes as short as possible.
> In other words, the set of pages, that are (over)written in memory and on disk during a series of write transactions, will be as small as possible. > In other words, the set of pages, that are (over)written in memory and on disk during a series of write transactions, will be as small as possible.
> Thus creates ideal conditions for the battery-backed or flash-backed disk cache efficiency. > Thus creates ideal conditions for the battery-backed or flash-backed disk cache efficiency.

View File

@ -231,7 +231,7 @@ else()
check_compiler_flag("-ggdb" CC_HAS_GGDB) check_compiler_flag("-ggdb" CC_HAS_GGDB)
check_compiler_flag("-fvisibility=hidden" CC_HAS_VISIBILITY) check_compiler_flag("-fvisibility=hidden" CC_HAS_VISIBILITY)
check_compiler_flag("-march=native" CC_HAS_ARCH_NATIVE) check_compiler_flag("-march=native" CC_HAS_ARCH_NATIVE)
check_compiler_flag("-Og" CC_HAS_DEBUG_FRENDLY_OPTIMIZATION) check_compiler_flag("-Og" CC_HAS_DEBUG_FRIENDLY_OPTIMIZATION)
check_compiler_flag("-Wall" CC_HAS_WALL) check_compiler_flag("-Wall" CC_HAS_WALL)
check_compiler_flag("-Ominimal" CC_HAS_OMINIMAL) check_compiler_flag("-Ominimal" CC_HAS_OMINIMAL)
check_compiler_flag("-ffunction-sections -fdata-sections" CC_HAS_SECTIONS) check_compiler_flag("-ffunction-sections -fdata-sections" CC_HAS_SECTIONS)

View File

@ -155,7 +155,7 @@ macro(fetch_version name source_root_directory parent_scope)
if(NOT ${name}_GIT_VERSION OR NOT ${name}_GIT_TIMESTAMP OR ${name}_GIT_REVISION STREQUAL "") if(NOT ${name}_GIT_VERSION OR NOT ${name}_GIT_TIMESTAMP OR ${name}_GIT_REVISION STREQUAL "")
if(GIT AND EXISTS "${source_root_directory}/.git") if(GIT AND EXISTS "${source_root_directory}/.git")
message(WARNING "Unable to retrive ${name} version from git.") message(WARNING "Unable to retrieve ${name} version from git.")
endif() endif()
set(${name}_GIT_VERSION "0;0;0;0") set(${name}_GIT_VERSION "0;0;0;0")
set(${name}_GIT_TIMESTAMP "") set(${name}_GIT_TIMESTAMP "")
@ -168,7 +168,7 @@ macro(fetch_version name source_root_directory parent_scope)
endif() endif()
if(NOT ${name}_VERSION) if(NOT ${name}_VERSION)
message(WARNING "Unable to retrive ${name} version from \"${version_file}\" file.") message(WARNING "Unable to retrieve ${name} version from \"${version_file}\" file.")
set(${name}_VERSION_LIST ${${name}_GIT_VERSION}) set(${name}_VERSION_LIST ${${name}_GIT_VERSION})
string(REPLACE ";" "." ${name}_VERSION "${${name}_GIT_VERSION}") string(REPLACE ";" "." ${name}_VERSION "${${name}_GIT_VERSION}")
else() else()

View File

@ -29,7 +29,7 @@ In addition to those listed for some functions.
\note Workaround: Check for stale readers periodically, using the \note Workaround: Check for stale readers periodically, using the
`mdbx_reader_check()` function or the mdbx_stat tool. `mdbx_reader_check()` function or the mdbx_stat tool.
3. Stale writers will be cleared automatically by MDBX on supprted 3. Stale writers will be cleared automatically by MDBX on supported
platforms. But this is platform-specific, especially of platforms. But this is platform-specific, especially of
implementation of shared POSIX-mutexes and support for robust implementation of shared POSIX-mutexes and support for robust
mutexes. For instance there are no known issues on Linux, OSX, mutexes. For instance there are no known issues on Linux, OSX,
@ -108,7 +108,7 @@ vulnerable to corruption from other processes.
For compatibility with LMDB which allows multi-opening, MDBX can be For compatibility with LMDB which allows multi-opening, MDBX can be
configured at runtime by `mdbx_setup_debug(MDBX_DBG_LEGACY_MULTIOPEN, ...)` configured at runtime by `mdbx_setup_debug(MDBX_DBG_LEGACY_MULTIOPEN, ...)`
prior to calling other MDBX funcitons. In this way MDBX will track prior to calling other MDBX functions. In this way MDBX will track
databases opening, detect multi-opening cases and then recover POSIX file databases opening, detect multi-opening cases and then recover POSIX file
locks as necessary. However, lock recovery can cause unexpected pauses, locks as necessary. However, lock recovery can cause unexpected pauses,
such as when another process opened the database in exclusive mode before such as when another process opened the database in exclusive mode before
@ -157,7 +157,7 @@ The "next" version of libmdbx (MithrilDB) will completely solve this.
The "next" version of libmdbx (MithrilDB) will solve this issue. The "next" version of libmdbx (MithrilDB) will solve this issue.
- Avoid aborting a process with an active read-only transaction in scenaries - Avoid aborting a process with an active read-only transaction in scenarios
with high rate of write transactions. The transaction becomes "long-lived" with high rate of write transactions. The transaction becomes "long-lived"
as above until a check for stale readers is performed or the LCK-file is as above until a check for stale readers is performed or the LCK-file is
reset, since the process may not remove it from the lockfile. This does reset, since the process may not remove it from the lockfile. This does

View File

@ -99,7 +99,7 @@ opened the file across all threads. The reason for this is:
vulnerable to corruption from other processes. vulnerable to corruption from other processes.
+ For compatibility with LMDB which allows multi-opening, MDBX can be + For compatibility with LMDB which allows multi-opening, MDBX can be
configured at runtime by \ref mdbx_setup_debug() with \ref MDBX_DBG_LEGACY_MULTIOPEN` option configured at runtime by \ref mdbx_setup_debug() with \ref MDBX_DBG_LEGACY_MULTIOPEN` option
prior to calling other MDBX funcitons. In this way MDBX will track prior to calling other MDBX functions. In this way MDBX will track
databases opening, detect multi-opening cases and then recover POSIX file databases opening, detect multi-opening cases and then recover POSIX file
locks as necessary. However, lock recovery can cause unexpected pauses, locks as necessary. However, lock recovery can cause unexpected pauses,
such as when another process opened the database in exclusive mode before such as when another process opened the database in exclusive mode before
@ -108,7 +108,7 @@ opened the file across all threads. The reason for this is:
Do not use opened MDBX environment(s) after `fork()` in a child process(es), Do not use opened MDBX environment(s) after `fork()` in a child process(es),
MDBX will check and prevent this at critical points. Instead, ensure there is MDBX will check and prevent this at critical points. Instead, ensure there is
no open MDBX-instance(s) during fork(), or atleast close it immediately after no open MDBX-instance(s) during fork(), or at least close it immediately after
`fork()` in the child process and reopen if required - for instance by using `fork()` in the child process and reopen if required - for instance by using
`pthread_atfork()`. The reason for this is: `pthread_atfork()`. The reason for this is:
- For competitive consistent reading, MDBX assigns a slot in the shared - For competitive consistent reading, MDBX assigns a slot in the shared
@ -123,7 +123,7 @@ no open MDBX-instance(s) during fork(), or atleast close it immediately after
threads could run in critical and/or intermediate sections of MDBX code threads could run in critical and/or intermediate sections of MDBX code
with interaction and/or racing conditions with threads from other with interaction and/or racing conditions with threads from other
process(es). For instance: shrinking a database or copying it to a pipe, process(es). For instance: shrinking a database or copying it to a pipe,
opening or closing environment, begining or finishing a transaction, opening or closing environment, beginning or finishing a transaction,
and so on. and so on.
= Therefore, any solution other than simply close database (and reopen if = Therefore, any solution other than simply close database (and reopen if
necessary) in a child process would be both extreme complicated and so necessary) in a child process would be both extreme complicated and so
@ -234,7 +234,7 @@ The full \ref c_api documentation lists further details below, like how to:
- Reduce (temporarily) robustness to gain even more speed: \ref sync_modes. - Reduce (temporarily) robustness to gain even more speed: \ref sync_modes.
- Gather statistics about the database: \ref c_statinfo. - Gather statistics about the database: \ref c_statinfo.
- Sstimate size of range query result: \ref c_rqest. - Sstimate size of range query result: \ref c_rqest.
- Double perfomance by LIFO reclaiming on storages with write-back: \ref MDBX_LIFORECLAIM. - Double performance by LIFO reclaiming on storages with write-back: \ref MDBX_LIFORECLAIM.
- Use sequences and canary markers: \ref mdbx_dbi_sequence(), \ref MDBX_canary. - Use sequences and canary markers: \ref mdbx_dbi_sequence(), \ref MDBX_canary.
- Use lack-of-space callback (aka OOM-KICK): \ref mdbx_env_set_oomfunc(). - Use lack-of-space callback (aka OOM-KICK): \ref mdbx_env_set_oomfunc().
- Use exclusive mode: \ref MDBX_EXCLUSIVE. - Use exclusive mode: \ref MDBX_EXCLUSIVE.

View File

@ -1,4 +1,4 @@
/* MDBX usage examle /* MDBX usage example
* *
* Do a line-by-line comparison of this and sample-bdb.txt * Do a line-by-line comparison of this and sample-bdb.txt
*/ */

48
mdbx.h
View File

@ -188,7 +188,7 @@ typedef DWORD mdbx_tid_t;
#include <errno.h> /* for error codes */ #include <errno.h> /* for error codes */
#include <pthread.h> /* for pthread_t */ #include <pthread.h> /* for pthread_t */
#include <sys/types.h> /* for pid_t */ #include <sys/types.h> /* for pid_t */
#include <sys/uio.h> /* for truct iovec */ #include <sys/uio.h> /* for struct iovec */
#define HAVE_STRUCT_IOVEC 1 #define HAVE_STRUCT_IOVEC 1
typedef int mdbx_filehandle_t; typedef int mdbx_filehandle_t;
typedef pid_t mdbx_pid_t; typedef pid_t mdbx_pid_t;
@ -644,7 +644,7 @@ struct iovec {
#if defined(__sun) || defined(__SVR4) || defined(__svr4__) #if defined(__sun) || defined(__SVR4) || defined(__svr4__)
/* The `iov_len` is signed on Sun/Solaris. /* The `iov_len` is signed on Sun/Solaris.
* So define custom MDBX_val to avoid a lot of warings. */ * So define custom MDBX_val to avoid a lot of warnings. */
struct MDBX_val { struct MDBX_val {
void *iov_base; /**< pointer to some data */ void *iov_base; /**< pointer to some data */
size_t iov_len; /**< the length of data in bytes */ size_t iov_len; /**< the length of data in bytes */
@ -869,7 +869,7 @@ enum MDBX_env_flags_t {
* `MDBX_EXCLUSIVE` flag can be used as a replacement for `MDB_NOLOCK`, * `MDBX_EXCLUSIVE` flag can be used as a replacement for `MDB_NOLOCK`,
* which don't supported by MDBX. * which don't supported by MDBX.
* In this way, you can get the minimal overhead, but with the correct * In this way, you can get the minimal overhead, but with the correct
* multi-process and mutli-thread locking. * multi-process and multi-thread locking.
* *
* - with `MDBX_EXCLUSIVE` = open environment in exclusive/monopolistic mode * - with `MDBX_EXCLUSIVE` = open environment in exclusive/monopolistic mode
* or return \ref MDBX_BUSY if environment already used by other process. * or return \ref MDBX_BUSY if environment already used by other process.
@ -1155,7 +1155,7 @@ enum MDBX_env_flags_t {
* \ref mdbx_env_sync() as alternatively for batch committing or nested * \ref mdbx_env_sync() as alternatively for batch committing or nested
* transaction (in some cases). As well, auto-sync feature exposed by * transaction (in some cases). As well, auto-sync feature exposed by
* \ref mdbx_env_set_syncbytes() and \ref mdbx_env_set_syncperiod() functions * \ref mdbx_env_set_syncbytes() and \ref mdbx_env_set_syncperiod() functions
* could be very usefull with `MDBX_SAFE_NOSYNC` flag. * could be very useful with `MDBX_SAFE_NOSYNC` flag.
* *
* The number and volume of of disk IOPs with MDBX_SAFE_NOSYNC flag will * The number and volume of of disk IOPs with MDBX_SAFE_NOSYNC flag will
* exactly the as without any no-sync flags. However, you should expect a * exactly the as without any no-sync flags. However, you should expect a
@ -1202,7 +1202,7 @@ enum MDBX_env_flags_t {
* - a system crash immediately after commit the write transaction * - a system crash immediately after commit the write transaction
* high likely lead to database corruption. * high likely lead to database corruption.
* - successful completion of mdbx_env_sync(force = true) after one or * - successful completion of mdbx_env_sync(force = true) after one or
* more commited transactions guarantees consystency and durability. * more commited transactions guarantees consistency and durability.
* - BUT by committing two or more transactions you back database into * - BUT by committing two or more transactions you back database into
* a weak state, in which a system crash may lead to database corruption! * a weak state, in which a system crash may lead to database corruption!
* In case single transaction after mdbx_env_sync, you may lose transaction * In case single transaction after mdbx_env_sync, you may lose transaction
@ -2059,8 +2059,10 @@ LIBMDBX_API int mdbx_env_sync_poll(MDBX_env *env);
* \returns A non-zero error value on failure and 0 on success. */ * \returns A non-zero error value on failure and 0 on success. */
LIBMDBX_API int mdbx_env_set_syncbytes(MDBX_env *env, size_t threshold); LIBMDBX_API int mdbx_env_set_syncbytes(MDBX_env *env, size_t threshold);
/** \brief Sets relative period since the last unsteay commit to force flush the /** \brief Sets relative period since the last unsteady commit to force flush
* data buffers to disk, even of \ref MDBX_SAFE_NOSYNC flag in the environment. * the data buffers to disk, even of \ref MDBX_SAFE_NOSYNC flag in the
* environment.
*
* \ingroup c_settings * \ingroup c_settings
* *
* The relative period value affects all processes which operates with given * The relative period value affects all processes which operates with given
@ -2084,7 +2086,7 @@ LIBMDBX_API int mdbx_env_set_syncbytes(MDBX_env *env, size_t threshold);
* \param [in] env An environment handle returned by \ref mdbx_env_create(). * \param [in] env An environment handle returned by \ref mdbx_env_create().
* \param [in] seconds_16dot16 The period in 1/65536 of second when * \param [in] seconds_16dot16 The period in 1/65536 of second when
* a synchronous flush would be made since * a synchronous flush would be made since
* the last unsteay commit. * the last unsteady commit.
* *
* \returns A non-zero error value on failure and 0 on success. */ * \returns A non-zero error value on failure and 0 on success. */
LIBMDBX_API int mdbx_env_set_syncperiod(MDBX_env *env, LIBMDBX_API int mdbx_env_set_syncperiod(MDBX_env *env,
@ -2187,7 +2189,7 @@ LIBMDBX_API int mdbx_env_get_path(const MDBX_env *env, const char **dest);
* \ingroup c_statinfo * \ingroup c_statinfo
* *
* \note All MDBX file descriptors have `FD_CLOEXEC` and * \note All MDBX file descriptors have `FD_CLOEXEC` and
* could't be used after exec() and or `fork()`. * couldn't be used after exec() and or `fork()`.
* *
* \param [in] env An environment handle returned by \ref mdbx_env_create(). * \param [in] env An environment handle returned by \ref mdbx_env_create().
* \param [out] fd Address of a int to contain the descriptor. * \param [out] fd Address of a int to contain the descriptor.
@ -2216,7 +2218,7 @@ LIBMDBX_API int mdbx_env_get_fd(const MDBX_env *env, mdbx_filehandle_t *fd);
* - In case \ref mdbx_env_info_ex() or legacy \ref mdbx_env_info() was called * - In case \ref mdbx_env_info_ex() or legacy \ref mdbx_env_info() was called
* BEFORE \ref mdbx_env_open(), i.e. for closed environment, then the * BEFORE \ref mdbx_env_open(), i.e. for closed environment, then the
* specified parameters will be used for new database creation, or will be * specified parameters will be used for new database creation, or will be
* appliend during openeing if database exists and no other process using it. * applied during opening if database exists and no other process using it.
* *
* If the database is already exist, opened with \ref MDBX_EXCLUSIVE or not * If the database is already exist, opened with \ref MDBX_EXCLUSIVE or not
* used by any other process, and parameters specified by * used by any other process, and parameters specified by
@ -2231,7 +2233,7 @@ LIBMDBX_API int mdbx_env_get_fd(const MDBX_env *env, mdbx_filehandle_t *fd);
* *
* - In case \ref mdbx_env_info_ex() or legacy \ref mdbx_env_info() was called * - In case \ref mdbx_env_info_ex() or legacy \ref mdbx_env_info() was called
* after \ref mdbx_env_open() WITHIN the write transaction running by current * after \ref mdbx_env_open() WITHIN the write transaction running by current
* thread, then specified parameters will be appliad as a part of write * thread, then specified parameters will be applied as a part of write
* transaction, i.e. will not be visible to any others processes until the * transaction, i.e. will not be visible to any others processes until the
* current write transaction has been committed by the current process. * current write transaction has been committed by the current process.
* However, if transaction will be aborted, then the database file will be * However, if transaction will be aborted, then the database file will be
@ -2242,7 +2244,7 @@ LIBMDBX_API int mdbx_env_get_fd(const MDBX_env *env, mdbx_filehandle_t *fd);
* after \ref mdbx_env_open() but OUTSIDE a write transaction, then MDBX will * after \ref mdbx_env_open() but OUTSIDE a write transaction, then MDBX will
* execute internal pseudo-transaction to apply new parameters (but only if * execute internal pseudo-transaction to apply new parameters (but only if
* anything has been changed), and changes be visible to any others processes * anything has been changed), and changes be visible to any others processes
* immediatelly after succesfull competeion of function. * immediately after succesful completion of function.
* *
* Essentially a concept of "automatic size management" is simple and useful: * Essentially a concept of "automatic size management" is simple and useful:
* - There are the lower and upper bound of the database file size; * - There are the lower and upper bound of the database file size;
@ -2635,7 +2637,7 @@ struct MDBX_txn_info {
/** For READ-ONLY transaction: the lag from a recent MVCC-snapshot, i.e. the /** For READ-ONLY transaction: the lag from a recent MVCC-snapshot, i.e. the
number of committed transaction since read transaction started. For WRITE number of committed transaction since read transaction started. For WRITE
transaction (provided if `scan_rlt=true`): the lag of the oldest reader transaction (provided if `scan_rlt=true`): the lag of the oldest reader
from current transaction (i.e. atleast 1 if any reader running). */ from current transaction (i.e. at least 1 if any reader running). */
uint64_t txn_reader_lag; uint64_t txn_reader_lag;
/** Used space by this transaction, i.e. corresponding to the last used /** Used space by this transaction, i.e. corresponding to the last used
@ -2646,7 +2648,7 @@ struct MDBX_txn_info {
uint64_t txn_space_limit_soft; uint64_t txn_space_limit_soft;
/** Upper bound for size the database file, i.e. the value `size_upper` /** Upper bound for size the database file, i.e. the value `size_upper`
argument of the approriate call of \ref mdbx_env_set_geometry(). */ argument of the appropriate call of \ref mdbx_env_set_geometry(). */
uint64_t txn_space_limit_hard; uint64_t txn_space_limit_hard;
/** For READ-ONLY transaction: The total size of the database pages that were /** For READ-ONLY transaction: The total size of the database pages that were
@ -2750,7 +2752,7 @@ mdbx_txn_id(const MDBX_txn *txn);
* be aborted due to previous errors. * be aborted due to previous errors.
* \retval MDBX_PANIC A fatal error occurred earlier * \retval MDBX_PANIC A fatal error occurred earlier
* and the environment must be shut down. * and the environment must be shut down.
* \retval MDBX_BAD_TXN Transaction is already fihished or never began. * \retval MDBX_BAD_TXN Transaction is already finished or never began.
* \retval MDBX_EBADSIGN Transaction object has invalid signature, * \retval MDBX_EBADSIGN Transaction object has invalid signature,
* e.g. transaction was already terminated * e.g. transaction was already terminated
* or memory was corrupted. * or memory was corrupted.
@ -2788,7 +2790,7 @@ LIBMDBX_API int mdbx_txn_commit(MDBX_txn *txn);
* some possible errors are: * some possible errors are:
* \retval MDBX_PANIC A fatal error occurred earlier and * \retval MDBX_PANIC A fatal error occurred earlier and
* the environment must be shut down. * the environment must be shut down.
* \retval MDBX_BAD_TXN Transaction is already fihished or never began. * \retval MDBX_BAD_TXN Transaction is already finished or never began.
* \retval MDBX_EBADSIGN Transaction object has invalid signature, * \retval MDBX_EBADSIGN Transaction object has invalid signature,
* e.g. transaction was already terminated * e.g. transaction was already terminated
* or memory was corrupted. * or memory was corrupted.
@ -2835,7 +2837,7 @@ LIBMDBX_API int mdbx_txn_break(MDBX_txn *txn);
* some possible errors are: * some possible errors are:
* \retval MDBX_PANIC A fatal error occurred earlier and * \retval MDBX_PANIC A fatal error occurred earlier and
* the environment must be shut down. * the environment must be shut down.
* \retval MDBX_BAD_TXN Transaction is already fihished or never began. * \retval MDBX_BAD_TXN Transaction is already finished or never began.
* \retval MDBX_EBADSIGN Transaction object has invalid signature, * \retval MDBX_EBADSIGN Transaction object has invalid signature,
* e.g. transaction was already terminated * e.g. transaction was already terminated
* or memory was corrupted. * or memory was corrupted.
@ -2857,7 +2859,7 @@ LIBMDBX_API int mdbx_txn_reset(MDBX_txn *txn);
* some possible errors are: * some possible errors are:
* \retval MDBX_PANIC A fatal error occurred earlier and * \retval MDBX_PANIC A fatal error occurred earlier and
* the environment must be shut down. * the environment must be shut down.
* \retval MDBX_BAD_TXN Transaction is already fihished or never began. * \retval MDBX_BAD_TXN Transaction is already finished or never began.
* \retval MDBX_EBADSIGN Transaction object has invalid signature, * \retval MDBX_EBADSIGN Transaction object has invalid signature,
* e.g. transaction was already terminated * e.g. transaction was already terminated
* or memory was corrupted. * or memory was corrupted.
@ -3230,7 +3232,8 @@ LIBMDBX_API int mdbx_get(MDBX_txn *txn, MDBX_dbi dbi, const MDBX_val *key,
MDBX_val *data); MDBX_val *data);
/** \brief Get items from a database /** \brief Get items from a database
* and optionaly number of data items for a given key. * and optionally number of data items for a given key.
*
* \ingroup c_crud * \ingroup c_crud
* *
* Briefly this function does the same as \ref mdbx_get() with a few * Briefly this function does the same as \ref mdbx_get() with a few
@ -4010,7 +4013,7 @@ mdbx_get_datacmp(MDBX_db_flags_t flags);
* starting from 1. * starting from 1.
* \param [in] slot The reader lock table slot number. * \param [in] slot The reader lock table slot number.
* \param [in] txnid The ID of the transaction being read, * \param [in] txnid The ID of the transaction being read,
* i.e. the MVCC-snaphot number. * i.e. the MVCC-snapshot number.
* \param [in] lag The lag from a recent MVCC-snapshot, * \param [in] lag The lag from a recent MVCC-snapshot,
* i.e. the number of committed write transactions * i.e. the number of committed write transactions
* since the current read transaction started. * since the current read transaction started.
@ -4032,7 +4035,8 @@ typedef int(MDBX_reader_list_func)(void *ctx, int num, int slot, mdbx_pid_t pid,
uint64_t lag, size_t bytes_used, uint64_t lag, size_t bytes_used,
size_t bytes_retained) MDBX_CXX17_NOEXCEPT; size_t bytes_retained) MDBX_CXX17_NOEXCEPT;
/** \brief Enumarete the entries in the reader lock table. /** \brief Enumerate the entries in the reader lock table.
*
* \ingroup c_statinfo * \ingroup c_statinfo
* *
* \param [in] env An environment handle returned by \ref mdbx_env_create(). * \param [in] env An environment handle returned by \ref mdbx_env_create().
@ -4102,7 +4106,7 @@ LIBMDBX_API int mdbx_thread_register(const MDBX_env *env);
* \param [in] env An environment handle returned by \ref mdbx_env_create(). * \param [in] env An environment handle returned by \ref mdbx_env_create().
* *
* \returns A non-zero error value on failure and 0 on success, or * \returns A non-zero error value on failure and 0 on success, or
* \ref MDBX_RESULT_TRUE if thread is not registered or already undegistered. */ * \ref MDBX_RESULT_TRUE if thread is not registered or already unregistered. */
LIBMDBX_API int mdbx_thread_unregister(const MDBX_env *env); LIBMDBX_API int mdbx_thread_unregister(const MDBX_env *env);
/** \brief A lack-of-space callback function to resolve issues with a laggard /** \brief A lack-of-space callback function to resolve issues with a laggard

View File

@ -319,7 +319,7 @@ node_largedata_pgno(const MDBX_node *const __restrict node) {
* leaf-page, since dupsort value couldn't be placed on a large/overflow * leaf-page, since dupsort value couldn't be placed on a large/overflow
* page. * page.
* *
* - So, the simpliest solution is to use half of branch.maxkey as * - So, the simplest solution is to use half of branch.maxkey as
* a common maxkey value. Nevertheless, the actual values of maxkey are: * a common maxkey value. Nevertheless, the actual values of maxkey are:
* nondupsort.maxkey = even_floor(pageroom / 3) * nondupsort.maxkey = even_floor(pageroom / 3)
* - sizeof(indx_t) - node_hdr_len; * - sizeof(indx_t) - node_hdr_len;
@ -415,7 +415,8 @@ MDBX_NOTHROW_PURE_FUNCTION static __always_inline size_t
leaf_size(const MDBX_env *env, const MDBX_val *key, const MDBX_val *data) { leaf_size(const MDBX_env *env, const MDBX_val *key, const MDBX_val *data) {
size_t node_bytes = node_size(key, data); size_t node_bytes = node_size(key, data);
/* NOTE: The actual limit is LEAF_NODEMAX(env->me_psize), but it reasonable to /* NOTE: The actual limit is LEAF_NODEMAX(env->me_psize), but it reasonable to
* use env->me_branch_nodemax (which is 3 times less) as the treshold because: * use env->me_branch_nodemax (which is 3 times less) as the threshold
* because:
* - Large threshold implies that any insertion/update could result split * - Large threshold implies that any insertion/update could result split
* a single leaf page to THREE, which requires TWO insertion into parent * a single leaf page to THREE, which requires TWO insertion into parent
* branch page, then could leads to split parent page and so on up to * branch page, then could leads to split parent page and so on up to
@ -1016,7 +1017,7 @@ static void __cold workaround_glibc_bug21031(void) {
/* Workaround for https://sourceware.org/bugzilla/show_bug.cgi?id=21031 /* Workaround for https://sourceware.org/bugzilla/show_bug.cgi?id=21031
* *
* Due race between pthread_key_delete() and __nptl_deallocate_tsd() * Due race between pthread_key_delete() and __nptl_deallocate_tsd()
* The destructor(s) of thread-local-storate object(s) may be running * The destructor(s) of thread-local-storage object(s) may be running
* in another thread(s) and be blocked or not finished yet. * in another thread(s) and be blocked or not finished yet.
* In such case we get a SEGFAULT after unload this library DSO. * In such case we get a SEGFAULT after unload this library DSO.
* *
@ -1084,11 +1085,11 @@ static void thread_rthc_set(mdbx_thread_key_t key, const void *value) {
mdbx_ensure(nullptr, TlsSetValue(key, (void *)value)); mdbx_ensure(nullptr, TlsSetValue(key, (void *)value));
#else #else
#define MDBX_THREAD_RTHC_ZERO 0 #define MDBX_THREAD_RTHC_ZERO 0
#define MDBX_THREAD_RTHC_REGISTERD 1 #define MDBX_THREAD_RTHC_REGISTERED 1
#define MDBX_THREAD_RTHC_COUNTED 2 #define MDBX_THREAD_RTHC_COUNTED 2
static __thread uint32_t thread_registration_state; static __thread uint32_t thread_registration_state;
if (value && unlikely(thread_registration_state == MDBX_THREAD_RTHC_ZERO)) { if (value && unlikely(thread_registration_state == MDBX_THREAD_RTHC_ZERO)) {
thread_registration_state = MDBX_THREAD_RTHC_REGISTERD; thread_registration_state = MDBX_THREAD_RTHC_REGISTERED;
mdbx_trace("thread registered 0x%" PRIxPTR, mdbx_thread_self()); mdbx_trace("thread registered 0x%" PRIxPTR, mdbx_thread_self());
if (&__cxa_thread_atexit_impl == nullptr || if (&__cxa_thread_atexit_impl == nullptr ||
__cxa_thread_atexit_impl(mdbx_rthc_thread_dtor, __cxa_thread_atexit_impl(mdbx_rthc_thread_dtor,
@ -4315,10 +4316,10 @@ static __always_inline bool meta_bootid_match(const MDBX_meta *meta) {
} }
static bool meta_weak_acceptable(const MDBX_env *env, const MDBX_meta *meta, static bool meta_weak_acceptable(const MDBX_env *env, const MDBX_meta *meta,
const int lck_exlusive) { const int lck_exclusive) {
return lck_exlusive ? /* exclusive lock */ meta_bootid_match(meta) return lck_exclusive ? /* exclusive lock */ meta_bootid_match(meta)
: /* db already opened */ env->me_lck && : /* db already opened */ env->me_lck &&
(env->me_lck->mti_envmode & MDBX_RDONLY) == 0; (env->me_lck->mti_envmode & MDBX_RDONLY) == 0;
} }
#define METAPAGE(env, n) page_meta(pgno2page(env, n)) #define METAPAGE(env, n) page_meta(pgno2page(env, n))
@ -4731,7 +4732,7 @@ static __cold int mdbx_mapresize(MDBX_env *env, const pgno_t used_pgno,
goto bailout; goto bailout;
/* 1) Windows allows only extending a read-write section, but not a /* 1) Windows allows only extending a read-write section, but not a
* corresponing mapped view. Therefore in other cases we must suspend * corresponding mapped view. Therefore in other cases we must suspend
* the local threads for safe remap. * the local threads for safe remap.
* 2) At least on Windows 10 1803 the entire mapped section is unavailable * 2) At least on Windows 10 1803 the entire mapped section is unavailable
* for short time during NtExtendSection() or VirtualAlloc() execution. * for short time during NtExtendSection() or VirtualAlloc() execution.
@ -5348,7 +5349,7 @@ skip_cache:
((autosync_threshold | autosync_period) == 0 || ((autosync_threshold | autosync_period) == 0 ||
next >= steady->mm_geo.now)) { next >= steady->mm_geo.now)) {
/* wipe steady checkpoint in MDBX_UTTERLY_NOSYNC mode /* wipe steady checkpoint in MDBX_UTTERLY_NOSYNC mode
* without any auto-sync treshold(s). */ * without any auto-sync threshold(s). */
rc = mdbx_wipe_steady(env, oldest); rc = mdbx_wipe_steady(env, oldest);
mdbx_debug("gc-wipe-steady, rc %d", rc); mdbx_debug("gc-wipe-steady, rc %d", rc);
mdbx_assert(env, steady != mdbx_meta_steady(env)); mdbx_assert(env, steady != mdbx_meta_steady(env));
@ -6523,7 +6524,7 @@ int mdbx_txn_begin(MDBX_env *env, MDBX_txn *parent, MDBX_txn_flags_t flags,
MDBX_PNL_SIZEOF(parent->tw.reclaimed_pglist)); MDBX_PNL_SIZEOF(parent->tw.reclaimed_pglist));
mdbx_assert(env, mdbx_pnl_check4assert( mdbx_assert(env, mdbx_pnl_check4assert(
txn->tw.reclaimed_pglist, txn->tw.reclaimed_pglist,
(txn->mt_next_pgno /* LY: intentional assigment here, (txn->mt_next_pgno /* LY: intentional assignment here,
only for assertion */ only for assertion */
= parent->mt_next_pgno))); = parent->mt_next_pgno)));
@ -7394,7 +7395,7 @@ retry_noaccount:
continue; continue;
} }
/* handle reclaimed and loost pages - merge and store both into gc */ /* handle reclaimed and lost pages - merge and store both into gc */
mdbx_tassert(txn, mdbx_pnl_check4assert(txn->tw.reclaimed_pglist, mdbx_tassert(txn, mdbx_pnl_check4assert(txn->tw.reclaimed_pglist,
txn->mt_next_pgno)); txn->mt_next_pgno));
mdbx_tassert(txn, txn->tw.loose_count == 0); mdbx_tassert(txn, txn->tw.loose_count == 0);
@ -8685,7 +8686,7 @@ static MDBX_page *__cold mdbx_meta_model(const MDBX_env *env, MDBX_page *model,
} }
/* Fill in most of the zeroed meta-pages for an empty database environment. /* Fill in most of the zeroed meta-pages for an empty database environment.
* Return pointer to recenly (head) meta-page. */ * Return pointer to recently (head) meta-page. */
static MDBX_meta *__cold mdbx_init_metas(const MDBX_env *env, void *buffer) { static MDBX_meta *__cold mdbx_init_metas(const MDBX_env *env, void *buffer) {
MDBX_page *page0 = (MDBX_page *)buffer; MDBX_page *page0 = (MDBX_page *)buffer;
MDBX_page *page1 = mdbx_meta_model(env, page0, 0); MDBX_page *page1 = mdbx_meta_model(env, page0, 0);
@ -8742,20 +8743,20 @@ static int mdbx_sync_locked(MDBX_env *env, unsigned flags,
#if defined(MADV_DONTNEED) #if defined(MADV_DONTNEED)
const size_t largest_bytes = pgno2bytes(env, largest_pgno); const size_t largest_bytes = pgno2bytes(env, largest_pgno);
/* threshold to avoid unreasonable frequent madvise() calls */ /* threshold to avoid unreasonable frequent madvise() calls */
const size_t madvise_treshold = (largest_bytes < 65536 * 256) const size_t madvise_threshold = (largest_bytes < 65536 * 256)
? 65536 ? 65536
: (largest_bytes > MEGABYTE * 4 * 256) : (largest_bytes > MEGABYTE * 4 * 256)
? MEGABYTE * 4 ? MEGABYTE * 4
: largest_bytes >> 10; : largest_bytes >> 10;
const size_t discard_edge_bytes = bytes_align2os_bytes( const size_t discard_edge_bytes = bytes_align2os_bytes(
env, ((MDBX_RDONLY & env, ((MDBX_RDONLY &
(env->me_lck ? env->me_lck->mti_envmode : env->me_flags)) (env->me_lck ? env->me_lck->mti_envmode : env->me_flags))
? largest_bytes ? largest_bytes
: largest_bytes + madvise_treshold)); : largest_bytes + madvise_threshold));
const pgno_t discard_edge_pgno = bytes2pgno(env, discard_edge_bytes); const pgno_t discard_edge_pgno = bytes2pgno(env, discard_edge_bytes);
const pgno_t prev_discarded_pgno = *env->me_discarded_tail; const pgno_t prev_discarded_pgno = *env->me_discarded_tail;
if (prev_discarded_pgno >= if (prev_discarded_pgno >=
discard_edge_pgno + bytes2pgno(env, madvise_treshold)) { discard_edge_pgno + bytes2pgno(env, madvise_threshold)) {
mdbx_notice("open-MADV_%s %u..%u", "DONTNEED", *env->me_discarded_tail, mdbx_notice("open-MADV_%s %u..%u", "DONTNEED", *env->me_discarded_tail,
largest_pgno); largest_pgno);
*env->me_discarded_tail = discard_edge_pgno; *env->me_discarded_tail = discard_edge_pgno;
@ -9806,7 +9807,7 @@ static int __cold mdbx_setup_dxb(MDBX_env *env, const int lck_rc) {
} }
if (!env->me_lck) { if (!env->me_lck) {
/* LY: without-lck (read-only) mode, so it is imposible that other /* LY: without-lck (read-only) mode, so it is impossible that other
* process made weak checkpoint. */ * process made weak checkpoint. */
mdbx_error("%s", "without-lck, unable recovery/rollback"); mdbx_error("%s", "without-lck, unable recovery/rollback");
return MDBX_WANNA_RECOVERY; return MDBX_WANNA_RECOVERY;
@ -10077,7 +10078,7 @@ static int __cold mdbx_setup_lck(MDBX_env *env, char *lck_pathname,
struct MDBX_lockinfo *const lck = env->me_lck; struct MDBX_lockinfo *const lck = env->me_lck;
if (lck_seize_rc == MDBX_RESULT_TRUE) { if (lck_seize_rc == MDBX_RESULT_TRUE) {
/* LY: exlcusive mode, check and reset lck content */ /* LY: exclusive mode, check and reset lck content */
memset(lck, 0, (size_t)size); memset(lck, 0, (size_t)size);
mdbx_jitter4testing(false); mdbx_jitter4testing(false);
lck->mti_magic_and_version = MDBX_LOCK_MAGIC; lck->mti_magic_and_version = MDBX_LOCK_MAGIC;
@ -10608,7 +10609,7 @@ __cold int mdbx_env_open(MDBX_env *env, const char *pathname,
sizeof(unsigned) + 1); sizeof(unsigned) + 1);
rc = mdbx_memalign_alloc( rc = mdbx_memalign_alloc(
env->me_os_psize, env->me_os_psize,
env->me_psize * (1 /* page buffer */ + 1 /* page killer bufer */), env->me_psize * (1 /* page buffer */ + 1 /* page killer buffer */),
&env->me_pbuf); &env->me_pbuf);
if (rc == MDBX_SUCCESS) { if (rc == MDBX_SUCCESS) {
memset(env->me_pbuf, -1, env->me_psize * 2); memset(env->me_pbuf, -1, env->me_psize * 2);
@ -16227,7 +16228,7 @@ static int __cold mdbx_env_compact(MDBX_env *env, MDBX_txn *read_txn,
if (flags & MDBX_CP_FORCE_DYNAMIC_SIZE) if (flags & MDBX_CP_FORCE_DYNAMIC_SIZE)
make_sizeable(meta); make_sizeable(meta);
/* copy canary sequenses if present */ /* copy canary sequences if present */
if (read_txn->mt_canary.v) { if (read_txn->mt_canary.v) {
meta->mm_canary = read_txn->mt_canary; meta->mm_canary = read_txn->mt_canary;
meta->mm_canary.v = mdbx_meta_txnid_stable(env, meta); meta->mm_canary.v = mdbx_meta_txnid_stable(env, meta);
@ -16341,7 +16342,7 @@ static int __cold mdbx_env_compact(MDBX_env *env, MDBX_txn *read_txn,
for (size_t offset = used_size; offset < whole_size;) { for (size_t offset = used_size; offset < whole_size;) {
const size_t chunk = const size_t chunk =
(MDBX_WBUF < whole_size - offset) ? MDBX_WBUF : whole_size - offset; (MDBX_WBUF < whole_size - offset) ? MDBX_WBUF : whole_size - offset;
/* copy to avoit EFAULT in case swapped-out */ /* copy to avoid EFAULT in case swapped-out */
int rc = mdbx_write(fd, data_buffer, chunk); int rc = mdbx_write(fd, data_buffer, chunk);
if (unlikely(rc != MDBX_SUCCESS)) if (unlikely(rc != MDBX_SUCCESS))
return rc; return rc;
@ -16376,7 +16377,7 @@ static int __cold mdbx_env_copy_asis(MDBX_env *env, MDBX_txn *read_txn,
/* Make a snapshot of meta-pages, /* Make a snapshot of meta-pages,
* but writing ones after the data was flushed */ * but writing ones after the data was flushed */
memcpy(buffer, env->me_map, meta_bytes); memcpy(buffer, env->me_map, meta_bytes);
MDBX_meta *const headcopy = /* LY: get pointer to the spanshot copy */ MDBX_meta *const headcopy = /* LY: get pointer to the snapshot copy */
(MDBX_meta *)(buffer + ((uint8_t *)mdbx_meta_head(env) - env->me_map)); (MDBX_meta *)(buffer + ((uint8_t *)mdbx_meta_head(env) - env->me_map));
mdbx_txn_unlock(env); mdbx_txn_unlock(env);
@ -16433,7 +16434,7 @@ static int __cold mdbx_env_copy_asis(MDBX_env *env, MDBX_txn *read_txn,
/* fallback to portable */ /* fallback to portable */
const size_t chunk = const size_t chunk =
(MDBX_WBUF < used_size - offset) ? MDBX_WBUF : used_size - offset; (MDBX_WBUF < used_size - offset) ? MDBX_WBUF : used_size - offset;
/* copy to avoit EFAULT in case swapped-out */ /* copy to avoid EFAULT in case swapped-out */
memcpy(data_buffer, env->me_map + offset, chunk); memcpy(data_buffer, env->me_map + offset, chunk);
rc = mdbx_write(fd, data_buffer, chunk); rc = mdbx_write(fd, data_buffer, chunk);
offset += chunk; offset += chunk;
@ -16449,7 +16450,7 @@ static int __cold mdbx_env_copy_asis(MDBX_env *env, MDBX_txn *read_txn,
rc == MDBX_SUCCESS && offset < whole_size;) { rc == MDBX_SUCCESS && offset < whole_size;) {
const size_t chunk = const size_t chunk =
(MDBX_WBUF < whole_size - offset) ? MDBX_WBUF : whole_size - offset; (MDBX_WBUF < whole_size - offset) ? MDBX_WBUF : whole_size - offset;
/* copy to avoit EFAULT in case swapped-out */ /* copy to avoid EFAULT in case swapped-out */
rc = mdbx_write(fd, data_buffer, chunk); rc = mdbx_write(fd, data_buffer, chunk);
offset += chunk; offset += chunk;
} }

View File

@ -84,7 +84,7 @@
#pragma warning(disable : 4127) /* conditional expression is constant */ #pragma warning(disable : 4127) /* conditional expression is constant */
#pragma warning(disable : 4324) /* 'xyz': structure was padded due to alignment specifier */ #pragma warning(disable : 4324) /* 'xyz': structure was padded due to alignment specifier */
#pragma warning(disable : 4310) /* cast truncates constant value */ #pragma warning(disable : 4310) /* cast truncates constant value */
#pragma warning(disable : 4820) /* bytes padding added after data member for aligment */ #pragma warning(disable : 4820) /* bytes padding added after data member for alignment */
#pragma warning(disable : 4548) /* expression before comma has no effect; expected expression with side - effect */ #pragma warning(disable : 4548) /* expression before comma has no effect; expected expression with side - effect */
#pragma warning(disable : 4366) /* the result of the unary '&' operator may be unaligned */ #pragma warning(disable : 4366) /* the result of the unary '&' operator may be unaligned */
#pragma warning(disable : 4200) /* nonstandard extension used: zero-sized array in struct/union */ #pragma warning(disable : 4200) /* nonstandard extension used: zero-sized array in struct/union */
@ -101,7 +101,7 @@
#include "defs.h" #include "defs.h"
#if defined(__GNUC__) && !__GNUC_PREREQ(4,2) #if defined(__GNUC__) && !__GNUC_PREREQ(4,2)
/* Actualy libmdbx was not tested with compilers older than GCC from RHEL6. /* Actually libmdbx was not tested with compilers older than GCC from RHEL6.
* But you could remove this #error and try to continue at your own risk. * But you could remove this #error and try to continue at your own risk.
* In such case please don't rise up an issues related ONLY to old compilers. * In such case please don't rise up an issues related ONLY to old compilers.
*/ */
@ -109,7 +109,7 @@
#endif #endif
#if defined(__clang__) && !__CLANG_PREREQ(3,8) #if defined(__clang__) && !__CLANG_PREREQ(3,8)
/* Actualy libmdbx was not tested with CLANG older than 3.8. /* Actually libmdbx was not tested with CLANG older than 3.8.
* But you could remove this #error and try to continue at your own risk. * But you could remove this #error and try to continue at your own risk.
* In such case please don't rise up an issues related ONLY to old compilers. * In such case please don't rise up an issues related ONLY to old compilers.
*/ */
@ -117,7 +117,7 @@
#endif #endif
#if defined(__GLIBC__) && !__GLIBC_PREREQ(2,12) #if defined(__GLIBC__) && !__GLIBC_PREREQ(2,12)
/* Actualy libmdbx was not tested with something older than glibc 2.12 (from RHEL6). /* Actually libmdbx was not tested with something older than glibc 2.12 (from RHEL6).
* But you could remove this #error and try to continue at your own risk. * But you could remove this #error and try to continue at your own risk.
* In such case please don't rise up an issues related ONLY to old systems. * In such case please don't rise up an issues related ONLY to old systems.
*/ */
@ -536,7 +536,7 @@ typedef struct MDBX_lockinfo {
alignas(MDBX_CACHELINE_SIZE) /* cacheline ---------------------------------*/ alignas(MDBX_CACHELINE_SIZE) /* cacheline ---------------------------------*/
/* Write transation lock. */ /* Write transaction lock. */
#if MDBX_LOCKING > 0 #if MDBX_LOCKING > 0
mdbx_ipclock_t mti_wlock; mdbx_ipclock_t mti_wlock;
#endif /* MDBX_LOCKING > 0 */ #endif /* MDBX_LOCKING > 0 */
@ -884,7 +884,7 @@ struct MDBX_cursor {
#define C_RECLAIMING 0x20 /* GC lookup is prohibited */ #define C_RECLAIMING 0x20 /* GC lookup is prohibited */
#define C_GCFREEZE 0x40 /* reclaimed_pglist must not be updated */ #define C_GCFREEZE 0x40 /* reclaimed_pglist must not be updated */
/* Cursor checing flags. */ /* Cursor checking flags. */
#define C_COPYING 0x100 /* skip key-value length check (copying simplify) */ #define C_COPYING 0x100 /* skip key-value length check (copying simplify) */
#define C_UPDATING 0x200 /* update/rebalance pending */ #define C_UPDATING 0x200 /* update/rebalance pending */
#define C_RETIRING 0x400 /* refs to child pages may be invalid */ #define C_RETIRING 0x400 /* refs to child pages may be invalid */

View File

@ -183,7 +183,8 @@ MDBX_INTERNAL_FUNC int mdbx_rdt_lock(MDBX_env *env) {
if (env->me_lfd == INVALID_HANDLE_VALUE) if (env->me_lfd == INVALID_HANDLE_VALUE)
return MDBX_SUCCESS; /* readonly database in readonly filesystem */ return MDBX_SUCCESS; /* readonly database in readonly filesystem */
/* transite from S-? (used) to S-E (locked), e.g. exclusive lock upper-part */ /* transition from S-? (used) to S-E (locked),
* e.g. exclusive lock upper-part */
if ((env->me_flags & MDBX_EXCLUSIVE) || if ((env->me_flags & MDBX_EXCLUSIVE) ||
flock(env->me_lfd, LCK_EXCLUSIVE | LCK_WAITFOR, LCK_UPPER)) flock(env->me_lfd, LCK_EXCLUSIVE | LCK_WAITFOR, LCK_UPPER))
return MDBX_SUCCESS; return MDBX_SUCCESS;
@ -195,7 +196,7 @@ MDBX_INTERNAL_FUNC int mdbx_rdt_lock(MDBX_env *env) {
MDBX_INTERNAL_FUNC void mdbx_rdt_unlock(MDBX_env *env) { MDBX_INTERNAL_FUNC void mdbx_rdt_unlock(MDBX_env *env) {
if (env->me_lfd != INVALID_HANDLE_VALUE) { if (env->me_lfd != INVALID_HANDLE_VALUE) {
/* transite from S-E (locked) to S-? (used), e.g. unlock upper-part */ /* transition from S-E (locked) to S-? (used), e.g. unlock upper-part */
if ((env->me_flags & MDBX_EXCLUSIVE) == 0 && if ((env->me_flags & MDBX_EXCLUSIVE) == 0 &&
!funlock(env->me_lfd, LCK_UPPER)) !funlock(env->me_lfd, LCK_UPPER))
mdbx_panic("%s failed: err %u", __func__, GetLastError()); mdbx_panic("%s failed: err %u", __func__, GetLastError());
@ -277,7 +278,7 @@ mdbx_suspend_threads_before_remap(MDBX_env *env, mdbx_handle_array_t **array) {
} }
} else { } else {
/* Without LCK (i.e. read-only mode). /* Without LCK (i.e. read-only mode).
* Walk thougth a snapshot of all running threads */ * Walk through a snapshot of all running threads */
mdbx_assert(env, mdbx_assert(env,
env->me_txn0 == NULL || (env->me_flags & MDBX_EXCLUSIVE) != 0); env->me_txn0 == NULL || (env->me_flags & MDBX_EXCLUSIVE) != 0);
const HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0); const HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
@ -336,7 +337,7 @@ mdbx_resume_threads_after_remap(mdbx_handle_array_t *array) {
/* global `initial` lock for lockfile initialization, /* global `initial` lock for lockfile initialization,
* exclusive/shared locking first cacheline */ * exclusive/shared locking first cacheline */
/* Briefly descritpion of locking schema/algorithm: /* Briefly description of locking schema/algorithm:
* - Windows does not support upgrading or downgrading for file locking. * - Windows does not support upgrading or downgrading for file locking.
* - Therefore upgrading/downgrading is emulated by shared and exclusive * - Therefore upgrading/downgrading is emulated by shared and exclusive
* locking of upper and lower halves. * locking of upper and lower halves.
@ -411,7 +412,7 @@ static void lck_unlock(MDBX_env *env) {
/* Seize state as 'exclusive-write' (E-E and returns MDBX_RESULT_TRUE) /* Seize state as 'exclusive-write' (E-E and returns MDBX_RESULT_TRUE)
* or as 'used' (S-? and returns MDBX_RESULT_FALSE). * or as 'used' (S-? and returns MDBX_RESULT_FALSE).
* Oherwise returns an error. */ * Otherwise returns an error. */
static int internal_seize_lck(HANDLE lfd) { static int internal_seize_lck(HANDLE lfd) {
int rc; int rc;
assert(lfd != INVALID_HANDLE_VALUE); assert(lfd != INVALID_HANDLE_VALUE);
@ -450,7 +451,7 @@ static int internal_seize_lck(HANDLE lfd) {
mdbx_error("%s, err %u", "?-E(middle) >> S-E(locked)", rc); mdbx_error("%s, err %u", "?-E(middle) >> S-E(locked)", rc);
/* 8) now on S-E (locked) or still on ?-E (middle), /* 8) now on S-E (locked) or still on ?-E (middle),
* transite to S-? (used) or ?-? (free) */ * transition to S-? (used) or ?-? (free) */
if (!funlock(lfd, LCK_UPPER)) if (!funlock(lfd, LCK_UPPER))
mdbx_panic("%s(%s) failed: err %u", __func__, mdbx_panic("%s(%s) failed: err %u", __func__,
"X-E(locked/middle) >> X-?(used/free)", GetLastError()); "X-E(locked/middle) >> X-?(used/free)", GetLastError());
@ -512,12 +513,12 @@ MDBX_INTERNAL_FUNC int mdbx_lck_downgrade(MDBX_env *env) {
if (env->me_flags & MDBX_EXCLUSIVE) if (env->me_flags & MDBX_EXCLUSIVE)
return MDBX_SUCCESS /* nope since files were must be opened non-shareable */ return MDBX_SUCCESS /* nope since files were must be opened non-shareable */
; ;
/* 1) now at E-E (exclusive-write), transite to ?_E (middle) */ /* 1) now at E-E (exclusive-write), transition to ?_E (middle) */
if (!funlock(env->me_lfd, LCK_LOWER)) if (!funlock(env->me_lfd, LCK_LOWER))
mdbx_panic("%s(%s) failed: err %u", __func__, mdbx_panic("%s(%s) failed: err %u", __func__,
"E-E(exclusive-write) >> ?-E(middle)", GetLastError()); "E-E(exclusive-write) >> ?-E(middle)", GetLastError());
/* 2) now at ?-E (middle), transite to S-E (locked) */ /* 2) now at ?-E (middle), transition to S-E (locked) */
if (!flock(env->me_lfd, LCK_SHARED | LCK_DONTWAIT, LCK_LOWER)) { if (!flock(env->me_lfd, LCK_SHARED | LCK_DONTWAIT, LCK_LOWER)) {
int rc = GetLastError() /* 3) something went wrong, give up */; int rc = GetLastError() /* 3) something went wrong, give up */;
mdbx_error("%s, err %u", "?-E(middle) >> S-E(locked)", rc); mdbx_error("%s, err %u", "?-E(middle) >> S-E(locked)", rc);
@ -549,7 +550,7 @@ MDBX_INTERNAL_FUNC int mdbx_lck_upgrade(MDBX_env *env) {
return rc; return rc;
} }
/* 3) now on S-E (locked), transite to ?-E (middle) */ /* 3) now on S-E (locked), transition to ?-E (middle) */
if (!funlock(env->me_lfd, LCK_LOWER)) if (!funlock(env->me_lfd, LCK_LOWER))
mdbx_panic("%s(%s) failed: err %u", __func__, "S-E(locked) >> ?-E(middle)", mdbx_panic("%s(%s) failed: err %u", __func__, "S-E(locked) >> ?-E(middle)",
GetLastError()); GetLastError());
@ -666,7 +667,7 @@ static void WINAPI stub_srwlock_AcquireShared(MDBX_srwlock *srwl) {
// Add to the readers list // Add to the readers list
_InterlockedIncrement(&srwl->readerCount); _InterlockedIncrement(&srwl->readerCount);
// Check for writers again (we may have been pre-empted). If // Check for writers again (we may have been preempted). If
// there are no writers writing or waiting, then we're done. // there are no writers writing or waiting, then we're done.
if (srwl->writerCount == 0) if (srwl->writerCount == 0)
break; break;

View File

@ -478,7 +478,7 @@ static int handle_freedb(const uint64_t record_number, const MDBX_val *key,
(number + 1) * sizeof(pgno_t), data->iov_len); (number + 1) * sizeof(pgno_t), data->iov_len);
number = data->iov_len / sizeof(pgno_t) - 1; number = data->iov_len / sizeof(pgno_t) - 1;
} else if (data->iov_len - (number + 1) * sizeof(pgno_t) >= } else if (data->iov_len - (number + 1) * sizeof(pgno_t) >=
/* LY: allow gap upto one page. it is ok /* LY: allow gap up to one page. it is ok
* and better than shink-and-retry inside mdbx_update_gc() */ * and better than shink-and-retry inside mdbx_update_gc() */
envstat.ms_psize) envstat.ms_psize)
problem_add("entry", txnid, "extra idl space", problem_add("entry", txnid, "extra idl space",
@ -1318,7 +1318,7 @@ int main(int argc, char *argv[]) {
alloc_pages = backed_pages; alloc_pages = backed_pages;
} }
} else { } else {
/* LY: DB may be shrinked by writer downto the allocated pages. */ /* LY: DB may be shrinked by writer down to the allocated pages. */
if (alloc_pages > backed_pages) { if (alloc_pages > backed_pages) {
print(" ! alloc-pages %" PRIu64 " > backed-pages %" PRIu64 "\n", print(" ! alloc-pages %" PRIu64 " > backed-pages %" PRIu64 "\n",
alloc_pages, backed_pages); alloc_pages, backed_pages);

View File

@ -224,7 +224,7 @@ static void usage(void) {
" -a\t\tdump main DB and all subDBs,\n" " -a\t\tdump main DB and all subDBs,\n"
" \t\tby default dump only the main DB\n" " \t\tby default dump only the main DB\n"
" -s\t\tdump only the named subDB\n" " -s\t\tdump only the named subDB\n"
" -r\t\trescure mode (ignore errors to dump corrupted DB)\n", " -r\t\trescue mode (ignore errors to dump corrupted DB)\n",
prog); prog);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }

View File

@ -459,7 +459,7 @@ static void usage(void) {
" -s name\tload into named subDB\n" " -s name\tload into named subDB\n"
" -N\t\tuse NOOVERWRITE on puts\n" " -N\t\tuse NOOVERWRITE on puts\n"
" -T\t\tread plaintext\n" " -T\t\tread plaintext\n"
" -r\t\trescure mode (ignore errors to load corrupted DB dump)\n", " -r\t\trescue mode (ignore errors to load corrupted DB dump)\n",
prog); prog);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }

View File

@ -60,7 +60,7 @@
/** Controls checking PID against reuse DB environment after the fork() */ /** Controls checking PID against reuse DB environment after the fork() */
#ifndef MDBX_ENV_CHECKPID #ifndef MDBX_ENV_CHECKPID
#if defined(MADV_DONTFORK) || defined(_WIN32) || defined(_WIN64) #if defined(MADV_DONTFORK) || defined(_WIN32) || defined(_WIN64)
/* PID check could be ommited: /* PID check could be omitted:
* - on Linux when madvise(MADV_DONTFORK) is available. i.e. after the fork() * - on Linux when madvise(MADV_DONTFORK) is available. i.e. after the fork()
* mapped pages will not be available for child process. * mapped pages will not be available for child process.
* - in Windows where fork() not available. */ * - in Windows where fork() not available. */

View File

@ -1387,7 +1387,7 @@ MDBX_INTERNAL_FUNC int mdbx_mmap(const int flags, mdbx_mmap_t *map,
MDBX_INTERNAL_FUNC int mdbx_munmap(mdbx_mmap_t *map) { MDBX_INTERNAL_FUNC int mdbx_munmap(mdbx_mmap_t *map) {
VALGRIND_MAKE_MEM_NOACCESS(map->address, map->current); VALGRIND_MAKE_MEM_NOACCESS(map->address, map->current);
/* Unpoisoning is required for ASAN to avoid false-positive diagnostic /* Unpoisoning is required for ASAN to avoid false-positive diagnostic
* when this memory will re-used by malloc or another mmaping. * when this memory will re-used by malloc or another mmapping.
* See https://github.com/erthink/libmdbx/pull/93#issuecomment-613687203 */ * See https://github.com/erthink/libmdbx/pull/93#issuecomment-613687203 */
ASAN_UNPOISON_MEMORY_REGION(map->address, map->limit); ASAN_UNPOISON_MEMORY_REGION(map->address, map->limit);
#if defined(_WIN32) || defined(_WIN64) #if defined(_WIN32) || defined(_WIN64)
@ -1673,7 +1673,7 @@ retry_mapview:;
if (unlikely(ptr == MAP_FAILED)) { if (unlikely(ptr == MAP_FAILED)) {
VALGRIND_MAKE_MEM_NOACCESS(map->address, map->current); VALGRIND_MAKE_MEM_NOACCESS(map->address, map->current);
/* Unpoisoning is required for ASAN to avoid false-positive diagnostic /* Unpoisoning is required for ASAN to avoid false-positive diagnostic
* when this memory will re-used by malloc or another mmaping. * when this memory will re-used by malloc or another mmapping.
* See https://github.com/erthink/libmdbx/pull/93#issuecomment-613687203 * See https://github.com/erthink/libmdbx/pull/93#issuecomment-613687203
*/ */
ASAN_UNPOISON_MEMORY_REGION(map->address, map->limit); ASAN_UNPOISON_MEMORY_REGION(map->address, map->limit);
@ -1691,7 +1691,7 @@ retry_mapview:;
if (map->address != ptr) { if (map->address != ptr) {
VALGRIND_MAKE_MEM_NOACCESS(map->address, map->current); VALGRIND_MAKE_MEM_NOACCESS(map->address, map->current);
/* Unpoisoning is required for ASAN to avoid false-positive diagnostic /* Unpoisoning is required for ASAN to avoid false-positive diagnostic
* when this memory will re-used by malloc or another mmaping. * when this memory will re-used by malloc or another mmapping.
* See https://github.com/erthink/libmdbx/pull/93#issuecomment-613687203 * See https://github.com/erthink/libmdbx/pull/93#issuecomment-613687203
*/ */
ASAN_UNPOISON_MEMORY_REGION(map->address, map->limit); ASAN_UNPOISON_MEMORY_REGION(map->address, map->limit);

View File

@ -741,12 +741,12 @@ MDBX_INTERNAL_FUNC int mdbx_lck_destroy(MDBX_env *env,
MDBX_INTERNAL_FUNC int mdbx_lck_seize(MDBX_env *env); MDBX_INTERNAL_FUNC int mdbx_lck_seize(MDBX_env *env);
/// \brief Downgrades the level of initially acquired lock to /// \brief Downgrades the level of initially acquired lock to
/// operational level specified by agrument. The reson for such downgrade: /// operational level specified by argument. The reson for such downgrade:
/// - unblocking of other processes that are waiting for access, i.e. /// - unblocking of other processes that are waiting for access, i.e.
/// if (env->me_flags & MDBX_EXCLUSIVE) != 0, then other processes /// if (env->me_flags & MDBX_EXCLUSIVE) != 0, then other processes
/// should be made aware that access is unavailable rather than /// should be made aware that access is unavailable rather than
/// wait for it. /// wait for it.
/// - freeing locks that interfere file operation (expecially for Windows) /// - freeing locks that interfere file operation (especially for Windows)
/// (env->me_flags & MDBX_EXCLUSIVE) == 0 - downgrade to shared lock. /// (env->me_flags & MDBX_EXCLUSIVE) == 0 - downgrade to shared lock.
/// (env->me_flags & MDBX_EXCLUSIVE) != 0 - downgrade to exclusive /// (env->me_flags & MDBX_EXCLUSIVE) != 0 - downgrade to exclusive
/// operational lock. /// operational lock.

View File

@ -103,7 +103,7 @@ time now_realtime() {
#endif #endif
} }
time now_motonic() { time now_monotonic() {
#if defined(_WIN32) || defined(_WIN64) || defined(_WINDOWS) #if defined(_WIN32) || defined(_WIN64) || defined(_WINDOWS)
static uint64_t reciprocal; static uint64_t reciprocal;
static LARGE_INTEGER Frequency; static LARGE_INTEGER Frequency;

View File

@ -94,6 +94,6 @@ inline time from_timeval(const struct timeval &tv) {
#endif /* HAVE_TIMEVAL_TV_USEC */ #endif /* HAVE_TIMEVAL_TV_USEC */
time now_realtime(); time now_realtime();
time now_motonic(); time now_monotonic();
} /* namespace chrono */ } /* namespace chrono */

View File

@ -31,7 +31,7 @@ bool parse_option(int argc, char *const argv[], int &narg, const char *option,
if (!value) { if (!value) {
if (current[optlen + 2] == '=') if (current[optlen + 2] == '=')
failure("Option '--%s' doen't accept any value\n", option); failure("Option '--%s' doesn't accept any value\n", option);
return true; return true;
} }
@ -45,7 +45,7 @@ bool parse_option(int argc, char *const argv[], int &narg, const char *option,
*value = argv[narg + 1]; *value = argv[narg + 1];
if (strcmp(*value, "default") == 0) { if (strcmp(*value, "default") == 0) {
if (!default_value) if (!default_value)
failure("Option '--%s' doen't accept default value\n", option); failure("Option '--%s' doesn't accept default value\n", option);
*value = default_value; *value = default_value;
} }
++narg; ++narg;
@ -74,7 +74,7 @@ bool parse_option(int argc, char *const argv[], int &narg, const char *option,
return false; return false;
if (!allow_empty && strlen(value_cstr) == 0) if (!allow_empty && strlen(value_cstr) == 0)
failure("Value for option '--%s' could't be empty\n", option); failure("Value for option '--%s' couldn't be empty\n", option);
value = value_cstr; value = value_cstr;
return true; return true;
@ -157,34 +157,34 @@ bool parse_option(int argc, char *const argv[], int &narg, const char *option,
failure("Option '--%s' expects a numeric value (%s)\n", option, failure("Option '--%s' expects a numeric value (%s)\n", option,
test_strerror(errno)); test_strerror(errno));
uint64_t multipler = 1; uint64_t multiplier = 1;
if (suffix && *suffix) { if (suffix && *suffix) {
if (scale == no_scale) if (scale == no_scale)
failure("Option '--%s' doen't accepts suffixes, so '%s' is unexpected\n", failure("Option '--%s' doesn't accepts suffixes, so '%s' is unexpected\n",
option, suffix); option, suffix);
if (strcmp(suffix, "K") == 0 || strcasecmp(suffix, "Kilo") == 0) if (strcmp(suffix, "K") == 0 || strcasecmp(suffix, "Kilo") == 0)
multipler = (scale == decimal) ? UINT64_C(1000) : UINT64_C(1024); multiplier = (scale == decimal) ? UINT64_C(1000) : UINT64_C(1024);
else if (strcmp(suffix, "M") == 0 || strcasecmp(suffix, "Mega") == 0) else if (strcmp(suffix, "M") == 0 || strcasecmp(suffix, "Mega") == 0)
multipler = multiplier =
(scale == decimal) ? UINT64_C(1000) * 1000 : UINT64_C(1024) * 1024; (scale == decimal) ? UINT64_C(1000) * 1000 : UINT64_C(1024) * 1024;
else if (strcmp(suffix, "G") == 0 || strcasecmp(suffix, "Giga") == 0) else if (strcmp(suffix, "G") == 0 || strcasecmp(suffix, "Giga") == 0)
multipler = (scale == decimal) ? UINT64_C(1000) * 1000 * 1000 multiplier = (scale == decimal) ? UINT64_C(1000) * 1000 * 1000
: UINT64_C(1024) * 1024 * 1024; : UINT64_C(1024) * 1024 * 1024;
else if (strcmp(suffix, "T") == 0 || strcasecmp(suffix, "Tera") == 0) else if (strcmp(suffix, "T") == 0 || strcasecmp(suffix, "Tera") == 0)
multipler = (scale == decimal) ? UINT64_C(1000) * 1000 * 1000 * 1000 multiplier = (scale == decimal) ? UINT64_C(1000) * 1000 * 1000 * 1000
: UINT64_C(1024) * 1024 * 1024 * 1024; : UINT64_C(1024) * 1024 * 1024 * 1024;
else if (scale == duration && else if (scale == duration &&
(strcmp(suffix, "s") == 0 || strcasecmp(suffix, "Seconds") == 0)) (strcmp(suffix, "s") == 0 || strcasecmp(suffix, "Seconds") == 0))
multipler = 1; multiplier = 1;
else if (scale == duration && else if (scale == duration &&
(strcmp(suffix, "m") == 0 || strcasecmp(suffix, "Minutes") == 0)) (strcmp(suffix, "m") == 0 || strcasecmp(suffix, "Minutes") == 0))
multipler = 60; multiplier = 60;
else if (scale == duration && else if (scale == duration &&
(strcmp(suffix, "h") == 0 || strcasecmp(suffix, "Hours") == 0)) (strcmp(suffix, "h") == 0 || strcasecmp(suffix, "Hours") == 0))
multipler = 3600; multiplier = 3600;
else if (scale == duration && else if (scale == duration &&
(strcmp(suffix, "d") == 0 || strcasecmp(suffix, "Days") == 0)) (strcmp(suffix, "d") == 0 || strcasecmp(suffix, "Days") == 0))
multipler = 3600 * 24; multiplier = 3600 * 24;
else else
failure( failure(
"Option '--%s' expects a numeric value with Kilo/Mega/Giga/Tera %s" "Option '--%s' expects a numeric value with Kilo/Mega/Giga/Tera %s"
@ -193,10 +193,10 @@ bool parse_option(int argc, char *const argv[], int &narg, const char *option,
suffix); suffix);
} }
if (raw >= UINT64_MAX / multipler) if (raw >= UINT64_MAX / multiplier)
failure("The value for option '--%s' is too huge\n", option); failure("The value for option '--%s' is too huge\n", option);
value = raw * multipler; value = raw * multiplier;
if (maxval && value > maxval) if (maxval && value > maxval)
failure("The maximal value for option '--%s' is %" PRIu64 "\n", option, failure("The maximal value for option '--%s' is %" PRIu64 "\n", option,
maxval); maxval);

View File

@ -240,7 +240,7 @@ local_suffix::~local_suffix() { suffix.erase(trim_pos); }
void progress_canary(bool active) { void progress_canary(bool active) {
static chrono::time progress_timestamp; static chrono::time progress_timestamp;
chrono::time now = chrono::now_motonic(); chrono::time now = chrono::now_monotonic();
if (now.fixedpoint - progress_timestamp.fixedpoint < if (now.fixedpoint - progress_timestamp.fixedpoint <
chrono::from_ms(42).fixedpoint) chrono::from_ms(42).fixedpoint)

View File

@ -26,7 +26,7 @@ MDBX_NORETURN void usage(void) {
"Common parameters:\n" "Common parameters:\n"
" --pathname=... Path and/or name of database files\n" " --pathname=... Path and/or name of database files\n"
" --repeat=N Set repeat counter\n" " --repeat=N Set repeat counter\n"
" --threads=N Number of thread (unsunpported for now)\n" " --threads=N Number of thread (unsupported for now)\n"
" --timeout=N[s|m|h|d] Set timeout in seconds/minutes/hours/days\n" " --timeout=N[s|m|h|d] Set timeout in seconds/minutes/hours/days\n"
" --failfast[=YES/no] Lill all actors on first failure/error\n" " --failfast[=YES/no] Lill all actors on first failure/error\n"
" --max-readers=N See mdbx_env_set_maxreaders() description\n" " --max-readers=N See mdbx_env_set_maxreaders() description\n"
@ -43,7 +43,7 @@ MDBX_NORETURN void usage(void) {
" --size Initial size in Kb/Mb/Gb/Tb\n" " --size Initial size in Kb/Mb/Gb/Tb\n"
" --shrink-threshold Shrink threshold in Kb/Mb/Gb/Tb\n" " --shrink-threshold Shrink threshold in Kb/Mb/Gb/Tb\n"
" --growth-step Grow step in Kb/Mb/Gb/Tb\n" " --growth-step Grow step in Kb/Mb/Gb/Tb\n"
"Predefined complext scenarios/cases:\n" "Predefined complex scenarios/cases:\n"
" --case=... Only `basic` scenario implemented for now\n" " --case=... Only `basic` scenario implemented for now\n"
" basic == Simultaneous multi-process execution\n" " basic == Simultaneous multi-process execution\n"
" of test-actors: nested,hill,ttl,copy,append,jitter,try\n" " of test-actors: nested,hill,ttl,copy,append,jitter,try\n"
@ -186,8 +186,8 @@ std::unordered_map<unsigned, actor_config *> events;
std::unordered_map<mdbx_pid_t, actor_config *> pid2actor; std::unordered_map<mdbx_pid_t, actor_config *> pid2actor;
std::set<std::string> databases; std::set<std::string> databases;
unsigned nactors; unsigned nactors;
chrono::time start_motonic; chrono::time start_monotonic;
chrono::time deadline_motonic; chrono::time deadline_monotonic;
bool singlemode; bool singlemode;
namespace config { namespace config {
@ -504,11 +504,11 @@ int main(int argc, char *const argv[]) {
} }
bool failed = false; bool failed = false;
global::start_motonic = chrono::now_motonic(); global::start_monotonic = chrono::now_monotonic();
global::deadline_motonic.fixedpoint = global::deadline_monotonic.fixedpoint =
(global::config::timeout_duration_seconds == 0) (global::config::timeout_duration_seconds == 0)
? chrono::infinite().fixedpoint ? chrono::infinite().fixedpoint
: global::start_motonic.fixedpoint + : global::start_monotonic.fixedpoint +
chrono::from_seconds(global::config::timeout_duration_seconds) chrono::from_seconds(global::config::timeout_duration_seconds)
.fixedpoint; .fixedpoint;
@ -557,14 +557,14 @@ int main(int argc, char *const argv[]) {
log_trace("=== polling..."); log_trace("=== polling...");
while (left > 0) { while (left > 0) {
unsigned timeout_seconds_left = INT_MAX; unsigned timeout_seconds_left = INT_MAX;
chrono::time now_motonic = chrono::now_motonic(); chrono::time now_monotonic = chrono::now_monotonic();
if (now_motonic.fixedpoint >= global::deadline_motonic.fixedpoint) if (now_monotonic.fixedpoint >= global::deadline_monotonic.fixedpoint)
timeout_seconds_left = 0; timeout_seconds_left = 0;
else { else {
chrono::time left_motonic; chrono::time left_monotonic;
left_motonic.fixedpoint = left_monotonic.fixedpoint =
global::deadline_motonic.fixedpoint - now_motonic.fixedpoint; global::deadline_monotonic.fixedpoint - now_monotonic.fixedpoint;
timeout_seconds_left = left_motonic.seconds(); timeout_seconds_left = left_monotonic.seconds();
} }
mdbx_pid_t pid; mdbx_pid_t pid;

View File

@ -336,7 +336,7 @@ bool osal_progress_push(bool active) {
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
static std::unordered_map<pid_t, actor_status> childs; static std::unordered_map<pid_t, actor_status> children;
static std::atomic_int sigalarm_head; static std::atomic_int sigalarm_head;
static void handler_SIGCHLD(int signum) { static void handler_SIGCHLD(int signum) {
@ -349,7 +349,7 @@ mdbx_pid_t osal_getpid(void) { return getpid(); }
int osal_delay(unsigned seconds) { return sleep(seconds) ? errno : 0; } int osal_delay(unsigned seconds) { return sleep(seconds) ? errno : 0; }
int osal_actor_start(const actor_config &config, mdbx_pid_t &pid) { int osal_actor_start(const actor_config &config, mdbx_pid_t &pid) {
if (childs.empty()) { if (children.empty()) {
struct sigaction act; struct sigaction act;
memset(&act, 0, sizeof(act)); memset(&act, 0, sizeof(act));
act.sa_handler = handler_SIGCHLD; act.sa_handler = handler_SIGCHLD;
@ -380,14 +380,14 @@ int osal_actor_start(const actor_config &config, mdbx_pid_t &pid) {
log_trace("osal_actor_start: fork pid %ld for %u", (long)pid, log_trace("osal_actor_start: fork pid %ld for %u", (long)pid,
config.actor_id); config.actor_id);
childs[pid] = as_running; children[pid] = as_running;
return 0; return 0;
} }
actor_status osal_actor_info(const mdbx_pid_t pid) { return childs.at(pid); } actor_status osal_actor_info(const mdbx_pid_t pid) { return children.at(pid); }
void osal_killall_actors(void) { void osal_killall_actors(void) {
for (auto &pair : childs) { for (auto &pair : children) {
kill(pair.first, SIGKILL); kill(pair.first, SIGKILL);
pair.second = as_killed; pair.second = as_killed;
} }
@ -417,16 +417,16 @@ int osal_actor_poll(mdbx_pid_t &pid, unsigned timeout) {
if (pid > 0) { if (pid > 0) {
if (WIFEXITED(status)) if (WIFEXITED(status))
childs[pid] = children[pid] =
(WEXITSTATUS(status) == EXIT_SUCCESS) ? as_successful : as_failed; (WEXITSTATUS(status) == EXIT_SUCCESS) ? as_successful : as_failed;
else if (WCOREDUMP(status)) else if (WCOREDUMP(status))
childs[pid] = as_coredump; children[pid] = as_coredump;
else if (WIFSIGNALED(status)) else if (WIFSIGNALED(status))
childs[pid] = as_killed; children[pid] = as_killed;
else if (WIFSTOPPED(status)) else if (WIFSTOPPED(status))
childs[pid] = as_debugging; children[pid] = as_debugging;
else if (WIFCONTINUED(status)) else if (WIFCONTINUED(status))
childs[pid] = as_running; children[pid] = as_running;
else { else {
assert(false); assert(false);
} }
@ -463,7 +463,7 @@ void osal_yield(void) {
} }
void osal_udelay(unsigned us) { void osal_udelay(unsigned us) {
chrono::time until, now = chrono::now_motonic(); chrono::time until, now = chrono::now_monotonic();
until.fixedpoint = now.fixedpoint + chrono::from_us(us).fixedpoint; until.fixedpoint = now.fixedpoint + chrono::from_us(us).fixedpoint;
struct timespec ts; struct timespec ts;
@ -506,7 +506,7 @@ void osal_udelay(unsigned us) {
} }
cpu_relax(); cpu_relax();
now = chrono::now_motonic(); now = chrono::now_monotonic();
} while (until.fixedpoint > now.fixedpoint); } while (until.fixedpoint > now.fixedpoint);
} }

View File

@ -186,10 +186,10 @@ bool actor_config::osal_deserialize(const char *str, const char *end,
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
typedef std::pair<HANDLE, actor_status> child; typedef std::pair<HANDLE, actor_status> child;
static std::unordered_map<mdbx_pid_t, child> childs; static std::unordered_map<mdbx_pid_t, child> children;
bool osal_progress_push(bool active) { bool osal_progress_push(bool active) {
if (!childs.empty()) { if (!children.empty()) {
if (!SetEvent(active ? hProgressActiveEvent : hProgressPassiveEvent)) if (!SetEvent(active ? hProgressActiveEvent : hProgressPassiveEvent))
failure_perror("osal_progress_push: SetEvent(overlord.progress)", failure_perror("osal_progress_push: SetEvent(overlord.progress)",
GetLastError()); GetLastError());
@ -284,8 +284,8 @@ Environment:
} }
int osal_actor_start(const actor_config &config, mdbx_pid_t &pid) { int osal_actor_start(const actor_config &config, mdbx_pid_t &pid) {
if (childs.size() == MAXIMUM_WAIT_OBJECTS) if (children.size() == MAXIMUM_WAIT_OBJECTS)
failure("Could't manage more that %u actors on Windows\n", failure("Couldn't manage more that %u actors on Windows\n",
MAXIMUM_WAIT_OBJECTS); MAXIMUM_WAIT_OBJECTS);
_flushall(); _flushall();
@ -324,17 +324,17 @@ int osal_actor_start(const actor_config &config, mdbx_pid_t &pid) {
CloseHandle(ProcessInformation.hThread); CloseHandle(ProcessInformation.hThread);
pid = ProcessInformation.dwProcessId; pid = ProcessInformation.dwProcessId;
childs[pid] = std::make_pair(ProcessInformation.hProcess, as_running); children[pid] = std::make_pair(ProcessInformation.hProcess, as_running);
return 0; return 0;
} }
actor_status osal_actor_info(const mdbx_pid_t pid) { actor_status osal_actor_info(const mdbx_pid_t pid) {
actor_status status = childs.at(pid).second; actor_status status = children.at(pid).second;
if (status > as_running) if (status > as_running)
return status; return status;
DWORD ExitCode; DWORD ExitCode;
if (!GetExitCodeProcess(childs.at(pid).first, &ExitCode)) if (!GetExitCodeProcess(children.at(pid).first, &ExitCode))
failure_perror("GetExitCodeProcess()", GetLastError()); failure_perror("GetExitCodeProcess()", GetLastError());
switch (ExitCode) { switch (ExitCode) {
@ -364,21 +364,21 @@ actor_status osal_actor_info(const mdbx_pid_t pid) {
break; break;
} }
childs.at(pid).second = status; children.at(pid).second = status;
return status; return status;
} }
void osal_killall_actors(void) { void osal_killall_actors(void) {
for (auto &pair : childs) for (auto &pair : children)
TerminateProcess(pair.second.first, STATUS_CONTROL_C_EXIT); TerminateProcess(pair.second.first, STATUS_CONTROL_C_EXIT);
} }
int osal_actor_poll(mdbx_pid_t &pid, unsigned timeout) { int osal_actor_poll(mdbx_pid_t &pid, unsigned timeout) {
std::vector<HANDLE> handles; std::vector<HANDLE> handles;
handles.reserve(childs.size() + 2); handles.reserve(children.size() + 2);
handles.push_back(hProgressActiveEvent); handles.push_back(hProgressActiveEvent);
handles.push_back(hProgressPassiveEvent); handles.push_back(hProgressPassiveEvent);
for (const auto &pair : childs) for (const auto &pair : children)
if (pair.second.second <= as_running) if (pair.second.second <= as_running)
handles.push_back(pair.second.first); handles.push_back(pair.second.first);
@ -399,7 +399,7 @@ int osal_actor_poll(mdbx_pid_t &pid, unsigned timeout) {
if (rc >= WAIT_OBJECT_0 + 2 && rc < WAIT_OBJECT_0 + handles.size()) { if (rc >= WAIT_OBJECT_0 + 2 && rc < WAIT_OBJECT_0 + handles.size()) {
pid = 0; pid = 0;
for (const auto &pair : childs) for (const auto &pair : children)
if (pair.second.first == handles[rc - WAIT_OBJECT_0]) { if (pair.second.first == handles[rc - WAIT_OBJECT_0]) {
pid = pair.first; pid = pair.first;
break; break;
@ -419,7 +419,7 @@ int osal_actor_poll(mdbx_pid_t &pid, unsigned timeout) {
void osal_yield(void) { SwitchToThread(); } void osal_yield(void) { SwitchToThread(); }
void osal_udelay(unsigned us) { void osal_udelay(unsigned us) {
chrono::time until, now = chrono::now_motonic(); chrono::time until, now = chrono::now_monotonic();
until.fixedpoint = now.fixedpoint + chrono::from_us(us).fixedpoint; until.fixedpoint = now.fixedpoint + chrono::from_us(us).fixedpoint;
static unsigned threshold_us; static unsigned threshold_us;
@ -440,7 +440,7 @@ void osal_udelay(unsigned us) {
} }
YieldProcessor(); YieldProcessor();
now = chrono::now_motonic(); now = chrono::now_monotonic();
} while (now.fixedpoint < until.fixedpoint); } while (now.fixedpoint < until.fixedpoint);
} }

View File

@ -376,7 +376,7 @@ bool testcase::setup() {
if (!wait4start()) if (!wait4start())
return false; return false;
start_timestamp = chrono::now_motonic(); start_timestamp = chrono::now_monotonic();
nops_completed = 0; nops_completed = 0;
return true; return true;
} }
@ -395,7 +395,7 @@ bool testcase::should_continue(bool check_timeout_only) const {
if (config.params.test_duration) { if (config.params.test_duration) {
chrono::time since; chrono::time since;
since.fixedpoint = since.fixedpoint =
chrono::now_motonic().fixedpoint - start_timestamp.fixedpoint; chrono::now_monotonic().fixedpoint - start_timestamp.fixedpoint;
if (since.seconds() >= config.params.test_duration) if (since.seconds() >= config.params.test_duration)
result = false; result = false;
} }

View File

@ -56,8 +56,8 @@ extern std::unordered_map<unsigned, actor_config *> events;
extern std::unordered_map<mdbx_pid_t, actor_config *> pid2actor; extern std::unordered_map<mdbx_pid_t, actor_config *> pid2actor;
extern std::set<std::string> databases; extern std::set<std::string> databases;
extern unsigned nactors; extern unsigned nactors;
extern chrono::time start_motonic; extern chrono::time start_monotonic;
extern chrono::time deadline_motonic; extern chrono::time deadline_monotonic;
extern bool singlemode; extern bool singlemode;
namespace config { namespace config {