void *writetx(void *arg){ //do the operations for writing; similar to readTx struct param *node = (struct param*)arg; // struct parameter that contains start_operation(node->tid, node->count); //do the operations for writing; similar to readTx. Write your code zgt_p(0); // Lock Tx manager; zgt_tx *txptr=get_tx(node->tid); if(txptr != NULL){ txptr->print_tm(); if(txptr->status == TR_ABORT){//tx is aborted fprintf(logfile, "T%d\t%c \tWriteTx\n", node->tid, node->Txtype); // Write log record and close fflush(logfile); zgt_v(0); // Release tx manager } else if(txptr->status == TR_ACTIVE){//Tx is active zgt_v(0); // Release tx manager int isLockObtain=txptr->set_lock(node->tid, txptr->sgno,node->obno, node->count,'X');//check is lock available if(isLockObtain == 0){//Lock is obtain for tx txptr->perform_readWrite(txptr->tid,node->obno,'X'); } } } else { zgt_v(0); // Release tx manager printf("Tx is not found it might be committed or not begin at all"); } finish_operation(node->tid); pthread_exit(NULL); // thread exit }
transaction BlockchainDB::get_tx(const crypto::hash& h) const { transaction tx; if (!get_tx(h, tx)) throw TX_DNE(std::string("tx with hash ").append(epee::string_tools::pod_to_hex(h)).append(" not found in db").c_str()); return tx; }
void *committx(void *arg) { //remove the locks before committing struct param *node = (struct param*)arg;// get tid and count start_operation(node->tid, node->count); zgt_tx *txptr=get_tx(node->tid); zgt_p(0); // locking the transaction manager txptr->status=TR_END; do_commit_abort(node->tid,TR_END); zgt_v(0); // releasing the transaction manager finish_operation(node->tid); pthread_exit(NULL); // thread exit }
void BlockchainDB::pop_block(block& blk, std::vector<transaction>& txs) { blk = get_top_block(); remove_block(); for (const auto& h : boost::adaptors::reverse(blk.tx_hashes)) { txs.push_back(get_tx(h)); remove_transaction(h); } remove_transaction(get_transaction_hash(blk.miner_tx)); }
void BlockchainDB::remove_transaction(const crypto::hash& tx_hash) { transaction tx = get_tx(tx_hash); for (const txin_v& tx_input : tx.vin) { if (tx_input.type() == typeid(txin_to_key)) { remove_spent_key(boost::get<txin_to_key>(tx_input).k_image); } } // need tx as tx.vout has the tx outputs, and the output amounts are needed remove_transaction_data(tx_hash, tx); }
// routine that sets the semno in the Tx when another tx waits on it. // the same number is the same as the tx number on which a Tx is waiting int zgt_tx::setTx_semno(long tid, int semno){ zgt_tx *txptr; txptr = get_tx(tid); if (txptr == NULL){ printf("\n:::ERROR:Txid %d wants to wait on sem:%d of tid:%d which does not exist\n", this->tid, semno, tid); fflush(stdout); return(-1); } if (txptr->semno == -1){ txptr->semno = semno; return(0); } else if (txptr->semno != semno){ #ifdef TX_DEBUG printf(":::ERROR Trying to wait on sem:%d, but on Tx:%d\n", semno, txptr->tid); fflush(stdout); #endif exit(1); } return(0); }
void *do_commit_abort(long t, char status){ // write your code zgt_tx *txptr=get_tx(t); if(txptr != NULL){ txptr->free_locks(); // frees all locks held on the object by current transaction zgt_v(t);//v operation on semaphore txptr->end_tx(); //Remove the transaction node if(status == TR_ABORT){ fprintf(logfile, "T%d\t \tAbortTx \t \n",t); // Write log record and close fflush(logfile); } else{ fprintf(logfile, "T%d\t \tCommitTx \t \n",t); // Write log record and close fflush(logfile); } } else{ printf("No Tx found with this tid %d",t); } }
// routine to perform the acutual read/write operation // based on the lockmode void zgt_tx::perform_readWrite(long tid,long obno, char lockmode){ // write your code zgt_p(0); // Lock Tx manager; zgt_tx *txptr=get_tx(tid); if(lockmode == 'S'){ //object value decrement by 1 for read ZGT_Sh->objarray[obno]->value=ZGT_Sh->objarray[obno]->value-1; //use for loop here for(int tmp = ZGT_Sh->optime[tid]; tmp != 0; tmp--){ int count=0; count=count+1; count=count*2; } fprintf(logfile, "T%d\t \tReadTx \t %d:%d:%d \t ReadLock \t Granted \t%c\n",tid,obno,ZGT_Sh->objarray[obno]->value,ZGT_Sh->optime[tid],txptr->status); // Write log record and close fflush(logfile); zgt_v(0); // Release tx manager } else if(lockmode == 'X'){ //object value increment by 1 for write ZGT_Sh->objarray[obno]->value=ZGT_Sh->objarray[obno]->value+1; for(int tmp = ZGT_Sh->optime[tid]; tmp != 0; tmp--){ int count=0; count=count+1; count=count*2; } fprintf(logfile, "T%d\t \tWriteTx \t %d:%d:%d \t WriteLock \t Granted \t%c\n",tid,obno,ZGT_Sh->objarray[obno]->value,ZGT_Sh->optime[tid],txptr->status); // Write log record and close fflush(logfile); zgt_v(0); // Release tx manager } else { printf("\n Error no lockmode set for tx \n"); zgt_v(0); // Release tx manager } }
int zgt_tx::set_lock(long tid1, long sgno1, long obno1, int count, char lockmode1){ //if the thread has to wait, block the thread on a semaphore from the //sempool in the transaction manager. Set the appropriate parameters in the //transaction list if waiting. //if successful return(0); //write your code bool lockGranted = false; while(lockGranted == false){ zgt_p(0); // Lock Tx manager; zgt_tx *txptr = get_tx(tid1); zgt_hlink *linkp = ZGT_Ht->find(sgno1, obno1); txptr->print_tm(); if(linkp == NULL){//Object is not present in hash table ZGT_Ht->add(txptr,sgno1, obno1,lockmode1); lockGranted=true; linkp=ZGT_Ht->find(sgno1, obno1); } else{//Object is present in hash table if(linkp->tid == tid1){ //current tx hold lock so proceed lockGranted=true; } else{ //lock on object is read and tx requesting lock is also read proceed otherwise wait if(get_tx(linkp->tid)->Txtype == 'R' && txptr->Txtype == 'R'){ lockGranted=true; if(txptr->head == NULL) //At Start tx with no object txptr->head=linkp; else{ zgt_hlink* elementInLink= txptr->head; while(elementInLink->nextp!=NULL){ elementInLink=elementInLink->nextp; } elementInLink->nextp=linkp; } } else{ //lock cannot obtain txptr->status = TR_WAIT; txptr->obno = obno1; txptr->lockmode = lockmode1; txptr->setTx_semno(linkp->tid, linkp->tid);//Set semaphore on tx printf("Tx %d is waiting on:T%d\n", txptr->tid,linkp->tid); zgt_v(0); // Release tx manager zgt_p(linkp->tid); //wait on this tx for } } } if(lockGranted){ zgt_v(0); // Release tx manager txptr->status = TR_ACTIVE; txptr->semno = -1; } } return (0); }