void TxnManager::cleanup(RC rc) { #if CC_ALG == OCC && MODE == NORMAL_MODE occ_man.finish(rc,this); #endif ts_t starttime = get_sys_clock(); uint64_t row_cnt = txn->accesses.get_count(); assert(txn->accesses.get_count() == txn->row_cnt); //assert((WORKLOAD == YCSB && row_cnt <= g_req_per_query) || (WORKLOAD == TPCC && row_cnt <= g_max_items_per_txn*2 + 3)); DEBUG("Cleanup %ld %ld\n",get_txn_id(),row_cnt); for (int rid = row_cnt - 1; rid >= 0; rid --) { cleanup_row(rc,rid); } #if CC_ALG == CALVIN // cleanup locked rows for (uint64_t i = 0; i < calvin_locked_rows.size(); i++) { row_t * row = calvin_locked_rows[i]; row->return_row(rc,RD,this,row); } #endif if (rc == Abort) { txn->release_inserts(get_thd_id()); txn->insert_rows.clear(); INC_STATS(get_thd_id(), abort_time, get_sys_clock() - starttime); } }
RC Row_maat::read(TxnManager * txn) { assert (CC_ALG == MAAT); RC rc = RCOK; uint64_t mtx_wait_starttime = get_sys_clock(); while(!ATOM_CAS(maat_avail,true,false)) { } INC_STATS(txn->get_thd_id(),mtx[30],get_sys_clock() - mtx_wait_starttime); DEBUG("READ %ld -- %ld: lw %ld\n",txn->get_txn_id(),_row->get_primary_key(),timestamp_last_write); // Copy uncommitted writes for(auto it = uncommitted_writes->begin(); it != uncommitted_writes->end(); it++) { uint64_t txn_id = *it; txn->uncommitted_writes->insert(txn_id); DEBUG(" UW %ld -- %ld: %ld\n",txn->get_txn_id(),_row->get_primary_key(),txn_id); } // Copy write timestamp if(txn->greatest_write_timestamp < timestamp_last_write) txn->greatest_write_timestamp = timestamp_last_write; //Add to uncommitted reads (soft lock) uncommitted_reads->insert(txn->get_txn_id()); ATOM_CAS(maat_avail,false,true); return rc; }
row_t * txn_man::get_row(row_t * row, access_t type) { if (CC_ALG == HSTORE) return row; uint64_t starttime = get_sys_clock(); RC rc = RCOK; // assert(row_cnt < MAX_ROW_PER_TXN); uint64_t part_id = row->get_part_id(); if (accesses[row_cnt] == NULL) { accesses[row_cnt] = (Access *) mem_allocator.alloc(sizeof(Access), part_id); num_accesses_alloc ++; } rc = row->get_row(type, this, accesses[ row_cnt ]->data); if (rc == Abort) { return NULL; } accesses[row_cnt]->type = type; accesses[row_cnt]->orig_row = row; #if ROLL_BACK && (CC_ALG == DL_DETECT || CC_ALG == NO_WAIT || CC_ALG == WAIT_DIE) if (type == WR) { accesses[row_cnt]->orig_data = (row_t *) mem_allocator.alloc(sizeof(row_t), part_id); accesses[row_cnt]->orig_data->init(row->get_table(), part_id, 0); accesses[row_cnt]->orig_data->copy(row); } #endif row_cnt ++; if (type == WR) wr_cnt ++; uint64_t timespan = get_sys_clock() - starttime; INC_TMP_STATS(get_thd_id(), time_man, timespan); return accesses[row_cnt - 1]->data; }
// FIXME: Rewrite abort queue uint64_t AbortQueue::enqueue(uint64_t thd_id, uint64_t txn_id, uint64_t abort_cnt) { uint64_t starttime = get_sys_clock(); uint64_t penalty = g_abort_penalty; #if BACKOFF penalty = max(penalty * 2^abort_cnt,g_abort_penalty_max); #endif penalty += starttime; //abort_entry * entry = new abort_entry(penalty,txn_id); DEBUG_M("AbortQueue::enqueue entry alloc\n"); abort_entry * entry = (abort_entry*)mem_allocator.alloc(sizeof(abort_entry)); entry->penalty_end = penalty; entry->txn_id = txn_id; uint64_t mtx_time_start = get_sys_clock(); pthread_mutex_lock(&mtx); INC_STATS(thd_id,mtx[0],get_sys_clock() - mtx_time_start); DEBUG("AQ Enqueue %ld %f -- %f\n",entry->txn_id,float(penalty - starttime)/BILLION,simulation->seconds_from_start(starttime)); INC_STATS(thd_id,abort_queue_penalty,penalty - starttime); INC_STATS(thd_id,abort_queue_enqueue_cnt,1); queue.push(entry); pthread_mutex_unlock(&mtx); INC_STATS(thd_id,abort_queue_enqueue_time,get_sys_clock() - starttime); return penalty - starttime; }
void AbortQueue::process(uint64_t thd_id) { if(queue.empty()) return; abort_entry * entry; uint64_t mtx_time_start = get_sys_clock(); pthread_mutex_lock(&mtx); INC_STATS(thd_id,mtx[1],get_sys_clock() - mtx_time_start); uint64_t starttime = get_sys_clock(); while(!queue.empty()) { entry = queue.top(); if(entry->penalty_end < starttime) { queue.pop(); // FIXME: add restart to work queue DEBUG("AQ Dequeue %ld %f -- %f\n",entry->txn_id,float(starttime - entry->penalty_end)/BILLION,simulation->seconds_from_start(starttime)); INC_STATS(thd_id,abort_queue_penalty_extra,starttime - entry->penalty_end); INC_STATS(thd_id,abort_queue_dequeue_cnt,1); Message * msg = Message::create_message(RTXN); msg->txn_id = entry->txn_id; work_queue.enqueue(thd_id,msg,false); //entry = queue.top(); DEBUG_M("AbortQueue::dequeue entry free\n"); mem_allocator.free(entry,sizeof(abort_entry)); } else { break; } } pthread_mutex_unlock(&mtx); INC_STATS(thd_id,abort_queue_dequeue_time,get_sys_clock() - starttime); }
RC YCSBTxnManager::run_txn() { RC rc = RCOK; assert(CC_ALG != CALVIN); if(IS_LOCAL(txn->txn_id) && state == YCSB_0 && next_record_id == 0) { DEBUG("Running txn %ld\n",txn->txn_id); //query->print(); query->partitions_touched.add_unique(GET_PART_ID(0,g_node_id)); } uint64_t starttime = get_sys_clock(); while(rc == RCOK && !is_done()) { rc = run_txn_state(); } uint64_t curr_time = get_sys_clock(); txn_stats.process_time += curr_time - starttime; txn_stats.process_time_short += curr_time - starttime; txn_stats.wait_starttime = get_sys_clock(); if(IS_LOCAL(get_txn_id())) { if(is_done() && rc == RCOK) rc = start_commit(); else if(rc == Abort) rc = start_abort(); } else if(rc == Abort){ rc = abort(); } return rc; }
itemid_t * txn_man::index_read(INDEX * index, idx_key_t key, int part_id) { uint64_t starttime = get_sys_clock(); itemid_t * item; index->index_read(key, item, part_id, get_thd_id()); INC_TMP_STATS(get_thd_id(), time_index, get_sys_clock() - starttime); return item; }
void TxnManager::release_locks(RC rc) { uint64_t starttime = get_sys_clock(); cleanup(rc); uint64_t timespan = (get_sys_clock() - starttime); INC_STATS(get_thd_id(), txn_cleanup_time, timespan); }
bool SimManager::is_warmup_done() { if(warmup) return true; bool done = ((get_sys_clock() - run_starttime) >= g_warmup_timer); if(done) { ATOM_CAS(warmup_end_time,0,get_sys_clock()); ATOM_CAS(warmup,false,true); } return done; }
void TimeTable::set_state(uint64_t thd_id, uint64_t key, MAATState value) { uint64_t idx = hash(key); uint64_t mtx_wait_starttime = get_sys_clock(); pthread_mutex_lock(&table[idx].mtx); INC_STATS(thd_id,mtx[41],get_sys_clock() - mtx_wait_starttime); TimeTableEntry* entry = find(key); if(entry) { entry->state = value; } pthread_mutex_unlock(&table[idx].mtx); }
MAATState TimeTable::get_state(uint64_t thd_id, uint64_t key) { uint64_t idx = hash(key); MAATState state = MAAT_ABORTED; uint64_t mtx_wait_starttime = get_sys_clock(); pthread_mutex_lock(&table[idx].mtx); INC_STATS(thd_id,mtx[40],get_sys_clock() - mtx_wait_starttime); TimeTableEntry* entry = find(key); if(entry) { state = entry->state; } pthread_mutex_unlock(&table[idx].mtx); return state; }
itemid_t * TxnManager::index_read(INDEX * index, idx_key_t key, int part_id, int count) { uint64_t starttime = get_sys_clock(); itemid_t * item; index->index_read(key, count, item, part_id); uint64_t t = get_sys_clock() - starttime; INC_STATS(get_thd_id(), txn_index_time, t); //txn_time_idx += t; return item; }
void TimeTable::release(uint64_t thd_id, uint64_t key) { uint64_t idx = hash(key); uint64_t mtx_wait_starttime = get_sys_clock(); pthread_mutex_lock(&table[idx].mtx); INC_STATS(thd_id,mtx[35],get_sys_clock() - mtx_wait_starttime); TimeTableEntry* entry = find(key); if(entry) { LIST_REMOVE_HT(entry,table[idx].head,table[idx].tail); DEBUG_M("TimeTable::release entry free\n"); mem_allocator.free(entry,sizeof(TimeTableEntry)); } pthread_mutex_unlock(&table[idx].mtx); }
uint64_t TimeTable::get_upper(uint64_t thd_id, uint64_t key) { uint64_t idx = hash(key); uint64_t value = UINT64_MAX; uint64_t mtx_wait_starttime = get_sys_clock(); pthread_mutex_lock(&table[idx].mtx); INC_STATS(thd_id,mtx[37],get_sys_clock() - mtx_wait_starttime); TimeTableEntry* entry = find(key); if(entry) { value = entry->upper; } pthread_mutex_unlock(&table[idx].mtx); return value; }
RC InputThread::server_recv_loop() { myrand rdm; rdm.init(get_thd_id()); RC rc = RCOK; assert (rc == RCOK); uint64_t starttime; std::vector<Message*> * msgs; while (!simulation->is_done()) { heartbeat(); starttime = get_sys_clock(); msgs = tport_man.recv_msg(get_thd_id()); INC_STATS(_thd_id,mtx[28], get_sys_clock() - starttime); starttime = get_sys_clock(); if(msgs == NULL) continue; while(!msgs->empty()) { Message * msg = msgs->front(); if(msg->rtype == INIT_DONE) { msgs->erase(msgs->begin()); continue; } #if CC_ALG == CALVIN if(msg->rtype == CALVIN_ACK ||(msg->rtype == CL_QRY && ISCLIENTN(msg->get_return_id()))) { work_queue.sequencer_enqueue(get_thd_id(),msg); msgs->erase(msgs->begin()); continue; } if( msg->rtype == RDONE || msg->rtype == CL_QRY) { assert(ISSERVERN(msg->get_return_id())); work_queue.sched_enqueue(get_thd_id(),msg); msgs->erase(msgs->begin()); continue; } #endif work_queue.enqueue(get_thd_id(),msg,false); msgs->erase(msgs->begin()); } delete msgs; INC_STATS(_thd_id,mtx[29], get_sys_clock() - starttime); } printf("FINISH %ld:%ld\n",_node_id,_thd_id); fflush(stdout); return FINISH; }
uint64_t TxnTable::get_min_ts(uint64_t thd_id) { uint64_t starttime = get_sys_clock(); uint64_t min_ts = UINT64_MAX; for(uint64_t i = 0 ; i < pool_size; i++) { uint64_t pool_min_ts = pool[i]->min_ts; if(pool_min_ts < min_ts) min_ts = pool_min_ts; } INC_STATS(thd_id,txn_table_min_ts_time,get_sys_clock() - starttime); return min_ts; }
RC txn_man::finish(RC rc) { if (CC_ALG == HSTORE) return RCOK; uint64_t starttime = get_sys_clock(); if (CC_ALG == OCC && rc == RCOK) { // validation phase. rc = occ_man.validate(this); } else cleanup(rc); uint64_t timespan = get_sys_clock() - starttime; INC_TMP_STATS(get_thd_id(), time_man, timespan); INC_STATS(get_thd_id(), time_cleanup, timespan); return rc; }
void TimeTable::init(uint64_t thd_id, uint64_t key) { uint64_t idx = hash(key); uint64_t mtx_wait_starttime = get_sys_clock(); pthread_mutex_lock(&table[idx].mtx); INC_STATS(thd_id,mtx[34],get_sys_clock() - mtx_wait_starttime); TimeTableEntry* entry = find(key); if(!entry) { DEBUG_M("TimeTable::init entry alloc\n"); entry = (TimeTableEntry*) mem_allocator.alloc(sizeof(TimeTableEntry)); entry->init(key); LIST_PUT_TAIL(table[idx].head,table[idx].tail,entry); } pthread_mutex_unlock(&table[idx].mtx); }
RC Row_maat::access(access_t type, TxnManager * txn) { uint64_t starttime = get_sys_clock(); #if WORKLOAD == TPCC read_and_prewrite(txn); #else if(type == RD) read(txn); if(type == WR) prewrite(txn); #endif uint64_t timespan = get_sys_clock() - starttime; txn->txn_stats.cc_time += timespan; txn->txn_stats.cc_time_short += timespan; return RCOK; }
void TxnStats::reset() { wait_starttime=get_sys_clock(); total_process_time += process_time; process_time = 0; total_local_wait_time += local_wait_time; local_wait_time = 0; total_remote_wait_time += remote_wait_time; remote_wait_time = 0; total_twopc_time += twopc_time; twopc_time = 0; write_cnt = 0; total_work_queue_time += work_queue_time; work_queue_time = 0; total_cc_block_time += cc_block_time; cc_block_time = 0; total_cc_time += cc_time; cc_time = 0; total_work_queue_cnt += work_queue_cnt; work_queue_cnt = 0; total_msg_queue_time += msg_queue_time; msg_queue_time = 0; clear_short(); }
void Row_mvcc::update_buffer(TxnManager * txn) { MVReqEntry * ready_read = debuffer_req(R_REQ, NULL); MVReqEntry * req = ready_read; MVReqEntry * tofree = NULL; while (req != NULL) { // find the version for the request MVHisEntry * whis = writehis; while (whis != NULL && whis->ts > req->ts) whis = whis->next; row_t * row = (whis == NULL)? _row : whis->row; req->txn->cur_row = row; insert_history(req->ts, NULL); assert(row->get_data() != NULL); assert(row->get_table() != NULL); assert(row->get_schema() == _row->get_schema()); req->txn->ts_ready = true; uint64_t timespan = get_sys_clock() - req->starttime; req->txn->txn_stats.cc_block_time += timespan; req->txn->txn_stats.cc_block_time_short += timespan; txn_table.restart_txn(txn->get_thd_id(),req->txn->get_txn_id(),0); tofree = req; req = req->next; // free ready_read return_req_entry(tofree); } }
void TxnStats::init() { starttime=0; wait_starttime=get_sys_clock(); total_process_time=0; process_time=0; total_local_wait_time=0; local_wait_time=0; total_remote_wait_time=0; remote_wait_time=0; total_twopc_time=0; twopc_time=0; write_cnt = 0; abort_cnt = 0; total_work_queue_time = 0; work_queue_time = 0; total_cc_block_time = 0; cc_block_time = 0; total_cc_time = 0; cc_time = 0; total_work_queue_cnt = 0; work_queue_cnt = 0; total_msg_queue_time = 0; msg_queue_time = 0; total_abort_time = 0; clear_short(); }
bool SimManager::timeout() { #if TIME_ENABLE return (get_sys_clock() - run_starttime) >= g_done_timer + g_warmup_timer; #else return (get_wall_clock() - run_starttime) >= g_done_timer + g_warmup_timer; #endif }
void SimManager::set_done() { if(ATOM_CAS(sim_done, false, true)) { if(warmup_end_time == 0) warmup_end_time = run_starttime; SET_STATS(0, total_runtime, get_sys_clock() - warmup_end_time); } }
void YCSBQueryGenerator::init() { mrand = (myrand *) mem_allocator.alloc(sizeof(myrand)); mrand->init(get_sys_clock()); if (SKEW_METHOD == ZIPF) { zeta_2_theta = zeta(2, g_zipf_theta); uint64_t table_size = g_synth_table_size / g_part_cnt; the_n = table_size - 1; denom = zeta(the_n, g_zipf_theta); } }
int DL_detect::detect_cycle(uint64_t txnid) { if (g_no_dl) return 0; uint64_t starttime = get_sys_clock(); INC_GLOB_STATS(cycle_detect, 1); bool deadlock = false; int thd = get_thdid_from_txnid(txnid); DetectData * detect_data = (DetectData *) mem_allocator.alloc(sizeof(DetectData), thd); detect_data->visited = (bool * ) mem_allocator.alloc(sizeof(bool) * V, thd); detect_data->recStack = (bool * ) mem_allocator.alloc(sizeof(bool) * V, thd); for(int i = 0; i < V; i++) { detect_data->visited[i] = false; detect_data->recStack[i] = false; } detect_data->min_lock_num = 1000; detect_data->min_txnid = -1; detect_data->loop = false; if ( isCyclic(txnid, detect_data) ){ deadlock = true; INC_GLOB_STATS(deadlock, 1); int thd_to_abort = get_thdid_from_txnid(detect_data->min_txnid); if (dependency[thd_to_abort].txnid == (SInt64) detect_data->min_txnid) { txn_man * txn = glob_manager->get_txn_man(thd_to_abort); txn->lock_abort = true; } } mem_allocator.free(detect_data->visited, sizeof(bool)*V); mem_allocator.free(detect_data->recStack, sizeof(bool)*V); mem_allocator.free(detect_data, sizeof(DetectData)); uint64_t timespan = get_sys_clock() - starttime; INC_GLOB_STATS(dl_detect_time, timespan); if (deadlock) return 1; else return 0; }
RC TxnManager::validate() { #if MODE != NORMAL_MODE return RCOK; #endif if (CC_ALG != OCC && CC_ALG != MAAT) { return RCOK; } RC rc = RCOK; uint64_t starttime = get_sys_clock(); if(CC_ALG == OCC && rc == RCOK) rc = occ_man.validate(this); if(CC_ALG == MAAT && rc == RCOK) { rc = maat_man.validate(this); // Note: home node must be last to validate if(IS_LOCAL(get_txn_id()) && rc == RCOK) { rc = maat_man.find_bound(this); } } INC_STATS(get_thd_id(),txn_validate_time,get_sys_clock() - starttime); return rc; }
void TxnManager::release() { uint64_t prof_starttime = get_sys_clock(); qry_pool.put(get_thd_id(),query); INC_STATS(get_thd_id(),mtx[0],get_sys_clock()-prof_starttime); query = NULL; prof_starttime = get_sys_clock(); txn_pool.put(get_thd_id(),txn); INC_STATS(get_thd_id(),mtx[1],get_sys_clock()-prof_starttime); txn = NULL; #if CC_ALG == MAAT delete uncommitted_writes; delete uncommitted_writes_y; delete uncommitted_reads; #endif #if CC_ALG == CALVIN calvin_locked_rows.release(); #endif txn_ready = true; }
RC Row_maat::abort(access_t type, TxnManager * txn) { uint64_t mtx_wait_starttime = get_sys_clock(); while(!ATOM_CAS(maat_avail,true,false)) { } INC_STATS(txn->get_thd_id(),mtx[32],get_sys_clock() - mtx_wait_starttime); DEBUG("Maat Abort %ld: %d -- %ld\n",txn->get_txn_id(),type,_row->get_primary_key()); #if WORKLOAD == TPCC uncommitted_reads->erase(txn->get_txn_id()); uncommitted_writes->erase(txn->get_txn_id()); #else if(type == RD) { uncommitted_reads->erase(txn->get_txn_id()); } if(type == WR) { uncommitted_writes->erase(txn->get_txn_id()); } #endif ATOM_CAS(maat_avail,false,true); return Abort; }
RC YCSBTxnManager::acquire_locks() { uint64_t starttime = get_sys_clock(); assert(CC_ALG == CALVIN); YCSBQuery* ycsb_query = (YCSBQuery*) query; locking_done = false; RC rc = RCOK; incr_lr(); assert(ycsb_query->requests.size() == g_req_per_query); assert(phase == CALVIN_RW_ANALYSIS); for (uint32_t rid = 0; rid < ycsb_query->requests.size(); rid ++) { ycsb_request * req = ycsb_query->requests[rid]; uint64_t part_id = _wl->key_to_part( req->key ); DEBUG("LK Acquire (%ld,%ld) %d,%ld -> %ld\n",get_txn_id(),get_batch_id(),req->acctype,req->key,GET_NODE_ID(part_id)); if(GET_NODE_ID(part_id) != g_node_id) continue; INDEX * index = _wl->the_index; itemid_t * item; item = index_read(index, req->key, part_id); row_t * row = ((row_t *)item->location); RC rc2 = get_lock(row,req->acctype); if(rc2 != RCOK) { rc = rc2; } } if(decr_lr() == 0) { if(ATOM_CAS(lock_ready,false,true)) rc = RCOK; } txn_stats.wait_starttime = get_sys_clock(); /* if(rc == WAIT && lock_ready_cnt == 0) { if(ATOM_CAS(lock_ready,false,true)) //lock_ready = true; rc = RCOK; } */ INC_STATS(get_thd_id(),calvin_sched_time,get_sys_clock() - starttime); locking_done = true; return rc; }