diff options
author | Michael Cahill <michael.cahill@mongodb.com> | 2017-08-17 14:04:31 +1000 |
---|---|---|
committer | Alex Gorrod <alexander.gorrod@mongodb.com> | 2017-08-17 14:04:31 +1000 |
commit | 2a2efab3a69df3979e88c2fe424d512c19b420d6 (patch) | |
tree | c88f05e38d8387307518a565a2ebe03d4db6f73f | |
parent | 146ad045334f9f0f4b951b92971da40ed1c4232f (diff) | |
download | mongo-2a2efab3a69df3979e88c2fe424d512c19b420d6.tar.gz |
WT-3465 Avoid locks when reading 8-byte timestamps. (#3589)
-rw-r--r-- | src/include/txn.h | 1 | ||||
-rw-r--r-- | src/include/txn.i | 13 | ||||
-rw-r--r-- | src/txn/txn.c | 18 | ||||
-rw-r--r-- | src/txn/txn_rollback_to_stable.c | 19 | ||||
-rw-r--r-- | src/txn/txn_timestamp.c | 16 |
5 files changed, 33 insertions, 34 deletions
diff --git a/src/include/txn.h b/src/include/txn.h index f3e377b3380..e0513a82892 100644 --- a/src/include/txn.h +++ b/src/include/txn.h @@ -69,7 +69,6 @@ struct __wt_named_snapshot { struct __wt_txn_state { WT_CACHE_LINE_PAD_BEGIN - WT_RWLOCK rwlock; volatile uint64_t id; volatile uint64_t pinned_id; volatile uint64_t metadata_pinned; diff --git a/src/include/txn.i b/src/include/txn.i index df0bd872a6c..b37163bd78f 100644 --- a/src/include/txn.i +++ b/src/include/txn.i @@ -11,6 +11,8 @@ static inline void __wt_txn_read_last(WT_SESSION_IMPL *session); #ifdef HAVE_TIMESTAMPS #if WT_TIMESTAMP_SIZE == 8 +#define WT_WITH_TIMESTAMP_READLOCK(session, l, e) e + /* * __wt_timestamp_cmp -- * Compare two timestamps. @@ -61,6 +63,12 @@ __wt_timestamp_set_zero(wt_timestamp_t *ts) ts->val = 0; } #else +#define WT_WITH_TIMESTAMP_READLOCK(s, l, e) do { \ + __wt_readlock((s), (l)); \ + e; \ + __wt_readunlock((s), (l)); \ +} while (0) + /* * __wt_timestamp_cmp -- * Compare two timestamps. @@ -314,9 +322,8 @@ __wt_txn_visible_all( if (!txn_global->has_pinned_timestamp || timestamp == NULL) return (true); - __wt_readlock(session, &txn_global->rwlock); - cmp = __wt_timestamp_cmp(timestamp, &txn_global->pinned_timestamp); - __wt_readunlock(session, &txn_global->rwlock); + WT_WITH_TIMESTAMP_READLOCK(session, &txn_global->rwlock, + cmp = __wt_timestamp_cmp(timestamp, &txn_global->pinned_timestamp)); /* * We can discard updates with timestamps less than or equal to the diff --git a/src/txn/txn.c b/src/txn/txn.c index 2aec962d885..09efb2924bf 100644 --- a/src/txn/txn.c +++ b/src/txn/txn.c @@ -445,12 +445,11 @@ __wt_txn_config(WT_SESSION_IMPL *session, const char *cfg[]) WT_RET(__wt_txn_parse_timestamp( session, "read", &txn->read_timestamp, &cval)); - __wt_readlock(session, &txn_global->rwlock); - __wt_timestamp_set( - &oldest_timestamp, &txn_global->oldest_timestamp); - __wt_timestamp_set( - &stable_timestamp, &txn_global->stable_timestamp); - __wt_readunlock(session, &txn_global->rwlock); + WT_WITH_TIMESTAMP_READLOCK(session, &txn_global->rwlock, + __wt_timestamp_set( + &oldest_timestamp, &txn_global->oldest_timestamp); + __wt_timestamp_set( + &stable_timestamp, &txn_global->stable_timestamp)); if (__wt_timestamp_cmp( &txn->read_timestamp, &oldest_timestamp) < 0) WT_RET_MSG(session, EINVAL, @@ -743,10 +742,9 @@ __wt_txn_commit(WT_SESSION_IMPL *session, const char *cfg[]) #ifdef HAVE_TIMESTAMPS /* First check if we've already committed something in the future. */ if (update_timestamp) { - __wt_readlock(session, &txn_global->rwlock); - __wt_timestamp_set( - &prev_commit_timestamp, &txn_global->commit_timestamp); - __wt_readunlock(session, &txn_global->rwlock); + WT_WITH_TIMESTAMP_READLOCK(session, &txn_global->rwlock, + __wt_timestamp_set( + &prev_commit_timestamp, &txn_global->commit_timestamp)); update_timestamp = __wt_timestamp_cmp( &txn->commit_timestamp, &prev_commit_timestamp) > 0; } diff --git a/src/txn/txn_rollback_to_stable.c b/src/txn/txn_rollback_to_stable.c index c9c3d3247c4..e19bbc73bb3 100644 --- a/src/txn/txn_rollback_to_stable.c +++ b/src/txn/txn_rollback_to_stable.c @@ -38,9 +38,9 @@ __txn_rollback_to_stable_lookaside_fixup(WT_SESSION_IMPL *session) * violate protocol. */ txn_global = &conn->txn_global; - __wt_readlock(session, &txn_global->rwlock); - __wt_timestamp_set(&rollback_timestamp, &txn_global->stable_timestamp); - __wt_readunlock(session, &txn_global->rwlock); + WT_WITH_TIMESTAMP_READLOCK(session, &txn_global->rwlock, + __wt_timestamp_set( + &rollback_timestamp, &txn_global->stable_timestamp)); __wt_las_cursor(session, &cursor, &session_flags); @@ -347,9 +347,9 @@ __txn_rollback_to_stable_btree( * updated while rolling back, accessing it without a lock would * violate protocol. */ - __wt_readlock(session, &txn_global->rwlock); - __wt_timestamp_set(&rollback_timestamp, &txn_global->stable_timestamp); - __wt_readunlock(session, &txn_global->rwlock); + WT_WITH_TIMESTAMP_READLOCK(session, &txn_global->rwlock, + __wt_timestamp_set( + &rollback_timestamp, &txn_global->stable_timestamp)); /* * Ensure the eviction server is out of the file - we don't @@ -373,13 +373,10 @@ static int __txn_rollback_to_stable_check(WT_SESSION_IMPL *session) { WT_TXN_GLOBAL *txn_global; - bool stable_set, txn_active; + bool txn_active; txn_global = &S2C(session)->txn_global; - __wt_readlock(session, &txn_global->rwlock); - stable_set = !__wt_timestamp_iszero(&txn_global->stable_timestamp); - __wt_readunlock(session, &txn_global->rwlock); - if (!stable_set) + if (!txn_global->has_stable_timestamp) WT_RET_MSG(session, EINVAL, "rollback_to_stable requires a stable timestamp"); diff --git a/src/txn/txn_timestamp.c b/src/txn/txn_timestamp.c index a947a0167ef..275ef941490 100644 --- a/src/txn/txn_timestamp.c +++ b/src/txn/txn_timestamp.c @@ -196,10 +196,9 @@ __txn_global_query_timestamp( if (WT_STRING_MATCH("all_committed", cval.str, cval.len)) { if (!txn_global->has_commit_timestamp) return (WT_NOTFOUND); - __wt_readlock(session, &txn_global->rwlock); - __wt_timestamp_set(&ts, &txn_global->commit_timestamp); + WT_WITH_TIMESTAMP_READLOCK(session, &txn_global->rwlock, + __wt_timestamp_set(&ts, &txn_global->commit_timestamp)); WT_ASSERT(session, !__wt_timestamp_iszero(&ts)); - __wt_readunlock(session, &txn_global->rwlock); /* Compare with the oldest running transaction. */ __wt_readlock(session, &txn_global->commit_timestamp_rwlock); @@ -234,9 +233,8 @@ __txn_global_query_timestamp( } else if (WT_STRING_MATCH("stable", cval.str, cval.len)) { if (!txn_global->has_stable_timestamp) return (WT_NOTFOUND); - __wt_readlock(session, &txn_global->rwlock); - __wt_timestamp_set(&ts, &txn_global->stable_timestamp); - __wt_readunlock(session, &txn_global->rwlock); + WT_WITH_TIMESTAMP_READLOCK(session, &txn_global->rwlock, + __wt_timestamp_set(&ts, &txn_global->stable_timestamp)); } else WT_RET_MSG(session, EINVAL, "unknown timestamp query %.*s", (int)cval.len, cval.str); @@ -290,9 +288,9 @@ __wt_txn_update_pinned_timestamp(WT_SESSION_IMPL *session) if (txn_global->oldest_is_pinned) return (0); - __wt_readlock(session, &txn_global->rwlock); - __wt_timestamp_set(&oldest_timestamp, &txn_global->oldest_timestamp); - __wt_readunlock(session, &txn_global->rwlock); + WT_WITH_TIMESTAMP_READLOCK(session, &txn_global->rwlock, + __wt_timestamp_set( + &oldest_timestamp, &txn_global->oldest_timestamp)); /* Scan to find the global pinned timestamp. */ if ((ret = __txn_global_query_timestamp( |