From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: From: Vladimir Davydov Subject: [PATCH] txn: convert txn flags into bit mask Date: Mon, 29 Jul 2019 13:52:26 +0300 Message-Id: <7aafa5dcfee6521e4e73cc5f47640b7189b255e3.1564397497.git.vdavydov.dev@gmail.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit To: tarantool-patches@freelists.org List-ID: --- https://github.com/tarantool/tarantool/commits/dv/txn-flags src/box/txn.c | 35 +++++++++++++++++------------------ src/box/txn.h | 38 ++++++++++++++++++++++---------------- 2 files changed, 39 insertions(+), 34 deletions(-) diff --git a/src/box/txn.c b/src/box/txn.c index c7d01b2e..93cc24c2 100644 --- a/src/box/txn.c +++ b/src/box/txn.c @@ -197,10 +197,7 @@ txn_begin() txn->n_new_rows = 0; txn->n_local_rows = 0; txn->n_applier_rows = 0; - txn->has_triggers = false; - txn->is_done = false; - txn->can_yield = true; - txn->is_aborted_by_yield = false; + txn->flags = TXN_CAN_YIELD; txn->in_sub_stmt = 0; txn->id = ++tsn; txn->signature = -1; @@ -396,13 +393,13 @@ txn_complete(struct txn *txn) /* Undo the transaction. */ if (txn->engine) engine_rollback(txn->engine, txn); - if (txn->has_triggers) + if (txn->flags & TXN_HAS_TRIGGERS) txn_run_rollback_triggers(txn); } else { /* Commit the transaction. */ if (txn->engine != NULL) engine_commit(txn->engine, txn); - if (txn->has_triggers) + if (txn->flags & TXN_HAS_TRIGGERS) txn_run_commit_triggers(txn); double stop_tm = ev_monotonic_now(loop()); @@ -422,7 +419,7 @@ txn_complete(struct txn *txn) if (txn->fiber == NULL) txn_free(txn); else { - txn->is_done = true; + txn->flags |= TXN_IS_DONE; if (txn->fiber != fiber()) /* Wake a waiting fiber up. */ fiber_wakeup(txn->fiber); @@ -491,8 +488,8 @@ txn_write_to_wal(struct txn *txn) static int txn_prepare(struct txn *txn) { - if (txn->is_aborted_by_yield) { - assert(!txn->can_yield); + if (txn->flags & TXN_IS_ABORTED_BY_YIELD) { + assert(!(txn->flags & TXN_CAN_YIELD)); diag_set(ClientError, ER_TRANSACTION_YIELD); diag_log(); return -1; @@ -518,7 +515,7 @@ txn_prepare(struct txn *txn) return -1; } trigger_clear(&txn->fiber_on_stop); - if (!txn->can_yield) + if (!(txn->flags & TXN_CAN_YIELD)) trigger_clear(&txn->fiber_on_yield); return 0; } @@ -558,7 +555,7 @@ txn_commit(struct txn *txn) * In case of non-yielding journal the transaction could already * be done and there is nothing to wait in such cases. */ - if (!txn->is_done) { + if (!(txn->flags & TXN_IS_DONE)) { bool cancellable = fiber_set_cancellable(false); fiber_yield(); fiber_set_cancellable(cancellable); @@ -586,7 +583,7 @@ txn_rollback(struct txn *txn) { assert(txn == in_txn()); trigger_clear(&txn->fiber_on_stop); - if (!txn->can_yield) + if (!(txn->flags & TXN_CAN_YIELD)) trigger_clear(&txn->fiber_on_yield); txn->signature = -1; txn_complete(txn); @@ -607,11 +604,13 @@ void txn_can_yield(struct txn *txn, bool set) { assert(txn == in_txn()); - assert(txn->can_yield != set); - txn->can_yield = set; if (set) { + assert(!(txn->flags & TXN_CAN_YIELD)); + txn->flags |= TXN_CAN_YIELD; trigger_clear(&txn->fiber_on_yield); } else { + assert(txn->flags & TXN_CAN_YIELD); + txn->flags &= ~TXN_CAN_YIELD; trigger_create(&txn->fiber_on_yield, txn_on_yield, NULL, NULL); trigger_add(&fiber()->on_yield, &txn->fiber_on_yield); } @@ -781,11 +780,11 @@ txn_on_yield(struct trigger *trigger, void *event) (void) trigger; (void) event; struct txn *txn = in_txn(); - assert(txn != NULL && !txn->can_yield); + assert(txn != NULL && !(txn->flags & TXN_CAN_YIELD)); txn_rollback_to_svp(txn, NULL); - if (txn->has_triggers) { + if (txn->flags & TXN_HAS_TRIGGERS) { txn_run_rollback_triggers(txn); - txn->has_triggers = false; + txn->flags &= ~TXN_HAS_TRIGGERS; } - txn->is_aborted_by_yield = true; + txn->flags |= TXN_IS_ABORTED_BY_YIELD; } diff --git a/src/box/txn.h b/src/box/txn.h index 2d5dea21..d5dceaed 100644 --- a/src/box/txn.h +++ b/src/box/txn.h @@ -51,6 +51,24 @@ struct tuple; struct xrow_header; struct Vdbe; +/** Allowed values for txn::flags. */ +enum { + /** Transaction has been processed. */ + TXN_IS_DONE = 1 << 0, + /** + * Transaction has been aborted by fiber yield so + * should be rolled back at commit. + */ + TXN_IS_ABORTED_BY_YIELD = 1 << 1, + /** + * fiber_yield() is allowed inside the transaction. + * See txn_can_yield() for more details. + */ + TXN_CAN_YIELD = 1 << 2, + /** on_commit and/or on_rollback list is not empty. */ + TXN_HAS_TRIGGERS = 1 << 3, +}; + enum { /** * Maximum recursion depth for on_replace triggers. @@ -160,20 +178,8 @@ struct txn { * already assigned LSN. */ int n_applier_rows; - /* True when transaction is processed. */ - bool is_done; - /** - * True if the transaction was aborted so should be - * rolled back at commit. - */ - bool is_aborted_by_yield; - /** - * True if yields are allowed inside a transaction, - * see txn_can_yield(). - */ - bool can_yield; - /** True if on_commit and on_rollback lists are non-empty. */ - bool has_triggers; + /** Transaction flags, see TXN_*. */ + unsigned flags; /** The number of active nested statement-level transactions. */ int8_t in_sub_stmt; /** @@ -260,10 +266,10 @@ txn_write(struct txn *txn); static inline void txn_init_triggers(struct txn *txn) { - if (txn->has_triggers == false) { + if (!(txn->flags & TXN_HAS_TRIGGERS)) { rlist_create(&txn->on_commit); rlist_create(&txn->on_rollback); - txn->has_triggers = true; + txn->flags |= TXN_HAS_TRIGGERS; } } -- 2.20.1