int main (int argc, char *argv[]) { try_transaction (); crash_in_transaction (); return 0; }
ErrorStack run(thread::Thread* context) { start_rendezvous.wait(); assorted::UniformRandom rand; rand.set_current_seed(client_id_); Epoch highest_commit_epoch; xct::XctManager* xct_manager = context->get_engine()->get_xct_manager(); xct::XctId prev_xct_id; for (int i = 0; i < kXctsPerThread; ++i) { uint64_t account_id; if (contended) { account_id = rand.next_uint32() % (kBranches * kAccounts); } else { const uint64_t accounts_per_thread = (kBranches * kAccounts / kMaxTestThreads); account_id = rand.next_uint32() % accounts_per_thread + (client_id_ * accounts_per_thread); } uint64_t teller_id = account_id / kAccountsPerTellers; uint64_t branch_id = account_id / kAccounts; uint64_t history_id = client_id_ * kXctsPerThread + i; int64_t amount = rand.uniform_within(kAmountRangeFrom, kAmountRangeTo); EXPECT_GE(amount, kAmountRangeFrom); EXPECT_LE(amount, kAmountRangeTo); while (true) { ErrorStack error_stack = try_transaction(context, &highest_commit_epoch, branch_id, teller_id, account_id, history_id, amount); if (!error_stack.is_error()) { xct::XctId xct_id = context->get_current_xct().get_id(); if (prev_xct_id.get_epoch() == xct_id.get_epoch()) { EXPECT_LT(prev_xct_id.get_ordinal(), xct_id.get_ordinal()); } prev_xct_id = context->get_current_xct().get_id(); break; } else if (error_stack.get_error_code() == kErrorCodeXctRaceAbort) { // abort and retry if (context->get_current_xct().is_active()) { CHECK_ERROR(xct_manager->abort_xct(context)); } } else { COERCE_ERROR(error_stack); } } } CHECK_ERROR(xct_manager->wait_for_commit(highest_commit_epoch)); return foedus::kRetOk; }