From ae429b4e8fa8cdd92a4a4159b4c8d0c34b2613af Mon Sep 17 00:00:00 2001 From: bdemsky Date: Fri, 9 Oct 2009 17:38:35 +0000 Subject: [PATCH] more reorg --- Robust/src/Runtime/STM/commit.c | 955 +++++++++++++++++++++++++++++ Robust/src/Runtime/STM/stats.c | 39 +- Robust/src/Runtime/STM/stm.c | 1009 ------------------------------- Robust/src/Runtime/STM/tm.h | 34 ++ 4 files changed, 1005 insertions(+), 1032 deletions(-) create mode 100644 Robust/src/Runtime/STM/commit.c diff --git a/Robust/src/Runtime/STM/commit.c b/Robust/src/Runtime/STM/commit.c new file mode 100644 index 00000000..a9d545e8 --- /dev/null +++ b/Robust/src/Runtime/STM/commit.c @@ -0,0 +1,955 @@ +#include + +/* ================================================================ + * transCommit + * - This function initiates the transaction commit process + * - goes through the transaction cache and decides + * - a final response + * ================================================================ + */ +#ifdef DELAYCOMP +int transCommit(void (*commitmethod)(void *, void *, void *), void * primitives, void * locals, void * params) { +#else +int transCommit() { +#endif +#ifdef SANDBOX + abortenabled=0; +#endif +#ifdef TRANSSTATS + numTransCommit++; +#endif + int softaborted=0; + do { + /* Look through all the objects in the transaction hash table */ + int finalResponse; +#ifdef DELAYCOMP + if (c_numelements<(c_size>>3)) + finalResponse= alttraverseCache(commitmethod, primitives, locals, params); + else + finalResponse= traverseCache(commitmethod, primitives, locals, params); +#else + if (c_numelements<(c_size>>3)) + finalResponse= alttraverseCache(); + else + finalResponse= traverseCache(); +#endif + if(finalResponse == TRANS_ABORT) { +#ifdef TRANSSTATS + numTransAbort++; + if (softaborted) { + nSoftAbortAbort++; + } +#endif + freenewobjs(); +#ifdef STMSTATS + freelockedobjs(); +#endif + objstrReset(); + t_chashreset(); +#ifdef READSET + rd_t_chashreset(); +#endif +#ifdef DELAYCOMP + dc_t_chashreset(); + ptrstack.count=0; + primstack.count=0; + branchstack.count=0; +#endif +#ifdef SANDBOX + abortenabled=1; +#endif + return TRANS_ABORT; + } + if(finalResponse == TRANS_COMMIT) { +#ifdef TRANSSTATS + //numTransCommit++; + if (softaborted) { + nSoftAbortCommit++; + } +#endif + freenewobjs(); +#ifdef STMSTATS + freelockedobjs(); +#endif + objstrReset(); + t_chashreset(); +#ifdef READSET + rd_t_chashreset(); +#endif +#ifdef DELAYCOMP + dc_t_chashreset(); + ptrstack.count=0; + primstack.count=0; + branchstack.count=0; +#endif + return 0; + } + + /* wait a random amount of time before retrying to commit transaction*/ + if(finalResponse == TRANS_SOFT_ABORT) { +#ifdef TRANSSTATS + nSoftAbort++; +#endif + softaborted++; +#ifdef SOFTABORT + if (softaborted>1) { +#else + if (1) { +#endif + //retry if too many soft aborts + freenewobjs(); +#ifdef STMSTATS + freelockedobjs(); +#endif + objstrReset(); + t_chashreset(); +#ifdef READSET + rd_t_chashreset(); +#endif +#ifdef DELAYCOMP + dc_t_chashreset(); + ptrstack.count=0; + primstack.count=0; + branchstack.count=0; +#endif + return TRANS_ABORT; + } + //randomdelay(softaborted); + } else { + printf("Error: in %s() Unknown outcome", __func__); + exit(-1); + } + } while (1); +} + +#ifdef STMSTATS + You need to add free statements for oidrdage in a way that they will not appear if this option is not defined. +#endif + +#ifdef DELAYCOMP +#define freearrays if (c_numelements>=200) { \ + free(oidrdlocked); \ + free(oidrdversion); \ + } \ + if (t_numelements>=200) { \ + free(oidwrlocked); \ + } +#else +#define freearrays if (c_numelements>=200) { \ + free(oidrdlocked); \ + free(oidrdversion); \ + free(oidwrlocked); \ + } +#endif + +#ifdef STMSTATS + you need to set oidrdage in a way that does not appear if this macro is not defined. +#endif + +#ifdef DELAYCOMP +#define allocarrays int t_numelements=c_numelements+dc_c_numelements; \ + if (t_numelements<200) { \ + oidwrlocked=wrlocked; \ + } else { \ + oidwrlocked=malloc(t_numelements*sizeof(void *)); \ + } \ + if (c_numelements<200) { \ + oidrdlocked=rdlocked; \ + oidrdversion=rdversion; \ + } else { \ + int size=c_numelements*sizeof(void*); \ + oidrdlocked=malloc(size); \ + oidrdversion=malloc(size); \ + } +#else +#define allocarrays if (c_numelements<200) { \ + oidrdlocked=rdlocked; \ + oidrdversion=rdversion; \ + oidwrlocked=wrlocked; \ + } else { \ + int size=c_numelements*sizeof(void*); \ + oidrdlocked=malloc(size); \ + oidrdversion=malloc(size); \ + oidwrlocked=malloc(size); \ + } +#endif + +/* ================================================== + * traverseCache + * - goes through the transaction cache and + * - decides if a transaction should commit or abort + * ================================================== + */ +#ifdef DELAYCOMP +int traverseCache(void (*commitmethod)(void *, void *, void *), void * primitives, void * locals, void * params) { +#else +int traverseCache() { +#endif + /* Create info to keep track of objects that can be locked */ + int numoidrdlocked=0; + int numoidwrlocked=0; + void * rdlocked[200]; + int rdversion[200]; + void * wrlocked[200]; + int softabort=0; + int i; + void ** oidrdlocked; + void ** oidwrlocked; +#ifdef STMSTATS + int rdage[200]; + int * oidrdage; + int ObjSeqId; + int objtypetraverse[TOTALNUMCLASSANDARRAY]; +#endif + int * oidrdversion; + allocarrays; + +#ifdef STMSTATS + for(i=0; ikey == NULL) + break; + objheader_t * headeraddr=&((objheader_t *) curr->val)[-1]; //cached object + objheader_t *header=(objheader_t *)(((char *)curr->key)-sizeof(objheader_t)); //real object + unsigned int version = headeraddr->version; + + if(STATUS(headeraddr) & DIRTY) { + /* Read from the main heap and compare versions */ + if(write_trylock(&header->lock)) { //can aquire write lock + if (version == header->version) { /* versions match */ + /* Keep track of objects locked */ + oidwrlocked[numoidwrlocked++] = header; + } else { + oidwrlocked[numoidwrlocked++] = header; + transAbortProcess(oidwrlocked, numoidwrlocked); +#ifdef STMSTATS + header->abortCount++; + ObjSeqId = headeraddr->accessCount; + (typesCausingAbort[TYPE(header)]).numabort++; + (typesCausingAbort[TYPE(header)]).numaccess+=c_numelements; + (typesCausingAbort[TYPE(header)]).numtrans+=1; + objtypetraverse[TYPE(header)]=1; + getTotalAbortCount(i+1, size, (void *)(curr->next), numoidrdlocked, oidrdlocked, oidrdversion, oidrdage, ObjSeqId, header, objtypetraverse); +#endif + DEBUGSTM("WR Abort: rd: %u wr: %u tot: %u type: %u ver: %u\n", numoidrdlocked, numoidwrlocked, c_numelements, TYPE(header), header->version); + DEBUGSTMSTAT("WR Abort: Access Count: %u AbortCount: %u type: %u ver: %u \n", header->accessCount, header->abortCount, TYPE(header), header->version); + freearrays; + if (softabort) + return TRANS_SOFT_ABORT; + else + return TRANS_ABORT; + } + } else { + if(version == header->version) { + /* versions match */ + softabort=1; + } + transAbortProcess(oidwrlocked, numoidwrlocked); +#ifdef STMSTATS + header->abortCount++; + ObjSeqId = headeraddr->accessCount; + (typesCausingAbort[TYPE(header)]).numabort++; + (typesCausingAbort[TYPE(header)]).numaccess+=c_numelements; + (typesCausingAbort[TYPE(header)]).numtrans+=1; + objtypetraverse[TYPE(header)]=1; + //(typesCausingAbort[TYPE(header)])++; +#endif +#if defined(STMSTATS)||defined(SOFTABORT) + if(getTotalAbortCount(i+1, size, (void *)(curr->next), numoidrdlocked, oidrdlocked, oidrdversion, oidrdage, ObjSeqId, header, objtypetraverse)) + softabort=0; +#endif + DEBUGSTM("WR Abort: rd: %u wr: %u tot: %u type: %u ver: %u\n", numoidrdlocked, numoidwrlocked, c_numelements, TYPE(header), header->version); + DEBUGSTMSTAT("WR Abort: Access Count: %u AbortCount: %u type: %u ver: %u \n", header->accessCount, header->abortCount, TYPE(header), header->version); + freearrays; + if (softabort) + return TRANS_SOFT_ABORT; + else + return TRANS_ABORT; + + } + } else { +#ifdef STMSTATS + oidrdage[numoidrdlocked]=headeraddr->accessCount; +#endif + oidrdversion[numoidrdlocked]=version; + oidrdlocked[numoidrdlocked++]=header; + } + curr = curr->next; + } + } //end of for + +#ifdef DELAYCOMP + //acquire access set locks + unsigned int numoidwrtotal=numoidwrlocked; + + chashlistnode_t *dc_curr = dc_c_list; + /* Inner loop to traverse the linked list of the cache lookupTable */ + while(likely(dc_curr != NULL)) { + //if the first bin in hash table is empty + objheader_t * headeraddr=&((objheader_t *) dc_curr->val)[-1]; + objheader_t *header=(objheader_t *)(((char *)dc_curr->key)-sizeof(objheader_t)); + if(write_trylock(&header->lock)) { //can aquire write lock + oidwrlocked[numoidwrtotal++] = header; + } else { + //maybe we already have lock + void * key=dc_curr->key; + chashlistnode_t *node = &c_table[(((unsigned INTPTR)key) & c_mask)>>4]; + + do { + if(node->key == key) { + objheader_t * headeraddr=&((objheader_t *) node->val)[-1]; + if(STATUS(headeraddr) & DIRTY) { + goto nextloop; + } else + break; + } + node = node->next; + } while(node != NULL); + + //have to abort to avoid deadlock + transAbortProcess(oidwrlocked, numoidwrtotal); +#ifdef STMSTATS + ObjSeqId = headeraddr->accessCount; + header->abortCount++; + (typesCausingAbort[TYPE(header)]).numabort++; + (typesCausingAbort[TYPE(header)]).numaccess+=c_numelements; + (typesCausingAbort[TYPE(header)]).numtrans+=1; + objtypetraverse[TYPE(header)]=1; +#endif +#if defined(STMSTATS)||defined(SOFTABORT) + if(getTotalAbortCount(i+1, size, (void *)(curr->next), numoidrdlocked, oidrdlocked, oidrdversion, oidrdage, ObjSeqId, header, objtypetraverse)) + softabort=0; +#endif + DEBUGSTM("WR Abort: rd: %u wr: %u tot: %u type: %u ver: %u\n", numoidrdlocked, numoidwrlocked, c_numelements, TYPE(header), header->version); + DEBUGSTMSTAT("WR Abort: Access Count: %u AbortCount: %u type: %u ver: %u \n", header->accessCount, header->abortCount, TYPE(header), header->version); + freearrays; + if (softabort) + return TRANS_SOFT_ABORT; + else + return TRANS_ABORT; + } + nextloop: + dc_curr = dc_curr->lnext; + } +#endif + + //THIS IS THE SERIALIZATION END POINT (START POINT IS END OF EXECUTION)***** + + for(i=0; ilock>0) { //not write locked + CFENCE; + if(version != header->version) { /* versions do not match */ +#ifdef DELAYCOMP + transAbortProcess(oidwrlocked, numoidwrtotal); +#else + transAbortProcess(oidwrlocked, numoidwrlocked); +#endif +#ifdef STMSTATS + ObjSeqId = oidrdage[i]; + header->abortCount++; + (typesCausingAbort[TYPE(header)]).numabort++; + (typesCausingAbort[TYPE(header)]).numaccess+=c_numelements; + (typesCausingAbort[TYPE(header)]).numtrans+=1; + objtypetraverse[TYPE(header)]=1; + getReadAbortCount(i+1, numoidrdlocked, oidrdlocked, oidrdversion, oidrdage, ObjSeqId, header, objtypetraverse); +#endif + DEBUGSTM("RD Abort: rd: %u wr: %u tot: %u type: %u ver: %u oid: %x\n", numoidrdlocked, numoidwrlocked, c_numelements, TYPE(header), header->version, OID(header)); + DEBUGSTMSTAT("RD Abort: Access Count: %u AbortCount: %u type: %u ver: %u \n", header->accessCount, header->abortCount, TYPE(header), header->version); + freearrays; + return TRANS_ABORT; + } +#if DELAYCOMP + } else if (dc_t_chashSearch(((char *)header)+sizeof(objheader_t))!=NULL) { + //couldn't get lock because we already have it + //check if it is the right version number + if (version!=header->version) { + transAbortProcess(oidwrlocked, numoidwrtotal); +#ifdef STMSTATS + ObjSeqId = oidrdage[i]; + header->abortCount++; + (typesCausingAbort[TYPE(header)]).numabort++; + (typesCausingAbort[TYPE(header)]).numaccess+=c_numelements; + (typesCausingAbort[TYPE(header)]).numtrans+=1; + objtypetraverse[TYPE(header)]=1; + getReadAbortCount(i+1, numoidrdlocked, oidrdlocked, oidrdversion, oidrdage, ObjSeqId, header, objtypetraverse); +#endif + DEBUGSTM("RD Abort: rd: %u wr: %u tot: %u type: %u ver: %u, oid: %x\n", numoidrdlocked, numoidwrlocked, c_numelements, TYPE(header), header->version, OID(header)); + DEBUGSTMSTAT("RD Abort: Access Count: %u AbortCount: %u type: %u ver: %u \n", header->accessCount, header->abortCount, TYPE(header), header->version); + freearrays; + return TRANS_ABORT; + } +#endif + } else { /* cannot aquire lock */ + //do increment as we didn't get lock + if(version == header->version) { + softabort=1; + } +#ifdef DELAYCOMP + transAbortProcess(oidwrlocked, numoidwrtotal); +#else + transAbortProcess(oidwrlocked, numoidwrlocked); +#endif +#ifdef STMSTATS + ObjSeqId = oidrdage[i]; + header->abortCount++; + (typesCausingAbort[TYPE(header)]).numabort++; + (typesCausingAbort[TYPE(header)]).numaccess+=c_numelements; + (typesCausingAbort[TYPE(header)]).numtrans+=1; + objtypetraverse[TYPE(header)]=1; +#endif +#if defined(STMSTATS)||defined(SOFTABORT) + if(getReadAbortCount(i+1, numoidrdlocked, oidrdlocked, oidrdversion, oidrdage, ObjSeqId, header, objtypetraverse)) + softabort=0; +#endif + DEBUGSTM("RD Abort: rd: %u wr: %u tot: %u type: %u ver: %u oid: %x\n", numoidrdlocked, numoidwrlocked, c_numelements, TYPE(header), header->version, OID(header)); + DEBUGSTMSTAT("RD Abort: Access Count: %u AbortCount: %u type: %u ver: %u \n", header->accessCount, header->abortCount, TYPE(header), header->version); + freearrays; + if (softabort) + return TRANS_SOFT_ABORT; + else + return TRANS_ABORT; + } + } + +#ifdef READSET + //need to validate auxilary readset + rdchashlistnode_t *rd_curr = rd_c_list; + /* Inner loop to traverse the linked list of the cache lookupTable */ + while(likely(rd_curr != NULL)) { + //if the first bin in hash table is empty + unsigned int version=rd_curr->version; + objheader_t *header=(objheader_t *)(((char *)rd_curr->key)-sizeof(objheader_t)); + if(header->lock>0) { //object is not locked + if (version!=header->version) { + //have to abort +#ifdef DELAYCOMP + transAbortProcess(oidwrlocked, numoidwrtotal); +#else + transAbortProcess(oidwrlocked, numoidwrlocked); +#endif +#ifdef STMSTATS + //ABORTCOUNT(header); + (typesCausingAbort[TYPE(header)])++; +#endif +#if defined(STMSTATS)||defined(SOFTABORT) + //if(getTotalAbortCount2((void *) curr->next, numoidrdlocked, oidrdlocked, oidrdversion)) + // softabort=0; +#endif + DEBUGSTM("WR Abort: rd: %u wr: %u tot: %u type: %u ver: %u oid: %x\n", numoidrdlocked, numoidwrlocked, c_numelements, TYPE(header), header->version, OID(header)); + DEBUGSTMSTAT("WR Abort: Access Count: %u AbortCount: %u type: %u ver: %u \n", header->accessCount, header->abortCount, TYPE(header), header->version); + freearrays; + if (softabort) + return TRANS_SOFT_ABORT; + else + return TRANS_ABORT; + } + } else { + //maybe we already have lock + if (version==header->version) { + void * key=rd_curr->key; +#ifdef DELAYCOMP + //check to see if it is in the delaycomp table + { + chashlistnode_t *node = &dc_c_table[(((unsigned INTPTR)key) & dc_c_mask)>>4]; + do { + if(node->key == key) + goto nextloopread; + node = node->next; + } while(node != NULL); + } +#endif + //check normal table + { + chashlistnode_t *node = &c_table[(((unsigned INTPTR)key) & c_mask)>>4]; + do { + if(node->key == key) { + objheader_t * headeraddr=&((objheader_t *) node->val)[-1]; + if(STATUS(headeraddr) & DIRTY) { + goto nextloopread; + } + } + node = node->next; + } while(node != NULL); + } + } +#ifdef DELAYCOMP + //have to abort to avoid deadlock + transAbortProcess(oidwrlocked, numoidwrtotal); +#else + transAbortProcess(oidwrlocked, numoidwrlocked); +#endif + +#ifdef STMSTATS + //ABORTCOUNT(header); + (typesCausingAbort[TYPE(header)])++; +#endif +#if defined(STMSTATS)||defined(SOFTABORT) + //if(getTotalAbortCount2((void *) curr->next, numoidrdlocked, oidrdlocked, oidrdversion)) + //softabort=0; +#endif + DEBUGSTM("WR Abort: rd: %u wr: %u tot: %u type: %u ver: %u oid: %x\n", numoidrdlocked, numoidwrlocked, c_numelements, TYPE(header), header->version, OID(header)); + DEBUGSTMSTAT("WR Abort: Access Count: %u AbortCount: %u type: %u ver: %u \n", header->accessCount, header->abortCount, TYPE(header), header->version); + freearrays; + if (softabort) + return TRANS_SOFT_ABORT; + else + return TRANS_ABORT; + } + nextloopread: + rd_curr = rd_curr->lnext; + } +#endif + + /* Decide the final response */ +#ifdef DELAYCOMP + transCommitProcess(oidwrlocked, numoidwrlocked, numoidwrtotal, commitmethod, primitives, locals, params); +#else + transCommitProcess(oidwrlocked, numoidwrlocked); +#endif + DEBUGSTM("Commit: rd: %u wr: %u tot: %u\n", numoidrdlocked, numoidwrlocked, c_numelements); + freearrays; + return TRANS_COMMIT; +} + +/* ================================================== + * alttraverseCache + * - goes through the transaction cache and + * - decides if a transaction should commit or abort + * ================================================== + */ + +#ifdef DELAYCOMP +int alttraverseCache(void (*commitmethod)(void *, void *, void *), void * primitives, void * locals, void * params) { +#else +int alttraverseCache() { +#endif + /* Create info to keep track of objects that can be locked */ + int numoidrdlocked=0; + int numoidwrlocked=0; + void * rdlocked[200]; + int rdversion[200]; + void * wrlocked[200]; + int softabort=0; + int i; + void ** oidrdlocked; + int * oidrdversion; +#ifdef STMSTATS + int rdage[200]; + int * oidrdage; + int ObjSeqId; + int objtypetraverse[TOTALNUMCLASSANDARRAY]; +#endif + void ** oidwrlocked; + allocarrays; + +#ifdef STMSTATS + for(i=0; ival)[-1]; + objheader_t *header=(objheader_t *)(((char *)curr->key)-sizeof(objheader_t)); + unsigned int version = headeraddr->version; + + if(STATUS(headeraddr) & DIRTY) { + /* Read from the main heap and compare versions */ + if(likely(write_trylock(&header->lock))) { //can aquire write lock + if (likely(version == header->version)) { /* versions match */ + /* Keep track of objects locked */ + oidwrlocked[numoidwrlocked++] = header; + } else { + oidwrlocked[numoidwrlocked++] = header; + transAbortProcess(oidwrlocked, numoidwrlocked); +#ifdef STMSTATS + header->abortCount++; + ObjSeqId = headeraddr->accessCount; + (typesCausingAbort[TYPE(header)]).numabort++; + (typesCausingAbort[TYPE(header)]).numaccess+=c_numelements; + (typesCausingAbort[TYPE(header)]).numtrans+=1; + objtypetraverse[TYPE(header)]=1; + getTotalAbortCount2((void *) curr->next, numoidrdlocked, oidrdlocked, oidrdversion, oidrdage, ObjSeqId, header, objtypetraverse); +#endif + DEBUGSTM("WR Abort: rd: %u wr: %u tot: %u type: %u ver: %u oid: %x\n", numoidrdlocked, numoidwrlocked, c_numelements, TYPE(header), header->version, OID(header)); + DEBUGSTMSTAT("WR Abort: Access Count: %u AbortCount: %u type: %u ver: %u \n", header->accessCount, header->abortCount, TYPE(header), header->version); + freearrays; + return TRANS_ABORT; + } + } else { /* cannot aquire lock */ + if(version == header->version) { + /* versions match */ + softabort=1; + } + transAbortProcess(oidwrlocked, numoidwrlocked); +#ifdef STMSTATS + header->abortCount++; + ObjSeqId = headeraddr->accessCount; + (typesCausingAbort[TYPE(header)]).numabort++; + (typesCausingAbort[TYPE(header)]).numaccess+=c_numelements; + (typesCausingAbort[TYPE(header)]).numtrans+=1; + objtypetraverse[TYPE(header)]=1; +#endif +#if defined(STMSTATS)||defined(SOFTABORT) + if(getTotalAbortCount2((void *) curr->next, numoidrdlocked, oidrdlocked, oidrdversion, oidrdage, ObjSeqId, header, objtypetraverse)) + softabort=0; +#endif + DEBUGSTM("WR Abort: rd: %u wr: %u tot: %u type: %u ver: %u oid: %x\n", numoidrdlocked, numoidwrlocked, c_numelements, TYPE(header), header->version, OID(header)); + DEBUGSTMSTAT("WR Abort: Access Count: %u AbortCount: %u type: %u ver: %u \n", header->accessCount, header->abortCount, TYPE(header), header->version); + freearrays; + if (softabort) + return TRANS_SOFT_ABORT; + else + return TRANS_ABORT; + } + } else { + /* Read from the main heap and compare versions */ + oidrdversion[numoidrdlocked]=version; + oidrdlocked[numoidrdlocked++] = header; + } + curr = curr->lnext; + } + +#ifdef DELAYCOMP + //acquire other locks + unsigned int numoidwrtotal=numoidwrlocked; + chashlistnode_t *dc_curr = dc_c_list; + /* Inner loop to traverse the linked list of the cache lookupTable */ + while(likely(dc_curr != NULL)) { + //if the first bin in hash table is empty + objheader_t * headeraddr=&((objheader_t *) dc_curr->val)[-1]; + objheader_t *header=(objheader_t *)(((char *)dc_curr->key)-sizeof(objheader_t)); + if(write_trylock(&header->lock)) { //can aquire write lock + oidwrlocked[numoidwrtotal++] = header; + } else { + //maybe we already have lock + void * key=dc_curr->key; + chashlistnode_t *node = &c_table[(((unsigned INTPTR)key) & c_mask)>>4]; + + do { + if(node->key == key) { + objheader_t * headeraddr=&((objheader_t *) node->val)[-1]; + if(STATUS(headeraddr) & DIRTY) { + goto nextloop; + } + } + node = node->next; + } while(node != NULL); + + //have to abort to avoid deadlock + transAbortProcess(oidwrlocked, numoidwrtotal); +#ifdef STMSTATS + header->abortCount++; + ObjSeqId = headeraddr->accessCount; + (typesCausingAbort[TYPE(header)]).numabort++; + (typesCausingAbort[TYPE(header)]).numaccess+=c_numelements; + (typesCausingAbort[TYPE(header)]).numtrans+=1; + objtypetraverse[TYPE(header)]=1; +#endif +#if defined(STMSTATS)||defined(SOFTABORT) + if(getTotalAbortCount2((void *) curr->next, numoidrdlocked, oidrdlocked, oidrdversion, oidrdage, ObjSeqId, header, objtypetraverse)) + softabort=0; +#endif + DEBUGSTM("WR Abort: rd: %u wr: %u tot: %u type: %u ver: %u oid: %x\n", numoidrdlocked, numoidwrlocked, c_numelements, TYPE(header), header->version, OID(header)); + DEBUGSTMSTAT("WR Abort: Access Count: %u AbortCount: %u type: %u ver: %u \n", header->accessCount, header->abortCount, TYPE(header), header->version); + freearrays; + if (softabort) + return TRANS_SOFT_ABORT; + else + return TRANS_ABORT; + } + nextloop: + dc_curr = dc_curr->lnext; + } +#endif + + //THIS IS THE SERIALIZATION END POINT (START POINT IS END OF EXECUTION)***** + + for(i=0; ilock>0) { + CFENCE; + if(version != header->version) { +#ifdef DELAYCOMP + transAbortProcess(oidwrlocked, numoidwrtotal); +#else + transAbortProcess(oidwrlocked, numoidwrlocked); +#endif +#ifdef STMSTATS + ObjSeqId = oidrdage[i]; + header->abortCount++; + (typesCausingAbort[TYPE(header)]).numabort++; + (typesCausingAbort[TYPE(header)]).numaccess+=c_numelements; + (typesCausingAbort[TYPE(header)]).numtrans+=1; + objtypetraverse[TYPE(header)]=1; + getReadAbortCount(i+1, numoidrdlocked, oidrdlocked, oidrdversion, oidrdage, ObjSeqId, header, objtypetraverse); +#endif + DEBUGSTM("RD Abort: rd: %u wr: %u tot: %u type: %u ver: %u oid: %x\n", numoidrdlocked, numoidwrlocked, c_numelements, TYPE(header), header->version, OID(header)); + DEBUGSTMSTAT("RD Abort: Access Count: %u AbortCount: %u type: %u ver: %u \n", header->accessCount, header->abortCount, TYPE(header), header->version); + freearrays; + return TRANS_ABORT; + } +#ifdef DELAYCOMP + } else if (dc_t_chashSearch(((char *)header)+sizeof(objheader_t))!=NULL) { + //couldn't get lock because we already have it + //check if it is the right version number + if (version!=header->version) { + transAbortProcess(oidwrlocked, numoidwrtotal); +#ifdef STMSTATS + ObjSeqId = oidrdage[i]; + header->abortCount++; + getReadAbortCount(i+1, numoidrdlocked, oidrdlocked, oidrdversion, oidrdage, ObjSeqId, header, objtypetraverse); +#endif + DEBUGSTM("RD Abort: rd: %u wr: %u tot: %u type: %u ver: %u oid: %x\n", numoidrdlocked, numoidwrlocked, c_numelements, TYPE(header), header->version, OID(header)); + DEBUGSTMSTAT("RD Abort: Access Count: %u AbortCount: %u type: %u ver: %u \n", header->accessCount, header->abortCount, TYPE(header), header->version); + freearrays; + return TRANS_ABORT; + } +#endif + } else { /* cannot aquire lock */ + if(version == header->version) { + softabort=1; + } +#ifdef DELAYCOMP + transAbortProcess(oidwrlocked, numoidwrtotal); +#else + transAbortProcess(oidwrlocked, numoidwrlocked); +#endif +#ifdef STMSTATS + ObjSeqId = oidrdage[i]; + header->abortCount++; + (typesCausingAbort[TYPE(header)]).numabort++; + (typesCausingAbort[TYPE(header)]).numaccess+=c_numelements; + (typesCausingAbort[TYPE(header)]).numtrans+=1; + objtypetraverse[TYPE(header)]=1; +#endif +#if defined(STMSTATS)||defined(SOFTABORT) + if(getReadAbortCount(i+1, numoidrdlocked, oidrdlocked, oidrdversion, oidrdage, ObjSeqId, header, objtypetraverse)) + softabort=0; +#endif + DEBUGSTM("RD Abort: rd: %u wr: %u tot: %u type: %u ver: %u\n", numoidrdlocked, numoidwrlocked, c_numelements, TYPE(header), header->version); + DEBUGSTMSTAT("RD Abort: Access Count: %u AbortCount: %u type: %u ver: %u \n", header->accessCount, header->abortCount, TYPE(header), header->version); + freearrays; + if (softabort) + return TRANS_SOFT_ABORT; + else + return TRANS_ABORT; + } + } + +#ifdef READSET + //need to validate auxilary readset + rdchashlistnode_t *rd_curr = rd_c_list; + /* Inner loop to traverse the linked list of the cache lookupTable */ + while(likely(rd_curr != NULL)) { + //if the first bin in hash table is empty + int version=rd_curr->version; + objheader_t *header=(objheader_t *)(((char *)rd_curr->key)-sizeof(objheader_t)); + if(header->lock>0) { //object is not locked + if (version!=header->version) { + //have to abort +#ifdef DELAYCOMP + transAbortProcess(oidwrlocked, numoidwrtotal); +#else + transAbortProcess(oidwrlocked, numoidwrlocked); +#endif +#ifdef STMSTATS + //ABORTCOUNT(header); + (typesCausingAbort[TYPE(header)])++; +#endif +#if defined(STMSTATS)||defined(SOFTABORT) + //if(getTotalAbortCount2((void *) curr->next, numoidrdlocked, oidrdlocked, oidrdversion)) + // softabort=0; +#endif + DEBUGSTM("WR Abort: rd: %u wr: %u tot: %u type: %u ver: %u\n", numoidrdlocked, numoidwrlocked, c_numelements, TYPE(header), header->version); + DEBUGSTMSTAT("WR Abort: Access Count: %u AbortCount: %u type: %u ver: %u \n", header->accessCount, header->abortCount, TYPE(header), header->version); + freearrays; + if (softabort) + return TRANS_SOFT_ABORT; + else + return TRANS_ABORT; + } + } else { + if (version==header->version) { + void * key=rd_curr->key; +#ifdef DELAYCOMP + //check to see if it is in the delaycomp table + { + chashlistnode_t *node = &dc_c_table[(((unsigned INTPTR)key) & dc_c_mask)>>4]; + do { + if(node->key == key) + goto nextloopread; + node = node->next; + } while(node != NULL); + } +#endif + //check normal table + { + chashlistnode_t *node = &c_table[(((unsigned INTPTR)key) & c_mask)>>4]; + do { + if(node->key == key) { + objheader_t * headeraddr=&((objheader_t *) node->val)[-1]; + if(STATUS(headeraddr) & DIRTY) { + goto nextloopread; + } + } + node = node->next; + } while(node != NULL); + } + } +#ifdef DELAYCOMP + //have to abort to avoid deadlock + transAbortProcess(oidwrlocked, numoidwrtotal); +#else + transAbortProcess(oidwrlocked, numoidwrlocked); +#endif +#ifdef STMSTATS + //ABORTCOUNT(header); + (typesCausingAbort[TYPE(header)])++; +#endif +#if defined(STMSTATS)||defined(SOFTABORT) + // if(getTotalAbortCount2((void *) curr->next, numoidrdlocked, oidrdlocked, oidrdversion)) + //softabort=0; +#endif + DEBUGSTM("WR Abort: rd: %u wr: %u tot: %u type: %u ver: %u\n", numoidrdlocked, numoidwrlocked, c_numelements, TYPE(header), header->version); + DEBUGSTMSTAT("WR Abort: Access Count: %u AbortCount: %u type: %u ver: %u \n", header->accessCount, header->abortCount, TYPE(header), header->version); + freearrays; + if (softabort) + return TRANS_SOFT_ABORT; + else + return TRANS_ABORT; + } + nextloopread: + rd_curr = rd_curr->lnext; + } +#endif + + /* Decide the final response */ +#ifdef DELAYCOMP + transCommitProcess(oidwrlocked, numoidwrlocked, numoidwrtotal, commitmethod, primitives, locals, params); +#else + transCommitProcess(oidwrlocked, numoidwrlocked); +#endif + DEBUGSTM("Commit: rd: %u wr: %u tot: %u\n", numoidrdlocked, numoidwrlocked, c_numelements); + freearrays; + return TRANS_COMMIT; +} + +/* ================================== + * transAbortProcess + * + * ================================= + */ +void transAbortProcess(void **oidwrlocked, int numoidwrlocked) { + int i; + objheader_t *header; + /* Release read locks */ + + /* Release write locks */ + for(i=numoidwrlocked-1; i>=0; i--) { + /* Read from the main heap */ + header = (objheader_t *)oidwrlocked[i]; + write_unlock(&header->lock); + } + +#ifdef STMSTATS + /* clear trec and then release objects locked */ + struct objlist *ptr=lockedobjs; + while(ptr!=NULL) { + int max=ptr->offset; + for(i=max-1; i>=0; i--) { + header = (objheader_t *)ptr->objs[i]; + header->trec = NULL; + pthread_mutex_unlock(header->objlock); + } + ptr=ptr->next; + } +#endif +} + +/* ================================== + * transCommitProcess + * + * ================================= + */ +#ifdef DELAYCOMP + void transCommitProcess(void ** oidwrlocked, int numoidwrlocked, int numoidwrtotal, void (*commitmethod)(void *, void *, void *), void * primitives, void * locals, void * params) { +#else + void transCommitProcess(void ** oidwrlocked, int numoidwrlocked) { +#endif + objheader_t *header; + void *ptrcreate; + int i; + struct objlist *ptr=newobjs; + while(ptr!=NULL) { + int max=ptr->offset; + for(i=0; iobjs[i])->___objstatus___=0; + } + ptr=ptr->next; + } + + /* Copy from transaction cache -> main object store */ + for (i = numoidwrlocked-1; i >=0; i--) { + /* Read from the main heap */ + header = (objheader_t *)oidwrlocked[i]; + int tmpsize; + GETSIZE(tmpsize, header); + struct ___Object___ *dst=(struct ___Object___*)(((char *)oidwrlocked[i])+sizeof(objheader_t)); + struct ___Object___ *src=t_chashSearch(dst); + dst->___cachedCode___=src->___cachedCode___; + dst->___cachedHash___=src->___cachedHash___; + A_memcpy(&dst[1], &src[1], tmpsize-sizeof(struct ___Object___)); + } + CFENCE; + +#ifdef DELAYCOMP + // call commit method + ptrstack.count=0; + primstack.count=0; + branchstack.count=0; + commitmethod(params, locals, primitives); +#endif + + /* Release write locks */ +#ifdef DELAYCOMP + for(i=numoidwrtotal-1; i>=0; i--) { +#else + for(i=numoidwrlocked-1; i>=0; i--) { +#endif + header = (objheader_t *)oidwrlocked[i]; + header->version++; + write_unlock(&header->lock); + } + +#ifdef STMSTATS + /* clear trec and then release objects locked */ + ptr=lockedobjs; + while(ptr!=NULL) { + int max=ptr->offset; + for(i=max-1; i>=0; i--) { + header = (objheader_t *)ptr->objs[i]; + header->trec = NULL; + pthread_mutex_unlock(header->objlock); + } + ptr=ptr->next; + } +#endif +} + diff --git a/Robust/src/Runtime/STM/stats.c b/Robust/src/Runtime/STM/stats.c index b08ccd75..c22f7c4f 100644 --- a/Robust/src/Runtime/STM/stats.c +++ b/Robust/src/Runtime/STM/stats.c @@ -2,11 +2,24 @@ #include "garbage.h" #ifdef STMSTATS -extern __thread threadrec_t *trec; -extern __thread struct objlist * lockedobjs; +/* Thread variable for locking/unlocking */ +__thread threadrec_t *trec; +__thread struct objlist * lockedobjs; +__thread int t_objnumcount=0; /* Collect stats for object classes causing abort */ -extern objtypestat_t typesCausingAbort[TOTALNUMCLASSANDARRAY]; +objtypestat_t typesCausingAbort[TOTALNUMCLASSANDARRAY]; + +void freelockedobjs() { + struct objlist *ptr=lockedobjs; + while(ptr->next!=NULL) { + struct objlist *tmp=ptr->next; + free(ptr); + ptr=tmp; + } + ptr->offset=0; + lockedobjs=ptr; +} INLINE void getTransSize(objheader_t *header , int *isObjTypeTraverse) { (typesCausingAbort[TYPE(header)]).numabort++; @@ -16,27 +29,7 @@ INLINE void getTransSize(objheader_t *header , int *isObjTypeTraverse) { } isObjTypeTraverse[TYPE(header)]=1; } -#endif - -#ifdef STMSTATS -#define DEBUGSTMSTAT(args...) -#else -#define DEBUGSTMSTAT(args...) -#endif -#ifdef STMDEBUG -#define DEBUGSTM(x...) printf(x); -#else -#define DEBUGSTM(x...); -#endif - -#ifdef STATDEBUG -#define DEBUGSTATS(x...) printf(x); -#else -#define DEBUGSTATS(x...); -#endif - -#ifdef STMSTATS /*** Global variables *****/ objlockstate_t *objlockscope; /** diff --git a/Robust/src/Runtime/STM/stm.c b/Robust/src/Runtime/STM/stm.c index 114a77d2..fb5b6c66 100644 --- a/Robust/src/Runtime/STM/stm.c +++ b/Robust/src/Runtime/STM/stm.c @@ -41,41 +41,6 @@ int nSoftAbortCommit = 0; int nSoftAbortAbort = 0; #endif -#ifdef STMSTATS -/* Thread variable for locking/unlocking */ -__thread threadrec_t *trec; -__thread struct objlist * lockedobjs; -__thread int t_objnumcount=0; - -/* Collect stats for object classes causing abort */ -objtypestat_t typesCausingAbort[TOTALNUMCLASSANDARRAY]; - -#endif - -#ifdef STMSTATS -#define DEBUGSTMSTAT(args...) -#else -#define DEBUGSTMSTAT(args...) -#endif - -#ifdef STMDEBUG -#define DEBUGSTM(x...) printf(x); -#else -#define DEBUGSTM(x...); -#endif - -#ifdef STATDEBUG -#define DEBUGSTATS(x...) printf(x); -#else -#define DEBUGSTATS(x...); -#endif - -//#ifdef FASTMEMCPY -//void * A_memcpy (void * dest, const void * src, size_t count); -//#else -//#define A_memcpy memcpy -//#endif - void * A_memcpy (void * dest, const void * src, size_t count) { int off=0; INTPTR *desti=(INTPTR *)dest; @@ -96,11 +61,6 @@ void * A_memcpy (void * dest, const void * src, size_t count) { } } - -extern void * curr_heapbase; -extern void * curr_heapptr; -extern void * curr_heaptop; - /* ================================================== * stmStartup * This function starts up the transaction runtime. @@ -214,972 +174,3 @@ void freenewobjs() { newobjs=ptr; } -#ifdef STMSTATS -void freelockedobjs() { - struct objlist *ptr=lockedobjs; - while(ptr->next!=NULL) { - struct objlist *tmp=ptr->next; - free(ptr); - ptr=tmp; - } - ptr->offset=0; - lockedobjs=ptr; -} -#endif - -/* ================================================================ - * transCommit - * - This function initiates the transaction commit process - * - goes through the transaction cache and decides - * - a final response - * ================================================================ - */ -#ifdef DELAYCOMP -int transCommit(void (*commitmethod)(void *, void *, void *), void * primitives, void * locals, void * params) { -#else -int transCommit() { -#endif -#ifdef SANDBOX - abortenabled=0; -#endif -#ifdef TRANSSTATS - numTransCommit++; -#endif - int softaborted=0; - do { - /* Look through all the objects in the transaction hash table */ - int finalResponse; -#ifdef DELAYCOMP - if (c_numelements<(c_size>>3)) - finalResponse= alttraverseCache(commitmethod, primitives, locals, params); - else - finalResponse= traverseCache(commitmethod, primitives, locals, params); -#else - if (c_numelements<(c_size>>3)) - finalResponse= alttraverseCache(); - else - finalResponse= traverseCache(); -#endif - if(finalResponse == TRANS_ABORT) { -#ifdef TRANSSTATS - numTransAbort++; - if (softaborted) { - nSoftAbortAbort++; - } -#endif - freenewobjs(); -#ifdef STMSTATS - freelockedobjs(); -#endif - objstrReset(); - t_chashreset(); -#ifdef READSET - rd_t_chashreset(); -#endif -#ifdef DELAYCOMP - dc_t_chashreset(); - ptrstack.count=0; - primstack.count=0; - branchstack.count=0; -#endif -#ifdef SANDBOX - abortenabled=1; -#endif - return TRANS_ABORT; - } - if(finalResponse == TRANS_COMMIT) { -#ifdef TRANSSTATS - //numTransCommit++; - if (softaborted) { - nSoftAbortCommit++; - } -#endif - freenewobjs(); -#ifdef STMSTATS - freelockedobjs(); -#endif - objstrReset(); - t_chashreset(); -#ifdef READSET - rd_t_chashreset(); -#endif -#ifdef DELAYCOMP - dc_t_chashreset(); - ptrstack.count=0; - primstack.count=0; - branchstack.count=0; -#endif - return 0; - } - - /* wait a random amount of time before retrying to commit transaction*/ - if(finalResponse == TRANS_SOFT_ABORT) { -#ifdef TRANSSTATS - nSoftAbort++; -#endif - softaborted++; -#ifdef SOFTABORT - if (softaborted>1) { -#else - if (1) { -#endif - //retry if too many soft aborts - freenewobjs(); -#ifdef STMSTATS - freelockedobjs(); -#endif - objstrReset(); - t_chashreset(); -#ifdef READSET - rd_t_chashreset(); -#endif -#ifdef DELAYCOMP - dc_t_chashreset(); - ptrstack.count=0; - primstack.count=0; - branchstack.count=0; -#endif - return TRANS_ABORT; - } - //randomdelay(softaborted); - } else { - printf("Error: in %s() Unknown outcome", __func__); - exit(-1); - } - } while (1); -} - -#ifdef STMSTATS - You need to add free statements for oidrdage in a way that they will not appear if this option is not defined. -#endif - -#ifdef DELAYCOMP -#define freearrays if (c_numelements>=200) { \ - free(oidrdlocked); \ - free(oidrdversion); \ - } \ - if (t_numelements>=200) { \ - free(oidwrlocked); \ - } -#else -#define freearrays if (c_numelements>=200) { \ - free(oidrdlocked); \ - free(oidrdversion); \ - free(oidwrlocked); \ - } -#endif - -#ifdef STMSTATS - you need to set oidrdage in a way that does not appear if this macro is not defined. -#endif - -#ifdef DELAYCOMP -#define allocarrays int t_numelements=c_numelements+dc_c_numelements; \ - if (t_numelements<200) { \ - oidwrlocked=wrlocked; \ - } else { \ - oidwrlocked=malloc(t_numelements*sizeof(void *)); \ - } \ - if (c_numelements<200) { \ - oidrdlocked=rdlocked; \ - oidrdversion=rdversion; \ - } else { \ - int size=c_numelements*sizeof(void*); \ - oidrdlocked=malloc(size); \ - oidrdversion=malloc(size); \ - } -#else -#define allocarrays if (c_numelements<200) { \ - oidrdlocked=rdlocked; \ - oidrdversion=rdversion; \ - oidwrlocked=wrlocked; \ - } else { \ - int size=c_numelements*sizeof(void*); \ - oidrdlocked=malloc(size); \ - oidrdversion=malloc(size); \ - oidwrlocked=malloc(size); \ - } -#endif - - - - -/* ================================================== - * traverseCache - * - goes through the transaction cache and - * - decides if a transaction should commit or abort - * ================================================== - */ -#ifdef DELAYCOMP -int traverseCache(void (*commitmethod)(void *, void *, void *), void * primitives, void * locals, void * params) { -#else -int traverseCache() { -#endif - /* Create info to keep track of objects that can be locked */ - int numoidrdlocked=0; - int numoidwrlocked=0; - void * rdlocked[200]; - int rdversion[200]; - void * wrlocked[200]; - int softabort=0; - int i; - void ** oidrdlocked; - void ** oidwrlocked; -#ifdef STMSTATS - int rdage[200]; - int * oidrdage; - int ObjSeqId; - int objtypetraverse[TOTALNUMCLASSANDARRAY]; -#endif - int * oidrdversion; - allocarrays; - -#ifdef STMSTATS - for(i=0; ikey == NULL) - break; - objheader_t * headeraddr=&((objheader_t *) curr->val)[-1]; //cached object - objheader_t *header=(objheader_t *)(((char *)curr->key)-sizeof(objheader_t)); //real object - unsigned int version = headeraddr->version; - - if(STATUS(headeraddr) & DIRTY) { - /* Read from the main heap and compare versions */ - if(write_trylock(&header->lock)) { //can aquire write lock - if (version == header->version) { /* versions match */ - /* Keep track of objects locked */ - oidwrlocked[numoidwrlocked++] = header; - } else { - oidwrlocked[numoidwrlocked++] = header; - transAbortProcess(oidwrlocked, numoidwrlocked); -#ifdef STMSTATS - header->abortCount++; - ObjSeqId = headeraddr->accessCount; - (typesCausingAbort[TYPE(header)]).numabort++; - (typesCausingAbort[TYPE(header)]).numaccess+=c_numelements; - (typesCausingAbort[TYPE(header)]).numtrans+=1; - objtypetraverse[TYPE(header)]=1; - getTotalAbortCount(i+1, size, (void *)(curr->next), numoidrdlocked, oidrdlocked, oidrdversion, oidrdage, ObjSeqId, header, objtypetraverse); -#endif - DEBUGSTM("WR Abort: rd: %u wr: %u tot: %u type: %u ver: %u\n", numoidrdlocked, numoidwrlocked, c_numelements, TYPE(header), header->version); - DEBUGSTMSTAT("WR Abort: Access Count: %u AbortCount: %u type: %u ver: %u \n", header->accessCount, header->abortCount, TYPE(header), header->version); - freearrays; - if (softabort) - return TRANS_SOFT_ABORT; - else - return TRANS_ABORT; - } - } else { - if(version == header->version) { - /* versions match */ - softabort=1; - } - transAbortProcess(oidwrlocked, numoidwrlocked); -#ifdef STMSTATS - header->abortCount++; - ObjSeqId = headeraddr->accessCount; - (typesCausingAbort[TYPE(header)]).numabort++; - (typesCausingAbort[TYPE(header)]).numaccess+=c_numelements; - (typesCausingAbort[TYPE(header)]).numtrans+=1; - objtypetraverse[TYPE(header)]=1; - //(typesCausingAbort[TYPE(header)])++; -#endif -#if defined(STMSTATS)||defined(SOFTABORT) - if(getTotalAbortCount(i+1, size, (void *)(curr->next), numoidrdlocked, oidrdlocked, oidrdversion, oidrdage, ObjSeqId, header, objtypetraverse)) - softabort=0; -#endif - DEBUGSTM("WR Abort: rd: %u wr: %u tot: %u type: %u ver: %u\n", numoidrdlocked, numoidwrlocked, c_numelements, TYPE(header), header->version); - DEBUGSTMSTAT("WR Abort: Access Count: %u AbortCount: %u type: %u ver: %u \n", header->accessCount, header->abortCount, TYPE(header), header->version); - freearrays; - if (softabort) - return TRANS_SOFT_ABORT; - else - return TRANS_ABORT; - - } - } else { -#ifdef STMSTATS - oidrdage[numoidrdlocked]=headeraddr->accessCount; -#endif - oidrdversion[numoidrdlocked]=version; - oidrdlocked[numoidrdlocked++]=header; - } - curr = curr->next; - } - } //end of for - -#ifdef DELAYCOMP - //acquire access set locks - unsigned int numoidwrtotal=numoidwrlocked; - - chashlistnode_t *dc_curr = dc_c_list; - /* Inner loop to traverse the linked list of the cache lookupTable */ - while(likely(dc_curr != NULL)) { - //if the first bin in hash table is empty - objheader_t * headeraddr=&((objheader_t *) dc_curr->val)[-1]; - objheader_t *header=(objheader_t *)(((char *)dc_curr->key)-sizeof(objheader_t)); - if(write_trylock(&header->lock)) { //can aquire write lock - oidwrlocked[numoidwrtotal++] = header; - } else { - //maybe we already have lock - void * key=dc_curr->key; - chashlistnode_t *node = &c_table[(((unsigned INTPTR)key) & c_mask)>>4]; - - do { - if(node->key == key) { - objheader_t * headeraddr=&((objheader_t *) node->val)[-1]; - if(STATUS(headeraddr) & DIRTY) { - goto nextloop; - } else - break; - } - node = node->next; - } while(node != NULL); - - //have to abort to avoid deadlock - transAbortProcess(oidwrlocked, numoidwrtotal); -#ifdef STMSTATS - ObjSeqId = headeraddr->accessCount; - header->abortCount++; - (typesCausingAbort[TYPE(header)]).numabort++; - (typesCausingAbort[TYPE(header)]).numaccess+=c_numelements; - (typesCausingAbort[TYPE(header)]).numtrans+=1; - objtypetraverse[TYPE(header)]=1; -#endif -#if defined(STMSTATS)||defined(SOFTABORT) - if(getTotalAbortCount(i+1, size, (void *)(curr->next), numoidrdlocked, oidrdlocked, oidrdversion, oidrdage, ObjSeqId, header, objtypetraverse)) - softabort=0; -#endif - DEBUGSTM("WR Abort: rd: %u wr: %u tot: %u type: %u ver: %u\n", numoidrdlocked, numoidwrlocked, c_numelements, TYPE(header), header->version); - DEBUGSTMSTAT("WR Abort: Access Count: %u AbortCount: %u type: %u ver: %u \n", header->accessCount, header->abortCount, TYPE(header), header->version); - freearrays; - if (softabort) - return TRANS_SOFT_ABORT; - else - return TRANS_ABORT; - } - nextloop: - dc_curr = dc_curr->lnext; - } -#endif - - //THIS IS THE SERIALIZATION END POINT (START POINT IS END OF EXECUTION)***** - - for(i=0; ilock>0) { //not write locked - CFENCE; - if(version != header->version) { /* versions do not match */ -#ifdef DELAYCOMP - transAbortProcess(oidwrlocked, numoidwrtotal); -#else - transAbortProcess(oidwrlocked, numoidwrlocked); -#endif -#ifdef STMSTATS - ObjSeqId = oidrdage[i]; - header->abortCount++; - (typesCausingAbort[TYPE(header)]).numabort++; - (typesCausingAbort[TYPE(header)]).numaccess+=c_numelements; - (typesCausingAbort[TYPE(header)]).numtrans+=1; - objtypetraverse[TYPE(header)]=1; - getReadAbortCount(i+1, numoidrdlocked, oidrdlocked, oidrdversion, oidrdage, ObjSeqId, header, objtypetraverse); -#endif - DEBUGSTM("RD Abort: rd: %u wr: %u tot: %u type: %u ver: %u oid: %x\n", numoidrdlocked, numoidwrlocked, c_numelements, TYPE(header), header->version, OID(header)); - DEBUGSTMSTAT("RD Abort: Access Count: %u AbortCount: %u type: %u ver: %u \n", header->accessCount, header->abortCount, TYPE(header), header->version); - freearrays; - return TRANS_ABORT; - } -#if DELAYCOMP - } else if (dc_t_chashSearch(((char *)header)+sizeof(objheader_t))!=NULL) { - //couldn't get lock because we already have it - //check if it is the right version number - if (version!=header->version) { - transAbortProcess(oidwrlocked, numoidwrtotal); -#ifdef STMSTATS - ObjSeqId = oidrdage[i]; - header->abortCount++; - (typesCausingAbort[TYPE(header)]).numabort++; - (typesCausingAbort[TYPE(header)]).numaccess+=c_numelements; - (typesCausingAbort[TYPE(header)]).numtrans+=1; - objtypetraverse[TYPE(header)]=1; - getReadAbortCount(i+1, numoidrdlocked, oidrdlocked, oidrdversion, oidrdage, ObjSeqId, header, objtypetraverse); -#endif - DEBUGSTM("RD Abort: rd: %u wr: %u tot: %u type: %u ver: %u, oid: %x\n", numoidrdlocked, numoidwrlocked, c_numelements, TYPE(header), header->version, OID(header)); - DEBUGSTMSTAT("RD Abort: Access Count: %u AbortCount: %u type: %u ver: %u \n", header->accessCount, header->abortCount, TYPE(header), header->version); - freearrays; - return TRANS_ABORT; - } -#endif - } else { /* cannot aquire lock */ - //do increment as we didn't get lock - if(version == header->version) { - softabort=1; - } -#ifdef DELAYCOMP - transAbortProcess(oidwrlocked, numoidwrtotal); -#else - transAbortProcess(oidwrlocked, numoidwrlocked); -#endif -#ifdef STMSTATS - ObjSeqId = oidrdage[i]; - header->abortCount++; - (typesCausingAbort[TYPE(header)]).numabort++; - (typesCausingAbort[TYPE(header)]).numaccess+=c_numelements; - (typesCausingAbort[TYPE(header)]).numtrans+=1; - objtypetraverse[TYPE(header)]=1; -#endif -#if defined(STMSTATS)||defined(SOFTABORT) - if(getReadAbortCount(i+1, numoidrdlocked, oidrdlocked, oidrdversion, oidrdage, ObjSeqId, header, objtypetraverse)) - softabort=0; -#endif - DEBUGSTM("RD Abort: rd: %u wr: %u tot: %u type: %u ver: %u oid: %x\n", numoidrdlocked, numoidwrlocked, c_numelements, TYPE(header), header->version, OID(header)); - DEBUGSTMSTAT("RD Abort: Access Count: %u AbortCount: %u type: %u ver: %u \n", header->accessCount, header->abortCount, TYPE(header), header->version); - freearrays; - if (softabort) - return TRANS_SOFT_ABORT; - else - return TRANS_ABORT; - } - } - -#ifdef READSET - //need to validate auxilary readset - rdchashlistnode_t *rd_curr = rd_c_list; - /* Inner loop to traverse the linked list of the cache lookupTable */ - while(likely(rd_curr != NULL)) { - //if the first bin in hash table is empty - unsigned int version=rd_curr->version; - objheader_t *header=(objheader_t *)(((char *)rd_curr->key)-sizeof(objheader_t)); - if(header->lock>0) { //object is not locked - if (version!=header->version) { - //have to abort -#ifdef DELAYCOMP - transAbortProcess(oidwrlocked, numoidwrtotal); -#else - transAbortProcess(oidwrlocked, numoidwrlocked); -#endif -#ifdef STMSTATS - //ABORTCOUNT(header); - (typesCausingAbort[TYPE(header)])++; -#endif -#if defined(STMSTATS)||defined(SOFTABORT) - //if(getTotalAbortCount2((void *) curr->next, numoidrdlocked, oidrdlocked, oidrdversion)) - // softabort=0; -#endif - DEBUGSTM("WR Abort: rd: %u wr: %u tot: %u type: %u ver: %u oid: %x\n", numoidrdlocked, numoidwrlocked, c_numelements, TYPE(header), header->version, OID(header)); - DEBUGSTMSTAT("WR Abort: Access Count: %u AbortCount: %u type: %u ver: %u \n", header->accessCount, header->abortCount, TYPE(header), header->version); - freearrays; - if (softabort) - return TRANS_SOFT_ABORT; - else - return TRANS_ABORT; - } - } else { - //maybe we already have lock - if (version==header->version) { - void * key=rd_curr->key; -#ifdef DELAYCOMP - //check to see if it is in the delaycomp table - { - chashlistnode_t *node = &dc_c_table[(((unsigned INTPTR)key) & dc_c_mask)>>4]; - do { - if(node->key == key) - goto nextloopread; - node = node->next; - } while(node != NULL); - } -#endif - //check normal table - { - chashlistnode_t *node = &c_table[(((unsigned INTPTR)key) & c_mask)>>4]; - do { - if(node->key == key) { - objheader_t * headeraddr=&((objheader_t *) node->val)[-1]; - if(STATUS(headeraddr) & DIRTY) { - goto nextloopread; - } - } - node = node->next; - } while(node != NULL); - } - } -#ifdef DELAYCOMP - //have to abort to avoid deadlock - transAbortProcess(oidwrlocked, numoidwrtotal); -#else - transAbortProcess(oidwrlocked, numoidwrlocked); -#endif - -#ifdef STMSTATS - //ABORTCOUNT(header); - (typesCausingAbort[TYPE(header)])++; -#endif -#if defined(STMSTATS)||defined(SOFTABORT) - //if(getTotalAbortCount2((void *) curr->next, numoidrdlocked, oidrdlocked, oidrdversion)) - //softabort=0; -#endif - DEBUGSTM("WR Abort: rd: %u wr: %u tot: %u type: %u ver: %u oid: %x\n", numoidrdlocked, numoidwrlocked, c_numelements, TYPE(header), header->version, OID(header)); - DEBUGSTMSTAT("WR Abort: Access Count: %u AbortCount: %u type: %u ver: %u \n", header->accessCount, header->abortCount, TYPE(header), header->version); - freearrays; - if (softabort) - return TRANS_SOFT_ABORT; - else - return TRANS_ABORT; - } - nextloopread: - rd_curr = rd_curr->lnext; - } -#endif - - /* Decide the final response */ -#ifdef DELAYCOMP - transCommitProcess(oidwrlocked, numoidwrlocked, numoidwrtotal, commitmethod, primitives, locals, params); -#else - transCommitProcess(oidwrlocked, numoidwrlocked); -#endif - DEBUGSTM("Commit: rd: %u wr: %u tot: %u\n", numoidrdlocked, numoidwrlocked, c_numelements); - freearrays; - return TRANS_COMMIT; -} - -/* ================================================== - * alttraverseCache - * - goes through the transaction cache and - * - decides if a transaction should commit or abort - * ================================================== - */ - -#ifdef DELAYCOMP -int alttraverseCache(void (*commitmethod)(void *, void *, void *), void * primitives, void * locals, void * params) { -#else -int alttraverseCache() { -#endif - /* Create info to keep track of objects that can be locked */ - int numoidrdlocked=0; - int numoidwrlocked=0; - void * rdlocked[200]; - int rdversion[200]; - void * wrlocked[200]; - int softabort=0; - int i; - void ** oidrdlocked; - int * oidrdversion; -#ifdef STMSTATS - int rdage[200]; - int * oidrdage; - int ObjSeqId; - int objtypetraverse[TOTALNUMCLASSANDARRAY]; -#endif - void ** oidwrlocked; - allocarrays; - -#ifdef STMSTATS - for(i=0; ival)[-1]; - objheader_t *header=(objheader_t *)(((char *)curr->key)-sizeof(objheader_t)); - unsigned int version = headeraddr->version; - - if(STATUS(headeraddr) & DIRTY) { - /* Read from the main heap and compare versions */ - if(likely(write_trylock(&header->lock))) { //can aquire write lock - if (likely(version == header->version)) { /* versions match */ - /* Keep track of objects locked */ - oidwrlocked[numoidwrlocked++] = header; - } else { - oidwrlocked[numoidwrlocked++] = header; - transAbortProcess(oidwrlocked, numoidwrlocked); -#ifdef STMSTATS - header->abortCount++; - ObjSeqId = headeraddr->accessCount; - (typesCausingAbort[TYPE(header)]).numabort++; - (typesCausingAbort[TYPE(header)]).numaccess+=c_numelements; - (typesCausingAbort[TYPE(header)]).numtrans+=1; - objtypetraverse[TYPE(header)]=1; - getTotalAbortCount2((void *) curr->next, numoidrdlocked, oidrdlocked, oidrdversion, oidrdage, ObjSeqId, header, objtypetraverse); -#endif - DEBUGSTM("WR Abort: rd: %u wr: %u tot: %u type: %u ver: %u oid: %x\n", numoidrdlocked, numoidwrlocked, c_numelements, TYPE(header), header->version, OID(header)); - DEBUGSTMSTAT("WR Abort: Access Count: %u AbortCount: %u type: %u ver: %u \n", header->accessCount, header->abortCount, TYPE(header), header->version); - freearrays; - return TRANS_ABORT; - } - } else { /* cannot aquire lock */ - if(version == header->version) { - /* versions match */ - softabort=1; - } - transAbortProcess(oidwrlocked, numoidwrlocked); -#ifdef STMSTATS - header->abortCount++; - ObjSeqId = headeraddr->accessCount; - (typesCausingAbort[TYPE(header)]).numabort++; - (typesCausingAbort[TYPE(header)]).numaccess+=c_numelements; - (typesCausingAbort[TYPE(header)]).numtrans+=1; - objtypetraverse[TYPE(header)]=1; -#endif -#if defined(STMSTATS)||defined(SOFTABORT) - if(getTotalAbortCount2((void *) curr->next, numoidrdlocked, oidrdlocked, oidrdversion, oidrdage, ObjSeqId, header, objtypetraverse)) - softabort=0; -#endif - DEBUGSTM("WR Abort: rd: %u wr: %u tot: %u type: %u ver: %u oid: %x\n", numoidrdlocked, numoidwrlocked, c_numelements, TYPE(header), header->version, OID(header)); - DEBUGSTMSTAT("WR Abort: Access Count: %u AbortCount: %u type: %u ver: %u \n", header->accessCount, header->abortCount, TYPE(header), header->version); - freearrays; - if (softabort) - return TRANS_SOFT_ABORT; - else - return TRANS_ABORT; - } - } else { - /* Read from the main heap and compare versions */ - oidrdversion[numoidrdlocked]=version; - oidrdlocked[numoidrdlocked++] = header; - } - curr = curr->lnext; - } - -#ifdef DELAYCOMP - //acquire other locks - unsigned int numoidwrtotal=numoidwrlocked; - chashlistnode_t *dc_curr = dc_c_list; - /* Inner loop to traverse the linked list of the cache lookupTable */ - while(likely(dc_curr != NULL)) { - //if the first bin in hash table is empty - objheader_t * headeraddr=&((objheader_t *) dc_curr->val)[-1]; - objheader_t *header=(objheader_t *)(((char *)dc_curr->key)-sizeof(objheader_t)); - if(write_trylock(&header->lock)) { //can aquire write lock - oidwrlocked[numoidwrtotal++] = header; - } else { - //maybe we already have lock - void * key=dc_curr->key; - chashlistnode_t *node = &c_table[(((unsigned INTPTR)key) & c_mask)>>4]; - - do { - if(node->key == key) { - objheader_t * headeraddr=&((objheader_t *) node->val)[-1]; - if(STATUS(headeraddr) & DIRTY) { - goto nextloop; - } - } - node = node->next; - } while(node != NULL); - - //have to abort to avoid deadlock - transAbortProcess(oidwrlocked, numoidwrtotal); -#ifdef STMSTATS - header->abortCount++; - ObjSeqId = headeraddr->accessCount; - (typesCausingAbort[TYPE(header)]).numabort++; - (typesCausingAbort[TYPE(header)]).numaccess+=c_numelements; - (typesCausingAbort[TYPE(header)]).numtrans+=1; - objtypetraverse[TYPE(header)]=1; -#endif -#if defined(STMSTATS)||defined(SOFTABORT) - if(getTotalAbortCount2((void *) curr->next, numoidrdlocked, oidrdlocked, oidrdversion, oidrdage, ObjSeqId, header, objtypetraverse)) - softabort=0; -#endif - DEBUGSTM("WR Abort: rd: %u wr: %u tot: %u type: %u ver: %u oid: %x\n", numoidrdlocked, numoidwrlocked, c_numelements, TYPE(header), header->version, OID(header)); - DEBUGSTMSTAT("WR Abort: Access Count: %u AbortCount: %u type: %u ver: %u \n", header->accessCount, header->abortCount, TYPE(header), header->version); - freearrays; - if (softabort) - return TRANS_SOFT_ABORT; - else - return TRANS_ABORT; - } - nextloop: - dc_curr = dc_curr->lnext; - } -#endif - - //THIS IS THE SERIALIZATION END POINT (START POINT IS END OF EXECUTION)***** - - for(i=0; ilock>0) { - CFENCE; - if(version != header->version) { -#ifdef DELAYCOMP - transAbortProcess(oidwrlocked, numoidwrtotal); -#else - transAbortProcess(oidwrlocked, numoidwrlocked); -#endif -#ifdef STMSTATS - ObjSeqId = oidrdage[i]; - header->abortCount++; - (typesCausingAbort[TYPE(header)]).numabort++; - (typesCausingAbort[TYPE(header)]).numaccess+=c_numelements; - (typesCausingAbort[TYPE(header)]).numtrans+=1; - objtypetraverse[TYPE(header)]=1; - getReadAbortCount(i+1, numoidrdlocked, oidrdlocked, oidrdversion, oidrdage, ObjSeqId, header, objtypetraverse); -#endif - DEBUGSTM("RD Abort: rd: %u wr: %u tot: %u type: %u ver: %u oid: %x\n", numoidrdlocked, numoidwrlocked, c_numelements, TYPE(header), header->version, OID(header)); - DEBUGSTMSTAT("RD Abort: Access Count: %u AbortCount: %u type: %u ver: %u \n", header->accessCount, header->abortCount, TYPE(header), header->version); - freearrays; - return TRANS_ABORT; - } -#ifdef DELAYCOMP - } else if (dc_t_chashSearch(((char *)header)+sizeof(objheader_t))!=NULL) { - //couldn't get lock because we already have it - //check if it is the right version number - if (version!=header->version) { - transAbortProcess(oidwrlocked, numoidwrtotal); -#ifdef STMSTATS - ObjSeqId = oidrdage[i]; - header->abortCount++; - getReadAbortCount(i+1, numoidrdlocked, oidrdlocked, oidrdversion, oidrdage, ObjSeqId, header, objtypetraverse); -#endif - DEBUGSTM("RD Abort: rd: %u wr: %u tot: %u type: %u ver: %u oid: %x\n", numoidrdlocked, numoidwrlocked, c_numelements, TYPE(header), header->version, OID(header)); - DEBUGSTMSTAT("RD Abort: Access Count: %u AbortCount: %u type: %u ver: %u \n", header->accessCount, header->abortCount, TYPE(header), header->version); - freearrays; - return TRANS_ABORT; - } -#endif - } else { /* cannot aquire lock */ - if(version == header->version) { - softabort=1; - } -#ifdef DELAYCOMP - transAbortProcess(oidwrlocked, numoidwrtotal); -#else - transAbortProcess(oidwrlocked, numoidwrlocked); -#endif -#ifdef STMSTATS - ObjSeqId = oidrdage[i]; - header->abortCount++; - (typesCausingAbort[TYPE(header)]).numabort++; - (typesCausingAbort[TYPE(header)]).numaccess+=c_numelements; - (typesCausingAbort[TYPE(header)]).numtrans+=1; - objtypetraverse[TYPE(header)]=1; -#endif -#if defined(STMSTATS)||defined(SOFTABORT) - if(getReadAbortCount(i+1, numoidrdlocked, oidrdlocked, oidrdversion, oidrdage, ObjSeqId, header, objtypetraverse)) - softabort=0; -#endif - DEBUGSTM("RD Abort: rd: %u wr: %u tot: %u type: %u ver: %u\n", numoidrdlocked, numoidwrlocked, c_numelements, TYPE(header), header->version); - DEBUGSTMSTAT("RD Abort: Access Count: %u AbortCount: %u type: %u ver: %u \n", header->accessCount, header->abortCount, TYPE(header), header->version); - freearrays; - if (softabort) - return TRANS_SOFT_ABORT; - else - return TRANS_ABORT; - } - } - -#ifdef READSET - //need to validate auxilary readset - rdchashlistnode_t *rd_curr = rd_c_list; - /* Inner loop to traverse the linked list of the cache lookupTable */ - while(likely(rd_curr != NULL)) { - //if the first bin in hash table is empty - int version=rd_curr->version; - objheader_t *header=(objheader_t *)(((char *)rd_curr->key)-sizeof(objheader_t)); - if(header->lock>0) { //object is not locked - if (version!=header->version) { - //have to abort -#ifdef DELAYCOMP - transAbortProcess(oidwrlocked, numoidwrtotal); -#else - transAbortProcess(oidwrlocked, numoidwrlocked); -#endif -#ifdef STMSTATS - //ABORTCOUNT(header); - (typesCausingAbort[TYPE(header)])++; -#endif -#if defined(STMSTATS)||defined(SOFTABORT) - //if(getTotalAbortCount2((void *) curr->next, numoidrdlocked, oidrdlocked, oidrdversion)) - // softabort=0; -#endif - DEBUGSTM("WR Abort: rd: %u wr: %u tot: %u type: %u ver: %u\n", numoidrdlocked, numoidwrlocked, c_numelements, TYPE(header), header->version); - DEBUGSTMSTAT("WR Abort: Access Count: %u AbortCount: %u type: %u ver: %u \n", header->accessCount, header->abortCount, TYPE(header), header->version); - freearrays; - if (softabort) - return TRANS_SOFT_ABORT; - else - return TRANS_ABORT; - } - } else { - if (version==header->version) { - void * key=rd_curr->key; -#ifdef DELAYCOMP - //check to see if it is in the delaycomp table - { - chashlistnode_t *node = &dc_c_table[(((unsigned INTPTR)key) & dc_c_mask)>>4]; - do { - if(node->key == key) - goto nextloopread; - node = node->next; - } while(node != NULL); - } -#endif - //check normal table - { - chashlistnode_t *node = &c_table[(((unsigned INTPTR)key) & c_mask)>>4]; - do { - if(node->key == key) { - objheader_t * headeraddr=&((objheader_t *) node->val)[-1]; - if(STATUS(headeraddr) & DIRTY) { - goto nextloopread; - } - } - node = node->next; - } while(node != NULL); - } - } -#ifdef DELAYCOMP - //have to abort to avoid deadlock - transAbortProcess(oidwrlocked, numoidwrtotal); -#else - transAbortProcess(oidwrlocked, numoidwrlocked); -#endif -#ifdef STMSTATS - //ABORTCOUNT(header); - (typesCausingAbort[TYPE(header)])++; -#endif -#if defined(STMSTATS)||defined(SOFTABORT) - // if(getTotalAbortCount2((void *) curr->next, numoidrdlocked, oidrdlocked, oidrdversion)) - //softabort=0; -#endif - DEBUGSTM("WR Abort: rd: %u wr: %u tot: %u type: %u ver: %u\n", numoidrdlocked, numoidwrlocked, c_numelements, TYPE(header), header->version); - DEBUGSTMSTAT("WR Abort: Access Count: %u AbortCount: %u type: %u ver: %u \n", header->accessCount, header->abortCount, TYPE(header), header->version); - freearrays; - if (softabort) - return TRANS_SOFT_ABORT; - else - return TRANS_ABORT; - } - nextloopread: - rd_curr = rd_curr->lnext; - } -#endif - - /* Decide the final response */ -#ifdef DELAYCOMP - transCommitProcess(oidwrlocked, numoidwrlocked, numoidwrtotal, commitmethod, primitives, locals, params); -#else - transCommitProcess(oidwrlocked, numoidwrlocked); -#endif - DEBUGSTM("Commit: rd: %u wr: %u tot: %u\n", numoidrdlocked, numoidwrlocked, c_numelements); - freearrays; - return TRANS_COMMIT; -} - -/* ================================== - * transAbortProcess - * - * ================================= - */ -void transAbortProcess(void **oidwrlocked, int numoidwrlocked) { - int i; - objheader_t *header; - /* Release read locks */ - - /* Release write locks */ - for(i=numoidwrlocked-1; i>=0; i--) { - /* Read from the main heap */ - header = (objheader_t *)oidwrlocked[i]; - write_unlock(&header->lock); - } - -#ifdef STMSTATS - /* clear trec and then release objects locked */ - struct objlist *ptr=lockedobjs; - while(ptr!=NULL) { - int max=ptr->offset; - for(i=max-1; i>=0; i--) { - header = (objheader_t *)ptr->objs[i]; - header->trec = NULL; - pthread_mutex_unlock(header->objlock); - } - ptr=ptr->next; - } -#endif -} - -/* ================================== - * transCommitProcess - * - * ================================= - */ -#ifdef DELAYCOMP - void transCommitProcess(void ** oidwrlocked, int numoidwrlocked, int numoidwrtotal, void (*commitmethod)(void *, void *, void *), void * primitives, void * locals, void * params) { -#else - void transCommitProcess(void ** oidwrlocked, int numoidwrlocked) { -#endif - objheader_t *header; - void *ptrcreate; - int i; - struct objlist *ptr=newobjs; - while(ptr!=NULL) { - int max=ptr->offset; - for(i=0; iobjs[i])->___objstatus___=0; - } - ptr=ptr->next; - } - - /* Copy from transaction cache -> main object store */ - for (i = numoidwrlocked-1; i >=0; i--) { - /* Read from the main heap */ - header = (objheader_t *)oidwrlocked[i]; - int tmpsize; - GETSIZE(tmpsize, header); - struct ___Object___ *dst=(struct ___Object___*)(((char *)oidwrlocked[i])+sizeof(objheader_t)); - struct ___Object___ *src=t_chashSearch(dst); - dst->___cachedCode___=src->___cachedCode___; - dst->___cachedHash___=src->___cachedHash___; - A_memcpy(&dst[1], &src[1], tmpsize-sizeof(struct ___Object___)); - } - CFENCE; - -#ifdef DELAYCOMP - // call commit method - ptrstack.count=0; - primstack.count=0; - branchstack.count=0; - commitmethod(params, locals, primitives); -#endif - - /* Release write locks */ -#ifdef DELAYCOMP - for(i=numoidwrtotal-1; i>=0; i--) { -#else - for(i=numoidwrlocked-1; i>=0; i--) { -#endif - header = (objheader_t *)oidwrlocked[i]; - header->version++; - write_unlock(&header->lock); - } - -#ifdef STMSTATS - /* clear trec and then release objects locked */ - ptr=lockedobjs; - while(ptr!=NULL) { - int max=ptr->offset; - for(i=max-1; i>=0; i--) { - header = (objheader_t *)ptr->objs[i]; - header->trec = NULL; - pthread_mutex_unlock(header->objlock); - } - ptr=ptr->next; - } -#endif -} - diff --git a/Robust/src/Runtime/STM/tm.h b/Robust/src/Runtime/STM/tm.h index 6dcbebf0..1a71dc2c 100644 --- a/Robust/src/Runtime/STM/tm.h +++ b/Robust/src/Runtime/STM/tm.h @@ -220,4 +220,38 @@ objheader_t * needLock(objheader_t *, void *); #ifdef SANDBOX #include "sandbox.h" #endif + +//STM Macros +#ifdef STMSTATS +#define DEBUGSTMSTAT(args...) +#else +#define DEBUGSTMSTAT(args...) +#endif + +#ifdef STMDEBUG +#define DEBUGSTM(x...) printf(x); +#else +#define DEBUGSTM(x...); +#endif + +#ifdef STATDEBUG +#define DEBUGSTATS(x...) printf(x); +#else +#define DEBUGSTATS(x...); +#endif + +#ifdef STMSTATS +/* Thread variable for locking/unlocking */ +extern __thread threadrec_t *trec; +extern __thread struct objlist * lockedobjs; +extern __thread int t_objnumcount; + +/* Collect stats for object classes causing abort */ +extern objtypestat_t typesCausingAbort[TOTALNUMCLASSANDARRAY]; +#endif + +extern void * curr_heapbase; +extern void * curr_heapptr; +extern void * curr_heaptop; + #endif -- 2.34.1