mirror of
https://gitflic.ru/project/erthink/libmdbx.git
synced 2025-01-09 17:56:51 +00:00
mdbx-testing: тестирование парковки транзакций.
This commit is contained in:
parent
ec0ada7b8c
commit
2311706272
@ -137,8 +137,16 @@ bool parse_option(int argc, char *const argv[], int &narg, const char *option,
|
|||||||
if (strcmp(value_cstr, "rnd") == 0 || strcmp(value_cstr, "rand") == 0 ||
|
if (strcmp(value_cstr, "rnd") == 0 || strcmp(value_cstr, "rand") == 0 ||
|
||||||
strcmp(value_cstr, "random") == 0) {
|
strcmp(value_cstr, "random") == 0) {
|
||||||
value = minval;
|
value = minval;
|
||||||
if (maxval > minval)
|
if (maxval > minval) {
|
||||||
value += (prng32() + UINT64_C(44263400549519813)) % (maxval - minval);
|
uint64_t salt = (scale != entropy)
|
||||||
|
? prng64() ^ UINT64_C(44263400549519813)
|
||||||
|
: (chrono::now_monotonic().fixedpoint ^
|
||||||
|
UINT64_C(0xD85794512ED321FD)) *
|
||||||
|
UINT64_C(0x9120038359EAF3) ^
|
||||||
|
chrono::now_realtime().fixedpoint *
|
||||||
|
UINT64_C(0x2FE5232BDC8E5F);
|
||||||
|
value += salt % (maxval - minval);
|
||||||
|
}
|
||||||
if (scale == intkey)
|
if (scale == intkey)
|
||||||
value &= ~3u;
|
value &= ~3u;
|
||||||
return true;
|
return true;
|
||||||
|
@ -52,7 +52,7 @@ const char *keygencase2str(const keygen_case);
|
|||||||
|
|
||||||
namespace config {
|
namespace config {
|
||||||
|
|
||||||
enum scale_mode { no_scale, decimal, binary, duration, intkey };
|
enum scale_mode { no_scale, decimal, binary, duration, intkey, entropy };
|
||||||
|
|
||||||
bool parse_option(int argc, char *const argv[], int &narg, const char *option,
|
bool parse_option(int argc, char *const argv[], int &narg, const char *option,
|
||||||
const char **value, const char *default_value = nullptr);
|
const char **value, const char *default_value = nullptr);
|
||||||
|
@ -28,7 +28,7 @@ public:
|
|||||||
bool testcase_smoke4fork::open_dbi() {
|
bool testcase_smoke4fork::open_dbi() {
|
||||||
if (!dbi || dbi_invalid) {
|
if (!dbi || dbi_invalid) {
|
||||||
if (dbi_stable ||
|
if (dbi_stable ||
|
||||||
(mdbx_txn_flags(txn_guard.get()) & int(MDBX_TXN_RDONLY)) == 0) {
|
(mdbx_txn_flags(txn_guard.get()) & MDBX_TXN_RDONLY) == 0) {
|
||||||
dbi = db_table_open(!dbi_stable);
|
dbi = db_table_open(!dbi_stable);
|
||||||
dbi_invalid = false;
|
dbi_invalid = false;
|
||||||
}
|
}
|
||||||
|
@ -164,6 +164,9 @@ bool testcase_jitter::run() {
|
|||||||
failure_perror("mdbx_env_set_geometry-1", err);
|
failure_perror("mdbx_env_set_geometry-1", err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (flipcoin()) {
|
||||||
|
// err =
|
||||||
|
}
|
||||||
txn_end(flipcoin());
|
txn_end(flipcoin());
|
||||||
|
|
||||||
if (global::config::geometry_jitter) {
|
if (global::config::geometry_jitter) {
|
||||||
|
@ -394,7 +394,7 @@ int main(int argc, char *const argv[]) {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (config::parse_option(argc, argv, narg, "repeat", params.nrepeat,
|
if (config::parse_option(argc, argv, narg, "repeat", params.nrepeat,
|
||||||
config::no_scale))
|
config::entropy))
|
||||||
continue;
|
continue;
|
||||||
if (config::parse_option(argc, argv, narg, "threads", params.nthreads,
|
if (config::parse_option(argc, argv, narg, "threads", params.nthreads,
|
||||||
config::no_scale, 1, 64))
|
config::no_scale, 1, 64))
|
||||||
@ -443,7 +443,7 @@ int main(int argc, char *const argv[]) {
|
|||||||
params.keygen.mesh, 0, 64))
|
params.keygen.mesh, 0, 64))
|
||||||
continue;
|
continue;
|
||||||
if (config::parse_option(argc, argv, narg, "prng-seed", params.prng_seed,
|
if (config::parse_option(argc, argv, narg, "prng-seed", params.prng_seed,
|
||||||
config::no_scale)) {
|
config::entropy)) {
|
||||||
prng_seed(params.prng_seed);
|
prng_seed(params.prng_seed);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -320,6 +320,8 @@ static void handler_SIGUSR(int signum) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool osal_multiactor_mode(void) { return overlord_pid != 0; }
|
||||||
|
|
||||||
bool osal_progress_push(bool active) {
|
bool osal_progress_push(bool active) {
|
||||||
if (overlord_pid) {
|
if (overlord_pid) {
|
||||||
if (kill(overlord_pid, active ? SIGUSR1 : SIGUSR2))
|
if (kill(overlord_pid, active ? SIGUSR1 : SIGUSR2))
|
||||||
|
@ -175,6 +175,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> children;
|
static std::unordered_map<mdbx_pid_t, child> children;
|
||||||
|
|
||||||
|
bool osal_multiactor_mode(void) {
|
||||||
|
return hProgressActiveEvent || hProgressPassiveEvent;
|
||||||
|
}
|
||||||
|
|
||||||
bool osal_progress_push(bool active) {
|
bool osal_progress_push(bool active) {
|
||||||
if (!children.empty()) {
|
if (!children.empty()) {
|
||||||
if (!SetEvent(active ? hProgressActiveEvent : hProgressPassiveEvent))
|
if (!SetEvent(active ? hProgressActiveEvent : hProgressPassiveEvent))
|
||||||
|
@ -16,6 +16,7 @@ int osal_actor_poll(mdbx_pid_t &pid, unsigned timeout);
|
|||||||
void osal_wait4barrier(void);
|
void osal_wait4barrier(void);
|
||||||
|
|
||||||
bool osal_progress_push(bool active);
|
bool osal_progress_push(bool active);
|
||||||
|
bool osal_multiactor_mode(void);
|
||||||
|
|
||||||
int osal_delay(unsigned seconds);
|
int osal_delay(unsigned seconds);
|
||||||
void osal_udelay(size_t us);
|
void osal_udelay(size_t us);
|
||||||
|
@ -212,6 +212,9 @@ void testcase::txn_begin(bool readonly, MDBX_txn_flags_t flags) {
|
|||||||
log_trace("== counter %u, env_warmup(flags %u), rc %d", counter,
|
log_trace("== counter %u, env_warmup(flags %u), rc %d", counter,
|
||||||
warmup_flags, err);
|
warmup_flags, err);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (readonly && flipcoin())
|
||||||
|
txn_probe_parking();
|
||||||
}
|
}
|
||||||
|
|
||||||
int testcase::breakable_commit() {
|
int testcase::breakable_commit() {
|
||||||
@ -267,6 +270,9 @@ void testcase::txn_end(bool abort) {
|
|||||||
log_trace(">> txn_end(%s)", abort ? "abort" : "commit");
|
log_trace(">> txn_end(%s)", abort ? "abort" : "commit");
|
||||||
assert(txn_guard);
|
assert(txn_guard);
|
||||||
|
|
||||||
|
if (flipcoin())
|
||||||
|
txn_probe_parking();
|
||||||
|
|
||||||
MDBX_txn *txn = txn_guard.release();
|
MDBX_txn *txn = txn_guard.release();
|
||||||
if (abort) {
|
if (abort) {
|
||||||
int err = mdbx_txn_abort(txn);
|
int err = mdbx_txn_abort(txn);
|
||||||
@ -321,6 +327,13 @@ int testcase::breakable_restart() {
|
|||||||
int rc = MDBX_SUCCESS;
|
int rc = MDBX_SUCCESS;
|
||||||
if (txn_guard)
|
if (txn_guard)
|
||||||
rc = breakable_commit();
|
rc = breakable_commit();
|
||||||
|
if (flipcoin()) {
|
||||||
|
txn_begin(true);
|
||||||
|
txn_probe_parking();
|
||||||
|
int err = mdbx_txn_abort(txn_guard.release());
|
||||||
|
if (unlikely(err != MDBX_SUCCESS))
|
||||||
|
failure_perror("mdbx_txn_abort()", err);
|
||||||
|
}
|
||||||
txn_begin(false, MDBX_TXN_READWRITE);
|
txn_begin(false, MDBX_TXN_READWRITE);
|
||||||
if (cursor_guard)
|
if (cursor_guard)
|
||||||
cursor_renew();
|
cursor_renew();
|
||||||
@ -1426,3 +1439,83 @@ bool testcase::check_batch_get() {
|
|||||||
mdbx_cursor_close(batch_cursor);
|
mdbx_cursor_close(batch_cursor);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool testcase::txn_probe_parking() {
|
||||||
|
MDBX_txn_flags_t state =
|
||||||
|
mdbx_txn_flags(txn_guard.get()) &
|
||||||
|
(MDBX_TXN_RDONLY | MDBX_TXN_PARKED | MDBX_TXN_AUTOUNPARK |
|
||||||
|
MDBX_TXN_OUSTED | MDBX_TXN_BLOCKED);
|
||||||
|
if (state != MDBX_TXN_RDONLY)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
const bool autounpark = flipcoin();
|
||||||
|
int err = mdbx_txn_park(txn_guard.get(), autounpark);
|
||||||
|
if (err != MDBX_SUCCESS)
|
||||||
|
failure("mdbx_txn_park(), err %d", err);
|
||||||
|
|
||||||
|
MDBX_txn_info txn_info;
|
||||||
|
if (flipcoin()) {
|
||||||
|
err = mdbx_txn_info(txn_guard.get(), &txn_info, flipcoin());
|
||||||
|
if (err != MDBX_SUCCESS)
|
||||||
|
failure("mdbx_txn_info(1), state 0x%x, err %d",
|
||||||
|
state = mdbx_txn_flags(txn_guard.get()), err);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (osal_multiactor_mode() && !mode_readonly()) {
|
||||||
|
while (flipcoin() &&
|
||||||
|
((state = mdbx_txn_flags(txn_guard.get())) & MDBX_TXN_OUSTED) == 0)
|
||||||
|
osal_udelay(4242);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (flipcoin()) {
|
||||||
|
err = mdbx_txn_info(txn_guard.get(), &txn_info, flipcoin());
|
||||||
|
if (err != MDBX_SUCCESS)
|
||||||
|
failure("mdbx_txn_info(2), state 0x%x, err %d",
|
||||||
|
state = mdbx_txn_flags(txn_guard.get()), err);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (flipcoin()) {
|
||||||
|
MDBX_envinfo env_info;
|
||||||
|
err = mdbx_env_info_ex(db_guard.get(), txn_guard.get(), &env_info,
|
||||||
|
sizeof(env_info));
|
||||||
|
if (!autounpark) {
|
||||||
|
if (err != MDBX_BAD_TXN)
|
||||||
|
failure("mdbx_env_info_ex(autounpark=%s), flags 0x%x, unexpected err "
|
||||||
|
"%d, must %d",
|
||||||
|
autounpark ? "true" : "false", state, err, MDBX_BAD_TXN);
|
||||||
|
} else if (err != MDBX_SUCCESS) {
|
||||||
|
if (err != MDBX_OUSTED ||
|
||||||
|
((state = mdbx_txn_flags(txn_guard.get())) & MDBX_TXN_OUSTED) == 0)
|
||||||
|
failure("mdbx_env_info_ex(autounpark=%s), flags 0x%x, err %d",
|
||||||
|
autounpark ? "true" : "false", state, err);
|
||||||
|
else {
|
||||||
|
err = mdbx_txn_renew(txn_guard.get());
|
||||||
|
if (err != MDBX_SUCCESS)
|
||||||
|
failure("mdbx_txn_renew(), state 0x%x, err %d",
|
||||||
|
state = mdbx_txn_flags(txn_guard.get()), err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const bool autorestart = flipcoin();
|
||||||
|
err = mdbx_txn_unpark(txn_guard.get(), autorestart);
|
||||||
|
if (MDBX_IS_ERROR(err)) {
|
||||||
|
if (err != MDBX_OUSTED || autorestart)
|
||||||
|
failure("mdbx_txn_unpark(autounpark=%s, autorestart=%s), err %d",
|
||||||
|
autounpark ? "true" : "false", autorestart ? "true" : "false",
|
||||||
|
err);
|
||||||
|
else {
|
||||||
|
err = mdbx_txn_renew(txn_guard.get());
|
||||||
|
if (err != MDBX_SUCCESS)
|
||||||
|
failure("mdbx_txn_renew(), state 0x%x, err %d",
|
||||||
|
state = mdbx_txn_flags(txn_guard.get()), err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
state = mdbx_txn_flags(txn_guard.get()) &
|
||||||
|
(MDBX_TXN_RDONLY | MDBX_TXN_PARKED | MDBX_TXN_AUTOUNPARK |
|
||||||
|
MDBX_TXN_OUSTED | MDBX_TXN_BLOCKED);
|
||||||
|
if (state != MDBX_TXN_RDONLY)
|
||||||
|
failure("unexpected txn-state 0x%x", state);
|
||||||
|
return state == MDBX_TXN_RDONLY;
|
||||||
|
}
|
||||||
|
@ -254,6 +254,8 @@ protected:
|
|||||||
void cursor_renew();
|
void cursor_renew();
|
||||||
void txn_inject_writefault(void);
|
void txn_inject_writefault(void);
|
||||||
void txn_inject_writefault(MDBX_txn *txn);
|
void txn_inject_writefault(MDBX_txn *txn);
|
||||||
|
bool txn_probe_parking();
|
||||||
|
|
||||||
void fetch_canary();
|
void fetch_canary();
|
||||||
void update_canary(uint64_t increment);
|
void update_canary(uint64_t increment);
|
||||||
bool checkdata(const char *step, MDBX_dbi handle, MDBX_val key2check,
|
bool checkdata(const char *step, MDBX_dbi handle, MDBX_val key2check,
|
||||||
@ -275,7 +277,7 @@ protected:
|
|||||||
void signal();
|
void signal();
|
||||||
bool should_continue(bool check_timeout_only = false) const;
|
bool should_continue(bool check_timeout_only = false) const;
|
||||||
|
|
||||||
bool failure(const char *fmt, ...) const;
|
bool MDBX_PRINTF_ARGS(2, 3) failure(const char *fmt, ...) const;
|
||||||
void generate_pair(const keygen::serial_t serial, keygen::buffer &out_key,
|
void generate_pair(const keygen::serial_t serial, keygen::buffer &out_key,
|
||||||
keygen::buffer &out_value, keygen::serial_t data_age) {
|
keygen::buffer &out_value, keygen::serial_t data_age) {
|
||||||
keyvalue_maker.pair(serial, out_key, out_value, data_age, false);
|
keyvalue_maker.pair(serial, out_key, out_value, data_age, false);
|
||||||
|
Loading…
Reference in New Issue
Block a user