if (state.SANDBOX) {
outmethodheader.println("#include \"sandbox.h\"");
}
+ if (state.EVENTMONITOR) {
+ outmethodheader.println("#include \"monitor.h\"");
+ }
if (state.SINGLETM) {
outmethodheader.println("#include \"tm.h\"");
outmethodheader.println("#include \"delaycomp.h\"");
outmethod.println("#endif\n");
}
+ if (state.EVENTMONITOR) {
+ outmethod.println("dumpdata();");
+ }
+
if (state.THREAD||state.SINGLETM)
outmethod.println("pthread_exit(NULL);");
//Print out definition for array type
outclassdefs.println("struct "+arraytype+" {");
outclassdefs.println(" int type;");
+ if (state.EVENTMONITOR) {
+ outclassdefs.println(" int objuid;");
+ }
if (state.THREAD) {
outclassdefs.println(" pthread_t tid;");
outclassdefs.println(" void * lockentry;");
/* Output class structure */
classdefout.println("struct "+cn.getSafeSymbol()+" {");
classdefout.println(" int type;");
+ if (state.EVENTMONITOR) {
+ classdefout.println(" int objuid;");
+ }
if (state.THREAD) {
classdefout.println(" pthread_t tid;");
classdefout.println(" void * lockentry;");
ar.liveout=liveout;
ar.liveoutvirtualread=liveoutvirtualread;
+
for(Iterator<TempDescriptor> it=liveinto.iterator(); it.hasNext();) {
TempDescriptor tmp=it.next();
//remove the pointers
}
if (wb.needBarrier(fsfn)&&
locality.getNodePreTempInfo(lb, fsfn).get(fsfn.getDst())!=LocalityAnalysis.SCRATCH) {
+ if (state.EVENTMONITOR) {
+ output.println("if ("+dst+"->___objstatus___&DIRTY) EVLOGEVENTOBJ(EV_WRITE,"+dst+"->objuid)");
+ }
output.println("*((unsigned int *)&("+dst+"->___objstatus___))|=DIRTY;");
}
if (srcptr&!fsfn.getSrc().getType().isNull()) {
public boolean DSMTASK=false;
public static boolean ABORTREADERS=false;
//STM options
+ public boolean EVENTMONITOR=false;
public static boolean STMARRAY=false;
public static boolean SINGLETM=false;
public static boolean READSET=false;
state.TAGSTATE=true;
else if (option.equals("-stmarray"))
state.STMARRAY=true;
+ else if (option.equals("-eventmonitor"))
+ state.EVENTMONITOR=true;
else if (option.equals("-dualview"))
state.DUALVIEW=true;
else if (option.equals("-hybrid"))
version=(unsigned int *)((char *)array-sizeof(objheader_t)-sizeof(int)*2*(byteindex)-sizeof(int)); \
}
+#ifdef EVENTMONITOR
+#define EVGETARRAY(array, index) EVLOGEVENTARRAY(EV_ARRAYREAD,array->objuid,index)
+#define EVSETARRAY(cond, array, index) if (cond!=STMDIRTY) EVLOGEVENTARRAY(EV_ARRAYWRITE,array->objuid,index)
+#else
+#define EVGETARRAY(array, index)
+#define EVSETARRAY(cond, array, index)
+#endif
+
#define STMGETARRAY(dst, array, index, type) { \
if (((char *)array)!=((char *)array->___objlocation___)) { \
if(!(array->___objstatus___&NEW)) { \
GETLOCKPTR(status, array, metaindex); \
if (metaindex<array->lowindex||metaindex>array->highindex \
||(*status)==STMNONE) { \
+ EVGETARRAY(array, metaindex); \
arraycopy(array, byteindex); \
(*status)=STMCLEAN;} \
} \
||(*status)==STMNONE) { \
arraycopy(array, byteindex); \
} \
+ EVSETARRAY(*status, array, metaindex); \
(*status)=STMDIRTY; \
} \
((type *)(((char *) &array->___length___)+sizeof(int)))[index]=src; \
#ifdef DELAYCOMP
#include<delaycomp.h>
#endif
+#ifdef EVENTMONITOR
+#include"monitor.h"
+#endif
#ifdef TRANSSTATS
#define TRANSWRAP(x) x
#ifdef SANDBOX
abortenabled=1;
#endif
-
+#ifdef EVENTMONITOR
+ EVLOGEVENT(EV_ABORT);
+#endif
return TRANS_ABORT;
}
if(finalResponse == TRANS_COMMIT) {
#if defined(STMARRAY)&&!defined(DUALVIEW)
arraystack.count=0;
#endif
+#endif
+#ifdef EVENTMONITOR
+ EVLOGEVENT(EV_COMMIT);
#endif
return 0;
}
#if defined(STMARRAY)&&!defined(DUALVIEW)
arraystack.count=0;
#endif
+#endif
+#ifdef EVENTMONITOR
+ EVLOGEVENT(EV_ABORT);
#endif
return TRANS_ABORT;
}
int j;
int addwrobject=0, addrdobject=0;
int elementsize=classsize[type];
- int baseoffset=(lowoffset<<INDEXSHIFT)+sizeof(int)+((int)&(((struct ArrayObject *)0)->___length___));
+ int baseoffset=(lowoffset<<INDEXSHIFT)+sizeof(int)+((int)(INTPTR)&(((struct ArrayObject *)0)->___length___));
char *dstptr=((char *)dst)+baseoffset;
char *srcptr=((char *)src)+baseoffset;
for(j=lowoffset; j<=highoffset;j++, srcptr+=INDEXLENGTH,dstptr+=INDEXLENGTH) {
+#include "runtime.h"
#include "monitor.h"
#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
+#include <stdlib.h>
+
+__thread struct eventmonitor * events;
+struct eventmonitor * eventlist;
+static volatile int threadcount=0;
+__thread int threadnum;
+
+static inline int atomicinc(volatile int *lock) {
+ int retval=1;
+ __asm__ __volatile__("lock; xadd %0,%1"
+ : "=r"(retval)
+ : "m"(*lock), "0"(retval)
+ : "memory");
+ return retval;
+}
//Need to have global lock before calling this method
void createmonitor() {
struct eventmonitor *event=calloc(1, sizeof(struct eventmonitor));
//add new eventmonitor to list
event->next=eventlist;
- eventlist=events;
+ eventlist=event;
+ int ourcount=atomicinc(&threadcount);
+ threadnum=ourcount;
+ if (threadnum>=MAXEVTHREADS) {
+ printf("ERROR: Threads exceeds MAXEVTHREADS\n");
+ }
+
//point thread lock variable to eventmonitor
events=event;
- EVLOGEVENT(EM_THREAD);
+ EVLOGEVENT(EV_THREAD);
}
void writedata(int fd, char * buffer, int count) {
}
void dumpdata() {
- int fd=open("logdata",O_RDWR|O_CREAT);
+ int fd=open("logdata",O_RDWR|O_CREAT,S_IRWXU);
int count=0;
struct eventmonitor * ptr=eventlist;
while(ptr!=NULL) {
count++;
+ if (ptr->index>MAXEVENTS) {
+ printf("ERROR: EVENT COUNT EXCEEDED\n");
+ }
ptr=ptr->next;
}
- writedata(fd, &count, sizeof(int));
+ writedata(fd, (char *)&count, sizeof(int));
ptr=eventlist;
- if (ptr->index>MAXEVENTS) {
- printf("ERROR: EVENT COUNT EXCEEDED\n")
- }
while(ptr!=NULL) {
- writedata(fd, &ptr->index, sizeof(int));
- writedata(fd, ptr->value, sizeof(int)*ptr->index);
+ writedata(fd, (char *) &ptr->index, sizeof(int));
+ writedata(fd, (char *) ptr->value, sizeof(int)*ptr->index);
ptr=ptr->next;
}
close(fd);
#define EV_START 4
#define EV_COMMIT 5
#define EV_ABORT 6
+#define EV_ARRAYREAD 7
+#define EV_ARRAYWRITE 8
struct eventmonitor {
int index;
unsigned int value[MAXEVENTS];
};
+#define MAXEVTHREADS 16
+#define EVTHREADSHIFT 4
+extern __thread int threadnum;
extern __thread struct eventmonitor * events;
extern struct eventmonitor * eventlist;
void createmonitor();
void dumpdata();
-#if defined(__i386__)
-static __inline__ unsigned long long rdtsc(void)
-{
- unsigned long long int x;
- __asm__ volatile (".byte 0x0f, 0x31" : "=A" (x));
- return x;
-}
-#elif defined(__x86_64__)
-static __inline__ unsigned long long rdtsc(void)
-{
- unsigned hi, lo;
- __asm__ __volatile__ ("rdtsc" : "=a"(lo), "=d"(hi));
- return ( (unsigned long long)lo)|( ((unsigned long long)hi)<<32 );
-}
-#endif
-
#define LOGTIME *((long long *)&events->value[events->index])=rdtsc(); \
events->index+=2;
}
#define EVLOGEVENTOBJ(x,o) { events->value[events->index++]=x; \
- events->value[events->index++]=o; \
+ events->value[events->index++]=o; \
LOGTIME \
}
+#define EVLOGEVENTARRAY(x,o,i) { events->value[events->index++]=x; \
+ events->value[events->index++]=o; \
+ events->value[events->index++]=i; \
+ LOGTIME \
+ }
+
#endif
#include "tm.h"
#include "garbage.h"
+#ifdef EVENTMONITOR
+#include "monitor.h"
+#endif
/* Per thread transaction variables */
__thread objstr_t *t_cache;
*/
void transStart() {
//Transaction start is currently free...commit and aborting is not
+#ifdef EVENTMONITOR
+ EVLOGEVENT(EV_START);
+#endif
}
/* =======================================================
size += sizeof(objheader_t);
objcopy = (objheader_t *) objstrAlloc(size);
A_memcpy(objcopy, header, size);
+#ifdef EVENTMONITOR
+ EVLOGEVENTOBJ(EV_READ, ((struct ___Object___ *)oid)->objuid);
+#endif
}
#else
GETSIZE(size, header);
size += sizeof(objheader_t);
objcopy = (objheader_t *) objstrAlloc(size);
A_memcpy(objcopy, header, size);
+#ifdef EVENTMONITOR
+ EVLOGEVENTOBJ(EV_READ, ((struct ___Object___ *) oid)->objuid);
+#endif
#endif
#ifdef STMSTATS
/* keep track of the object's access sequence in a transaction */
unsigned long long beginClock=0;
#define FILENAME "log"
#endif
+#ifdef EVENTMONITOR
+#include "monitor.h"
+__thread int objcount=0;
+#define ASSIGNUID(x) { \
+ int number=((objcount++)<<EVTHREADSHIFT)|threadnum; \
+ x->objuid=number; \
+ }
+#else
+#define ASSIGNUID(x)
+#endif
#if defined(THREADS)||defined(STM)
/* Global barrier for STM */
}
#endif
#endif
+#endif
+#ifdef EVENTMONITOR
+ dumpdata();
#endif
exit(___status___);
}
-#if defined(__i386__)
-
-static __inline__ unsigned long long rdtsc(void)
-{
- unsigned long long int x;
- __asm__ volatile (".byte 0x0f, 0x31" : "=A" (x));
- return x;
-}
-#elif defined(__x86_64__)
-
-static __inline__ unsigned long long rdtsc(void)
-{
- unsigned hi, lo;
- __asm__ __volatile__ ("rdtsc" : "=a"(lo), "=d"(hi));
- return ( (unsigned long long)lo)|( ((unsigned long long)hi)<<32 );
-}
-
-#elif defined(__powerpc__)
-
-typedef unsigned long long int unsigned long long;
-
-static __inline__ unsigned long long rdtsc(void)
-{
- unsigned long long int result=0;
- unsigned long int upper, lower,tmp;
- __asm__ volatile(
- "0: \n"
- "\tmftbu %0 \n"
- "\tmftb %1 \n"
- "\tmftbu %2 \n"
- "\tcmpw %2,%0 \n"
- "\tbne 0b \n"
- : "=r"(upper),"=r"(lower),"=r"(tmp)
- );
- result = upper;
- result = result<<32;
- result = result|lower;
-
- return(result);
-}
-#endif
-
void CALL11(___System______logevent____I,int ___event___, int ___event___) {
#ifdef STMLOG
event[counter] = ___event___;
printf("%s() Could not wait on barrier: error %d in %s\n", __func__, errno, __FILE__);
exit(-1);
}
+#ifdef EVENTMONITOR
+ EVLOGEVENT(EV_BARRIER);
+#endif
}
#endif
#else
struct ___Object___ * v=(struct ___Object___ *) transCreateObj(ptr, classsize[type]);
#endif
+ ASSIGNUID(v);
v->type=type;
v->___objlocation___=v;
return v;
#else
struct ArrayObject * v=(struct ArrayObject *)transCreateObj(ptr, sizeof(struct ArrayObject)+length*classsize[type]);
#endif
+ ASSIGNUID(v);
if (length<0) {
printf("ERROR: negative array\n");
return NULL;
__attribute__((malloc)) void * allocate_new(void * ptr, int type) {
objheader_t *tmp=mygcmalloc((struct garbagelist *) ptr, classsize[type]+sizeof(objheader_t));
struct ___Object___ * v=(struct ___Object___ *) &tmp[1];
+ ASSIGNUID(v);
initdsmlocks(&tmp->lock);
tmp->version = 1;
v->___objlocation___=v;
initdsmlocks(&tmp->lock);
#endif
tmp->version=1;
+ ASSIGNUID(v);
v->type=type;
if (length<0) {
printf("ERROR: negative array %d\n", length);
#endif
+#if defined(__i386__)
+
+static __inline__ unsigned long long rdtsc(void)
+{
+ unsigned long long int x;
+ __asm__ volatile (".byte 0x0f, 0x31" : "=A" (x));
+ return x;
+}
+#elif defined(__x86_64__)
+
+static __inline__ unsigned long long rdtsc(void)
+{
+ unsigned hi, lo;
+ __asm__ __volatile__ ("rdtsc" : "=a"(lo), "=d"(hi));
+ return ( (unsigned long long)lo)|( ((unsigned long long)hi)<<32 );
+}
+
+#elif defined(__powerpc__)
+
+typedef unsigned long long int unsigned long long;
+
+static __inline__ unsigned long long rdtsc(void)
+{
+ unsigned long long int result=0;
+ unsigned long int upper, lower,tmp;
+ __asm__ volatile(
+ "0: \n"
+ "\tmftbu %0 \n"
+ "\tmftb %1 \n"
+ "\tmftbu %2 \n"
+ "\tcmpw %2,%0 \n"
+ "\tbne 0b \n"
+ : "=r"(upper),"=r"(lower),"=r"(tmp)
+ );
+ result = upper;
+ result = result<<32;
+ result = result|lower;
+
+ return(result);
+}
+#endif
+
+
#endif
#include "tm.h"
#endif
#include <execinfo.h>
+#ifdef EVENTMONITOR
+#include "monitor.h"
+#endif
int threadcount;
list->prev=&litem;
list=&litem;
#endif
+#ifdef EVENTMONITOR
+ createmonitor();
+#endif
}
#if defined(THREADS)||defined(STM)
#ifdef AFFINITY
set_affinity();
#endif
+#ifdef EVENTMONITOR
+ createmonitor();
+#endif
#ifdef SANDBOX
struct sigaction sig;
abortenabled=0;
echo "-dualview dual view of arrays"
echo "-hybrid use fission only when it looks like a good choice"
echo "-numa numa aware"
+echo "-eventmonitor turn on transaction event trace recording"
echo
echo DSM options
echo -dsm distributed shared memory
STMARRAY=false
DUALVIEW=false
STM=false
+EVENTMONITOR=false
NOJAVA=false
CHECKFLAG=false
RECOVERFLAG=false
elif [[ $1 = '-nojava' ]]
then
NOJAVA=true
+elif [[ $1 = '-eventmonitor' ]]
+then
+JAVAOPTS="$JAVAOPTS -eventmonitor"
+EVENTMONITOR=true
+EXTRAOPTIONS="$EXTRAOPTIONS -DEVENTMONITOR"
elif [[ $1 = '-garbagestats' ]]
then
EXTRAOPTIONS="$EXTRAOPTIONS -DGARBAGESTATS"
FILES="$FILES $ROBUSTROOT/Runtime/affinity.c"
fi
+if $EVENTMONITOR
+then
+FILES="$FILES $ROBUSTROOT/Runtime/STM/monitor.c"
+fi
+
if $FASTMEMCPY
then
FILES="$FILES $ROBUSTROOT/Runtime/memcpy32.o $ROBUSTROOT/Runtime/instrset32.o"