Commit b2129ebb authored by Yoni Fogel's avatar Yoni Fogel

[t:5064] Closes #5064 Move most of the work of creating xids (including...

[t:5064] Closes #5064 Move most of the work of creating xids (including malloc) out of the txn_manager_lock

git-svn-id: file:///svn/toku/tokudb@44892 c7de825b-a66e-492c-adef-691d508d4ae1
parent 665f1acf
...@@ -118,6 +118,7 @@ toku_txn_create_txn ( ...@@ -118,6 +118,7 @@ toku_txn_create_txn (
TOKULOGGER logger, TOKULOGGER logger,
TXN_SNAPSHOT_TYPE snapshot_type, TXN_SNAPSHOT_TYPE snapshot_type,
DB_TXN *container_db_txn, DB_TXN *container_db_txn,
XIDS xids,
bool for_checkpoint bool for_checkpoint
) )
{ {
...@@ -164,7 +165,7 @@ toku_txn_create_txn ( ...@@ -164,7 +165,7 @@ toku_txn_create_txn (
.do_fsync_lsn = ZERO_LSN, .do_fsync_lsn = ZERO_LSN,
.txnid64 = TXNID_NONE, .txnid64 = TXNID_NONE,
.ancestor_txnid64 = TXNID_NONE, .ancestor_txnid64 = TXNID_NONE,
.xids = NULL, .xids = xids,
.roll_info = roll_info, .roll_info = roll_info,
.num_pin = 0 .num_pin = 0
}; };
...@@ -184,13 +185,12 @@ toku_txn_create_txn ( ...@@ -184,13 +185,12 @@ toku_txn_create_txn (
} }
void void
toku_txn_update_xids_in_txn(TOKUTXN txn, TXNID xid, XIDS xids) toku_txn_update_xids_in_txn(TOKUTXN txn, TXNID xid)
{ {
// these should not have been set yet // these should not have been set yet
invariant(txn->txnid64 == TXNID_NONE); invariant(txn->txnid64 == TXNID_NONE);
invariant(txn->ancestor_txnid64 == TXNID_NONE); invariant(txn->ancestor_txnid64 == TXNID_NONE);
invariant(txn->snapshot_txnid64 == TXNID_NONE); invariant(txn->snapshot_txnid64 == TXNID_NONE);
invariant(txn->xids == NULL);
TXNID snapshot_txnid64; TXNID snapshot_txnid64;
if (txn->snapshot_type == TXN_SNAPSHOT_NONE) { if (txn->snapshot_type == TXN_SNAPSHOT_NONE) {
...@@ -211,7 +211,6 @@ toku_txn_update_xids_in_txn(TOKUTXN txn, TXNID xid, XIDS xids) ...@@ -211,7 +211,6 @@ toku_txn_update_xids_in_txn(TOKUTXN txn, TXNID xid, XIDS xids)
UNCONST(TXNID, txn->txnid64) = xid; UNCONST(TXNID, txn->txnid64) = xid;
UNCONST(TXNID, txn->snapshot_txnid64) = snapshot_txnid64; UNCONST(TXNID, txn->snapshot_txnid64) = snapshot_txnid64;
UNCONST(TXNID, txn->ancestor_txnid64) = (txn->parent ? txn->parent->ancestor_txnid64 : xid); UNCONST(TXNID, txn->ancestor_txnid64) = (txn->parent ? txn->parent->ancestor_txnid64 : xid);
txn->xids = xids;
#undef UNCONST #undef UNCONST
} }
......
...@@ -39,8 +39,8 @@ int toku_txn_begin_with_xid ( ...@@ -39,8 +39,8 @@ int toku_txn_begin_with_xid (
); );
// Allocate and initialize a txn // Allocate and initialize a txn
int toku_txn_create_txn(TOKUTXN *txn_ptr, TOKUTXN parent, TOKULOGGER logger, TXN_SNAPSHOT_TYPE snapshot_type, DB_TXN *container_db_txn, bool for_checkpoint); int toku_txn_create_txn(TOKUTXN *txn_ptr, TOKUTXN parent, TOKULOGGER logger, TXN_SNAPSHOT_TYPE snapshot_type, DB_TXN *container_db_txn, XIDS xids, bool for_checkpoint);
void toku_txn_update_xids_in_txn(TOKUTXN txn, TXNID xid, XIDS xids); void toku_txn_update_xids_in_txn(TOKUTXN txn, TXNID xid);
int toku_txn_load_txninfo (TOKUTXN txn, TXNINFO info); int toku_txn_load_txninfo (TOKUTXN txn, TXNINFO info);
......
...@@ -359,16 +359,22 @@ int toku_txn_manager_start_txn( ...@@ -359,16 +359,22 @@ int toku_txn_manager_start_txn(
bool for_recovery) bool for_recovery)
{ {
int r; int r;
XIDS xids;
TOKUTXN txn;
// Do as much (safe) work as possible before serializing on the txn_manager lock. // Do as much (safe) work as possible before serializing on the txn_manager lock.
XIDS parent_xids; XIDS parent_xids;
if (parent == NULL) if (parent == NULL) {
parent_xids = xids_get_root_xids(); parent_xids = xids_get_root_xids();
else } else {
parent_xids = parent->xids; parent_xids = parent->xids;
}
r = xids_create_unknown_child(parent_xids, &xids);
if (r != 0) {
return r;
}
TOKUTXN txn; r = toku_txn_create_txn(&txn, parent, logger, snapshot_type, container_db_txn, xids, for_recovery);
r = toku_txn_create_txn(&txn, parent, logger, snapshot_type, container_db_txn, for_recovery);
if (r != 0) { if (r != 0) {
// logger is panicked // logger is panicked
return r; return r;
...@@ -393,11 +399,9 @@ int toku_txn_manager_start_txn( ...@@ -393,11 +399,9 @@ int toku_txn_manager_start_txn(
invariant(for_recovery); invariant(for_recovery);
txn_manager->last_xid = max_xid(txn_manager->last_xid, xid); txn_manager->last_xid = max_xid(txn_manager->last_xid, xid);
} }
XIDS xids; xids_finalize_with_child(txn->xids, xid);
r = xids_create_child(parent_xids, &xids, xid);
assert_zero(r);
toku_txn_update_xids_in_txn(txn, xid, xids); toku_txn_update_xids_in_txn(txn, xid);
if (!for_recovery) { if (!for_recovery) {
// TODO(leif): this would be WRONG during recovery. We cannot // TODO(leif): this would be WRONG during recovery. We cannot
......
...@@ -60,37 +60,50 @@ xids_get_root_xids(void) { ...@@ -60,37 +60,50 @@ xids_get_root_xids(void) {
XIDS rval = (XIDS)&root_xids; XIDS rval = (XIDS)&root_xids;
return rval; return rval;
} }
// xids is immutable. This function creates a new xids by copying the inline int
// parent's list and then appending the xid of the new transaction. xids_create_unknown_child(XIDS parent_xids, XIDS *xids_p) {
int // Postcondition:
xids_create_child(XIDS parent_xids, // xids list for parent transaction // xids_p points to an xids that is an exact copy of parent_xids, but with room for one more xid.
XIDS * xids_p, // xids list created
TXNID this_xid) { // xid of this transaction (new innermost)
int rval; int rval;
invariant(parent_xids); invariant(parent_xids);
invariant(this_xid > xids_get_innermost_xid(parent_xids));
u_int32_t num_child_xids = parent_xids->num_xids + 1; u_int32_t num_child_xids = parent_xids->num_xids + 1;
invariant(num_child_xids > 0); invariant(num_child_xids > 0);
invariant(num_child_xids <= MAX_TRANSACTION_RECORDS); invariant(num_child_xids <= MAX_TRANSACTION_RECORDS);
if (num_child_xids == MAX_TRANSACTION_RECORDS) rval = EINVAL; if (num_child_xids == MAX_TRANSACTION_RECORDS) rval = EINVAL;
else { else {
XIDS xids = toku_malloc(sizeof(*xids) + num_child_xids*sizeof(xids->ids[0])); size_t new_size = sizeof(*parent_xids) + num_child_xids*sizeof(parent_xids->ids[0]);
if (!xids) rval = ENOMEM; XIDS xids = toku_xmalloc(new_size);
else { // Clone everything (parent does not have the newest xid).
// comment: invariant (num_child_xids <= MAX_TRANSACTION_RECORDS) memcpy(xids, parent_xids, new_size - sizeof(xids->ids[0]));
// makes this cast ok *xids_p = xids;
xids->num_xids = (u_int8_t)num_child_xids; rval = 0;
memcpy(xids->ids, }
parent_xids->ids, return rval;
parent_xids->num_xids*sizeof(parent_xids->ids[0])); }
TXNID this_xid_disk = toku_htod64(this_xid);
xids->ids[num_child_xids-1] = this_xid_disk; void
*xids_p = xids; xids_finalize_with_child(XIDS xids, TXNID this_xid) {
rval = 0; // Precondition:
} // - xids was created by xids_create_unknown_child
// - All error checking (except that this_xid is higher than its parent) is already complete
invariant(this_xid > xids_get_innermost_xid(xids));
TXNID this_xid_disk = toku_htod64(this_xid);
u_int32_t num_child_xids = ++xids->num_xids;
xids->ids[num_child_xids - 1] = this_xid_disk;
}
// xids is immutable. This function creates a new xids by copying the
// parent's list and then appending the xid of the new transaction.
int
xids_create_child(XIDS parent_xids, // xids list for parent transaction
XIDS * xids_p, // xids list created
TXNID this_xid) { // xid of this transaction (new innermost)
int rval = xids_create_unknown_child(parent_xids, xids_p);
if (rval == 0) {
xids_finalize_with_child(*xids_p, this_xid);
} }
return rval; return rval;
} }
......
...@@ -36,6 +36,12 @@ void xids_cpy(XIDS target, XIDS source); ...@@ -36,6 +36,12 @@ void xids_cpy(XIDS target, XIDS source);
//Creates an XIDS representing this transaction. //Creates an XIDS representing this transaction.
//You must pass in an XIDS representing the parent of this transaction. //You must pass in an XIDS representing the parent of this transaction.
int xids_create_child(XIDS parent_xids, XIDS *xids_p, TXNID this_xid); int xids_create_child(XIDS parent_xids, XIDS *xids_p, TXNID this_xid);
// The following two functions (in order) are equivalent to xids_create child,
// but allow you to do most of the work without knowing the new xid.
int xids_create_unknown_child(XIDS parent_xids, XIDS *xids_p);
void xids_finalize_with_child(XIDS xids, TXNID this_xid);
void xids_create_from_buffer(struct rbuf *rb, XIDS * xids_p); void xids_create_from_buffer(struct rbuf *rb, XIDS * xids_p);
void xids_destroy(XIDS *xids_p); void xids_destroy(XIDS *xids_p);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment