summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Cahill <michael.cahill@mongodb.com>2015-11-26 11:41:03 +1100
committerMichael Cahill <michael.cahill@mongodb.com>2015-12-02 15:05:51 +1100
commit03985157328c9f29f8f575a03e0023e38ed9bd4c (patch)
tree158966ebe0dc3ffbb7c868551f2abe7738daf79d
parent06a5c7b7a99053110395209c23ff26d39ba22db4 (diff)
downloadmongo-03985157328c9f29f8f575a03e0023e38ed9bd4c.tar.gz
Merge pull request #2337 from wiredtiger/WT-2241
WT-2241 Use a lock to protect transaction ID allocation. (cherry picked from commit 6c7338f2e62d74d59d590a6712eb7e55f2586a8a)
-rw-r--r--src/include/txn.h2
-rw-r--r--src/include/txn.i15
-rw-r--r--src/txn/txn.c11
3 files changed, 13 insertions, 15 deletions
diff --git a/src/include/txn.h b/src/include/txn.h
index 634363b9216..9f9f282bfa4 100644
--- a/src/include/txn.h
+++ b/src/include/txn.h
@@ -34,7 +34,7 @@ struct WT_COMPILER_TYPE_ALIGN(WT_CACHE_LINE_ALIGNMENT) __wt_txn_state {
};
struct __wt_txn_global {
- uint64_t alloc; /* Transaction ID to allocate. */
+ WT_SPINLOCK id_lock;
volatile uint64_t current; /* Current transaction ID. */
/* The oldest running transaction ID (may race). */
diff --git a/src/include/txn.i b/src/include/txn.i
index ceea2e4b581..d7d958e801e 100644
--- a/src/include/txn.i
+++ b/src/include/txn.i
@@ -314,7 +314,6 @@ __wt_txn_id_alloc(WT_SESSION_IMPL *session, bool publish)
{
WT_TXN_GLOBAL *txn_global;
uint64_t id;
- u_int i;
txn_global = &S2C(session)->txn_global;
@@ -341,20 +340,16 @@ __wt_txn_id_alloc(WT_SESSION_IMPL *session, bool publish)
* global current ID, so we want post-increment semantics. Our atomic
* add primitive does pre-increment, so adjust the result here.
*/
- id = __wt_atomic_addv64(&S2C(session)->txn_global.alloc, 1) - 1;
+ __wt_spin_lock(session, &txn_global->id_lock);
+ id = txn_global->current;
if (publish) {
session->txn.id = id;
- WT_SESSION_TXN_STATE(session)->id = id;
+ WT_PUBLISH(WT_SESSION_TXN_STATE(session)->id, id);
}
- for (i = 0; txn_global->current != id; i++)
- if (i < 100)
- WT_PAUSE();
- else
- __wt_yield();
-
- WT_PUBLISH(txn_global->current, id + 1);
+ ++txn_global->current;
+ __wt_spin_unlock(session, &txn_global->id_lock);
return (id);
}
diff --git a/src/txn/txn.c b/src/txn/txn.c
index f89a8ae1b53..f9af9589172 100644
--- a/src/txn/txn.c
+++ b/src/txn/txn.c
@@ -594,8 +594,11 @@ __wt_txn_global_init(WT_SESSION_IMPL *session, const char *cfg[])
conn = S2C(session);
txn_global = &conn->txn_global;
- txn_global->alloc = txn_global->current =
- txn_global->last_running = txn_global->oldest_id = WT_TXN_FIRST;
+ txn_global->current = txn_global->last_running =
+ txn_global->oldest_id = WT_TXN_FIRST;
+
+ WT_RET(__wt_spin_init(session,
+ &txn_global->id_lock, "transaction id lock"));
WT_RET(__wt_calloc_def(
session, conn->session_size, &txn_global->states));
@@ -618,6 +621,6 @@ __wt_txn_global_destroy(WT_SESSION_IMPL *session)
conn = S2C(session);
txn_global = &conn->txn_global;
- if (txn_global != NULL)
- __wt_free(session, txn_global->states);
+ __wt_spin_destroy(session, &txn_global->id_lock);
+ __wt_free(session, txn_global->states);
}