Common.java \
GlobalArgs.java \
../../../ClassLibrary/JavaSTM/Barrier.java
-FLAGS=-mainclass ${MAINCLASS} -singleTM -optimize -debug -dcopts -transstats -joptimize -stmdebug -stmstats
+FLAGS=-mainclass ${MAINCLASS} -singleTM -optimize -debug -dcopts -transstats -joptimize -stmstats
default:
../../../buildscript ${FLAGS} -o ${MAINCLASS} ${SRC}
if (state.THREAD||state.DSM||state.SINGLETM) {
outmethod.println("initializethreads();");
outmethod.println("#ifdef STMSTATS\n");
- outmethod.println(" for(i=0; i<TOTALNUMCLASSANDARRAY; i++) {");
- outmethod.println(" typesCausingAbort[i] = 0;");
- outmethod.println(" }");
+ outmethod.println("objlockscope = calloc(1, sizeof(objlockstate_t));");
+ outmethod.println("pthread_mutex_init(&lockedobjstore, NULL);");
+ outmethod.println("for(i=0; i<MAXOBJLIST; i++) {");
+ outmethod.println(" pthread_mutex_init(&(objlockscope->lock[i]), NULL);");
+ outmethod.println("}");
+ outmethod.println("for(i=0; i<TOTALNUMCLASSANDARRAY; i++) {");
+ outmethod.println(" typesCausingAbort[i] = 0;");
+ outmethod.println("}");
outmethod.println("#endif\n");
}
if (state.DSM) {
if (state.DSM) {
output.println("TRANSREAD("+generateTemp(fm, fgcn.getSrc(),lb)+", (unsigned int) "+generateTemp(fm, fgcn.getSrc(),lb)+");");
} else {
- output.println("TRANSREAD("+generateTemp(fm, fgcn.getSrc(),lb)+", "+generateTemp(fm, fgcn.getSrc(),lb)+");");
+ output.println("TRANSREAD("+generateTemp(fm, fgcn.getSrc(),lb)+", "+generateTemp(fm, fgcn.getSrc(),lb)+", (void *)&("+localsprefix+"));");
}
} else {
/* Need to convert to OID */
if (ffn.getField().getType().isPtr()&&locality.getAtomic(lb).get(ffn).intValue()>0&&
((dc==null)||dc.getNeedTrans(lb, ffn))&&
locality.getNodePreTempInfo(lb, ffn).get(ffn.getSrc())!=LocalityAnalysis.SCRATCH) {
- output.println("TRANSREAD("+dst+", "+dst+");");
+ output.println("TRANSREAD("+dst+", "+dst+", (void *) &(" + localsprefix + "));");
}
} else if (state.DSM) {
Integer status=locality.getNodePreTempInfo(lb,ffn).get(ffn.getSrc());
if (elementtype.isPtr()&&locality.getAtomic(lb).get(fen).intValue()>0&&
((dc==null)||dc.getNeedTrans(lb, fen))&&
locality.getNodePreTempInfo(lb, fen).get(fen.getSrc())!=LocalityAnalysis.SCRATCH) {
- output.println("TRANSREAD("+dst+", "+dst+");");
+ output.println("TRANSREAD("+dst+", "+dst+", (void *)&(" + localsprefix+"));");
}
} else if (state.DSM) {
Integer status=locality.getNodePreTempInfo(lb,fen).get(fen.getSrc());
#include "tm.h"
#include "garbage.h"
-/*** Globals *****/
-/* Thread transaction variables */
+/* Per thread transaction variables */
__thread objstr_t *t_cache;
__thread objstr_t *t_reserve;
__thread struct objlist * newobjs;
/** Global lock **/
int typesCausingAbort[TOTALNUMCLASSANDARRAY];
/******Keep track of objects and types causing aborts******/
-/*TODO
+/* TODO uncomment for later use
#define DEBUGSTMSTAT(args...) { \
printf(args); \
fflush(stdout); \
#define DEBUGSTM(x...)
#endif
-#define ABORTCOUNT(x) x->abortCount++; \
- if (x->abortCount > MAXABORTS) { \
- x->riskyflag = 1; \
+#ifdef STMSTATS
+/*** Global variables *****/
+objlockstate_t *objlockscope;
+/**
+ * ABORTCOUNT
+ * params: object header
+ * Increments the abort count for each object
+ **/
+void ABORTCOUNT(objheader_t * x) {
+ x->abortCount++;
+ if (x->abortCount > MAXABORTS && (x->riskyflag != 1)) {
+ //makes riskflag sticky
+ x->riskyflag = 1;
+ pthread_mutex_lock(&lockedobjstore);
+ if (objlockscope->offset<MAXOBJLIST) {
+ x->objlock=&(objlockscope->lock[objlockscope->offset++]);
+ } else {
+ objlockstate_t *tmp=malloc(sizeof(objlockstate_t));
+ int i;
+ for(i=0; i<MAXOBJLIST; i++)
+ pthread_mutex_init(&(tmp->lock[i]), NULL);
+ tmp->next=objlockscope;
+ x->objlock=&(tmp->lock[0]);
+ tmp->offset=1;
+ objlockscope=tmp;
+ }
+ pthread_mutex_unlock(&lockedobjstore);
}
+}
+#endif
/* ==================================================
* stmStartup
tmp->accessCount = 0;
tmp->riskyflag = 0;
tmp->trec = NULL;
- //initialize obj lock
- pthread_mutex_init(&tmp->objlock, NULL);
+ //initialize obj lock to the header
+ tmp->objlock = NULL;
STATUS(tmp)=NEW;
// don't insert into table
if (newobjs->offset<MAXOBJLIST) {
* -copies the object into the transaction cache
* =============================================================
*/
-__attribute__((pure)) void *transRead(void * oid) {
+__attribute__((pure)) void *transRead(void * oid, void *gl) {
objheader_t *tmp, *objheader;
objheader_t *objcopy;
int size;
//DEBUGSTMSTAT("type: %d, header->abortCount: %d, header->accessCount: %d, riskratio: %f\n", TYPE(header), header->abortCount, header->accessCount, riskratio);
//DEBUGSTMSTAT("type: %d, header->abortCount: %d, header->accessCount: %d\n", TYPE(header), header->abortCount, header->accessCount);
//if(header->abortCount > MAXABORTS && riskratio > NEED_LOCK_THRESHOLD) {
- if (header->riskyflag) {
- //makes riskflag sticky
- needLock(header);
+ if(header->riskyflag) {
+ needLock(header,gl);
}
#endif
/* Insert into cache's lookup table */
for(i=0; i<max; i++) {
header = (objheader_t *)((char *)(ptr->objs[i]) - sizeof(objheader_t));
header->trec = NULL;
- pthread_mutex_unlock(&(header->objlock));
+ pthread_mutex_unlock(header->objlock);
}
ptr=ptr->next;
}
for(i=0; i<max; i++) {
header = (objheader_t *)(((char *)(ptr->objs[i])) - sizeof(objheader_t));
header->trec = NULL;
- pthread_mutex_unlock(&(header->objlock));
+ pthread_mutex_unlock(header->objlock);
}
ptr=ptr->next;
}
* params: Object header
* Locks an object that causes aborts
**/
-void needLock(objheader_t *header) {
+void needLock(objheader_t *header, void *gl) {
int lockstatus;
threadrec_t *ptr;
- while((lockstatus = pthread_mutex_trylock(&(header->objlock)))
+ while((lockstatus = pthread_mutex_trylock(header->objlock))
&& ((ptr = header->trec) == NULL)) { //retry
;
}
trec->blocked=0;
return;
} else {
+#ifdef PRECISE_GC
+ struct listitem *tmp=stopforgc((struct garbagelist *)gl);
+#endif
//grab lock and wait our turn
- pthread_mutex_lock(&(header->objlock));
+ pthread_mutex_lock(header->objlock);
+#ifdef PRECISE_GC
+ restartaftergc(tmp);
+#endif
/* we have lock, so we are not blocked anymore */
trec->blocked = 0;
/* Set our trec */
int accessCount; /* track how many times is this object accessed */
threadrec_t *trec; /* some thread that locked this object */
int riskyflag; /* track how risky is the object */
- pthread_mutex_t objlock; /* lock this object */
+ pthread_mutex_t *objlock; /* lock this object */
} objheader_t;
#define OID(x) \
#define NEED_LOCK_THRESHOLD 0.020000
#define OSUSED(x) (((unsigned INTPTR)(x)->top)-((unsigned INTPTR) (x+1)))
#define OSFREE(x) ((x)->size-OSUSED(x))
-#define TRANSREAD(x,y) { \
+#define TRANSREAD(x,y,z) { \
void * inputvalue; \
if ((inputvalue=y)==NULL) x=NULL;\
else { \
if (cnodetmp->key==inputvalue) {x=cnodetmp->val; break;} \
cnodetmp=cnodetmp->next; \
if (cnodetmp==NULL) {if (((struct ___Object___*)inputvalue)->___objstatus___&NEW) {x=inputvalue; break;} else \
- {x=transRead(inputvalue); asm volatile ("" : "=m" (c_table),"=m" (c_mask)); break;}} \
+ {x=transRead(inputvalue,z); asm volatile ("" : "=m" (c_table),"=m" (c_mask)); break;}} \
} while(1); \
}}
extern __thread objstr_t *t_cache;
extern __thread objstr_t *t_reserve;
#ifdef STMSTATS
+typedef struct objlockstate {
+ int offset;
+ pthread_mutex_t lock[MAXOBJLIST];
+ struct objlockstate *next;
+} objlockstate_t;
extern __thread threadrec_t *trec;
extern __thread struct objlist * lockedobjs;
+extern objlockstate_t *objlockscope;
+pthread_mutex_t lockedobjstore;
#endif
objheader_t *transCreateObj(void * ptr, unsigned int size);
unsigned int getNewOID(void);
void *objstrAlloc(unsigned int size);
-__attribute__((pure)) void *transRead(void * oid);
+__attribute__((pure)) void *transRead(void *, void *);
int transCommit();
int traverseCache();
int alttraverseCache();
void randomdelay(int);
#ifdef STMSTATS
void getTotalAbortCount(int, int, void *, void *, int);
-void needLock(objheader_t *);
+void needLock(objheader_t *, void *);
#endif
#endif