summaryrefslogtreecommitdiff
path: root/src/third_party/wiredtiger/bench/workgen
diff options
context:
space:
mode:
authorTammy Bailey <tammy.bailey@mongodb.com>2023-01-20 04:39:10 +0000
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2023-01-20 05:16:25 +0000
commit5f792ec4e19e0b98fd333e3c3e56e760cbdfd517 (patch)
tree3d6f097da2c6b1174aeaa6c7b58d38139e469516 /src/third_party/wiredtiger/bench/workgen
parent0085b0337d3719810726cb159aa0066c79c7cdf2 (diff)
downloadmongo-5f792ec4e19e0b98fd333e3c3e56e760cbdfd517.tar.gz
Import wiredtiger: 39c85567caebe0f52ac8120fb0437599bbd40ba5 from branch mongodb-master
ref: 0f4ca11ba5..39c85567ca for: 6.3.0-rc0 WT-10309 Replace mutex with shared_mutex for dynamic tables in workgen
Diffstat (limited to 'src/third_party/wiredtiger/bench/workgen')
-rw-r--r--src/third_party/wiredtiger/bench/workgen/workgen.cpp34
-rw-r--r--src/third_party/wiredtiger/bench/workgen/workgen_func.c6
-rw-r--r--src/third_party/wiredtiger/bench/workgen/workgen_func.h1
-rw-r--r--src/third_party/wiredtiger/bench/workgen/workgen_int.h4
4 files changed, 31 insertions, 14 deletions
diff --git a/src/third_party/wiredtiger/bench/workgen/workgen.cpp b/src/third_party/wiredtiger/bench/workgen/workgen.cpp
index 50334f97d44..224e4be151c 100644
--- a/src/third_party/wiredtiger/bench/workgen/workgen.cpp
+++ b/src/third_party/wiredtiger/bench/workgen/workgen.cpp
@@ -394,8 +394,12 @@ WorkloadRunner::start_tables_create(WT_CONNECTION *conn)
uri += rand_chars;
// Check if a table with this name already exists. Skip if it does.
- if (icontext->_tint.count(uri) > 0 || icontext->_dyn_tint.count(uri) > 0)
- continue;
+ // Use a shared lock to read the dynamic tables structures.
+ {
+ const std::shared_lock lock(*icontext->_dyn_mutex);
+ if (icontext->_tint.count(uri) > 0 || icontext->_dyn_tint.count(uri) > 0)
+ continue;
+ }
/*
* Create the table. Mark the table as part of the dynamic set by storing extra
@@ -411,7 +415,7 @@ WorkloadRunner::start_tables_create(WT_CONNECTION *conn)
// The data structures for the dynamic table set are protected by a mutex.
{
- const std::lock_guard<std::mutex> lock(*icontext->_dyn_mutex);
+ const std::lock_guard<std::shared_mutex> lock(*icontext->_dyn_mutex);
// Add the table into the list of dynamic set.
tint_t tint = icontext->_dyn_tint_last;
@@ -489,7 +493,7 @@ WorkloadRunner::start_tables_drop(WT_CONNECTION *conn)
std::vector<std::string> drop_files; // Files ready to be dropped.
// The data structures for the dynamic table set are protected by a mutex.
{
- const std::lock_guard<std::mutex> lock(*icontext->_dyn_mutex);
+ const std::lock_guard<std::shared_mutex> lock(*icontext->_dyn_mutex);
/*
* When dropping, consider how many dynamic tables we have left and how many are already
@@ -512,6 +516,8 @@ WorkloadRunner::start_tables_drop(WT_CONNECTION *conn)
VERBOSE(*_workload, "Marking pending removal for: " << it->first);
icontext->_dyn_table_runtime[it->second]._pending_delete = true;
+ ASSERT(std::find(pending_delete.begin(), pending_delete.end(), it->first) ==
+ pending_delete.end());
pending_delete.push_back(it->first);
++drops;
}
@@ -732,7 +738,8 @@ Context::operator=(const Context &other)
ContextInternal::ContextInternal()
: _tint(), _table_names(), _table_runtime(), _tint_last(0), _dyn_tint(), _dyn_table_names(),
- _dyn_table_runtime(), _dyn_tint_last(0), _context_count(0), _dyn_mutex(new std::mutex())
+ _dyn_table_runtime(), _dyn_tint_last(0), _context_count(0),
+ _dyn_mutex(new std::shared_mutex())
{
uint32_t count = workgen_atomic_add32(&context_count, 1);
@@ -785,7 +792,8 @@ ContextInternal::create_all(WT_CONNECTION *conn)
if (std::string(value).find(DYN_TABLE_APP_METADATA) != std::string::npos &&
WT_PREFIX_MATCH(key, "table:")) {
- // Add the table into the list of dynamic set.
+ // Add the table into the list of dynamic set. We are single threaded here and hence
+ // do not yet need to protect the dynamic table structures with a lock.
_dyn_tint[key] = _dyn_tint_last;
_dyn_table_names[_dyn_tint_last] = key;
_dyn_table_runtime[_dyn_tint_last] = TableRuntime();
@@ -1292,7 +1300,7 @@ ThreadRunner::op_get_key_recno(Operation *op, uint64_t range, tint_t tint)
recno_count = range;
else {
if (op->_random_table) {
- const std::lock_guard<std::mutex> lock(*_icontext->_dyn_mutex);
+ const std::shared_lock lock(*_icontext->_dyn_mutex);
recno_count = _icontext->_dyn_table_runtime.at(tint)._max_recno;
} else
recno_count = _icontext->_table_runtime[tint]._max_recno;
@@ -1347,7 +1355,7 @@ ThreadRunner::op_run(Operation *op)
// Find a table to operate on.
if (op->_random_table) {
- const std::lock_guard<std::mutex> lock(*_icontext->_dyn_mutex);
+ const std::shared_lock lock(*_icontext->_dyn_mutex);
size_t num_tables = _icontext->_dyn_table_names.size();
if (num_tables == 0)
@@ -1363,7 +1371,8 @@ ThreadRunner::op_run(Operation *op)
if (!marked_deleted) {
table_uri = uri;
tint = _icontext->_dyn_tint[uri];
- ++_icontext->_dyn_table_runtime[tint]._in_use;
+ // Use atomic here as we can race with another thread that acquires the shared lock.
+ (void)workgen_atomic_add32(&_icontext->_dyn_table_runtime[tint]._in_use, 1);
} else {
goto err;
}
@@ -1389,7 +1398,7 @@ ThreadRunner::op_run(Operation *op)
track = &_stats.insert;
if (op->_key._keytype == Key::KEYGEN_APPEND || op->_key._keytype == Key::KEYGEN_AUTO) {
if (op->_random_table) {
- const std::lock_guard<std::mutex> lock(*_icontext->_dyn_mutex);
+ const std::shared_lock lock(*_icontext->_dyn_mutex);
recno = workgen_atomic_add64(&_icontext->_dyn_table_runtime.at(tint)._max_recno, 1);
} else {
recno = workgen_atomic_add64(&_icontext->_table_runtime[tint]._max_recno, 1);
@@ -1592,9 +1601,10 @@ err:
// For operations on random tables, if a table has been selected, decrement the reference
// counter.
if (op->_random_table && !table_uri.empty()) {
- const std::lock_guard<std::mutex> lock(*_icontext->_dyn_mutex);
+ const std::shared_lock lock(*_icontext->_dyn_mutex);
ASSERT(_icontext->_dyn_table_runtime[tint]._in_use > 0);
- --_icontext->_dyn_table_runtime[tint]._in_use;
+ // Use atomic here as we can race with another thread that acquires the shared lock.
+ (void)workgen_atomic_sub32(&_icontext->_dyn_table_runtime[tint]._in_use, 1);
}
return (ret);
diff --git a/src/third_party/wiredtiger/bench/workgen/workgen_func.c b/src/third_party/wiredtiger/bench/workgen/workgen_func.c
index 7480a3d8fa2..d85b8cab7b8 100644
--- a/src/third_party/wiredtiger/bench/workgen/workgen_func.c
+++ b/src/third_party/wiredtiger/bench/workgen/workgen_func.c
@@ -56,6 +56,12 @@ workgen_atomic_add64(uint64_t *vp, uint64_t v)
return (__wt_atomic_add64(vp, v));
}
+uint32_t
+workgen_atomic_sub32(uint32_t *vp, uint32_t v)
+{
+ return (__wt_atomic_sub32(vp, v));
+}
+
void
workgen_clock(uint64_t *clockp)
{
diff --git a/src/third_party/wiredtiger/bench/workgen/workgen_func.h b/src/third_party/wiredtiger/bench/workgen/workgen_func.h
index dfabc9dc85d..5471f9bbb31 100644
--- a/src/third_party/wiredtiger/bench/workgen/workgen_func.h
+++ b/src/third_party/wiredtiger/bench/workgen/workgen_func.h
@@ -29,6 +29,7 @@ struct workgen_random_state;
extern uint32_t workgen_atomic_add32(uint32_t *vp, uint32_t v);
extern uint64_t workgen_atomic_add64(uint64_t *vp, uint64_t v);
+extern uint32_t workgen_atomic_sub32(uint32_t *vp, uint32_t v);
extern void workgen_clock(uint64_t *tsp);
extern void workgen_epoch(struct timespec *tsp);
extern uint32_t workgen_random(struct workgen_random_state volatile *rnd_state);
diff --git a/src/third_party/wiredtiger/bench/workgen/workgen_int.h b/src/third_party/wiredtiger/bench/workgen/workgen_int.h
index c08759ec802..c2f41ae0d64 100644
--- a/src/third_party/wiredtiger/bench/workgen/workgen_int.h
+++ b/src/third_party/wiredtiger/bench/workgen/workgen_int.h
@@ -27,7 +27,7 @@
*/
#include <map>
#include <memory>
-#include <mutex>
+#include <shared_mutex>
#include <ostream>
#include <set>
#include <string>
@@ -222,7 +222,7 @@ struct ContextInternal {
std::map<tint_t, TableRuntime> _dyn_table_runtime;
tint_t _dyn_tint_last;
// This mutex should be used to protect the access to the dynamic tables set.
- std::mutex* _dyn_mutex;
+ std::shared_mutex* _dyn_mutex;
// unique id per context, to work with multiple contexts, starts at 1.
uint32_t _context_count;