X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;ds=sidebyside;f=Robust%2Fsrc%2FRuntime%2Fruntime.c;h=c175242faf4de4d6beb6b940a4b3cfcf725f36b2;hb=6a37681b314d9ed892ea004ee4cb638f8118820b;hp=818138debe8501e7a47ff59eac8220bca5dfce5b;hpb=cacaf39ca7d94217f19f4944229a3a331bb96e02;p=IRC.git diff --git a/Robust/src/Runtime/runtime.c b/Robust/src/Runtime/runtime.c index 818138de..c175242f 100644 --- a/Robust/src/Runtime/runtime.c +++ b/Robust/src/Runtime/runtime.c @@ -1,306 +1,453 @@ #include "runtime.h" #include "structdefs.h" -#include #include #include "mem.h" -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include "option.h" +#include "methodheaders.h" +#ifdef DSTM +#include "dstm.h" +#include "prelookup.h" +#include "prefetch.h" +#endif +#ifdef STM +#include "tm.h" +#include +#endif + +#if defined(THREADS)||defined(STM) +/* Global barrier for STM */ +pthread_barrier_t barrier; +pthread_barrierattr_t attr; +#endif + +#include extern int classsize[]; +extern int typearray[]; +extern int typearray2[]; jmp_buf error_handler; +int instructioncount; -#ifdef TASK -#include "checkpoint.h" -#include "Queue.h" -#include "SimpleHash.h" -#include "GenericHashtable.h" -#ifdef CONSCHECK -#include "initialize.h" +char *options; +int injectfailures=0; +float failurechance=0; +int errors=0; +int debugtask=0; +int injectinstructionfailures; +int failurecount; +float instfailurechance=0; +int numfailures; +int instaccum=0; +#ifdef DMALLOC +#include "dmalloc.h" #endif -struct Queue * activetasks; -struct parameterwrapper * objectqueues[NUMCLASSES]; -struct genhashtable * failedtasks; +int instanceof(struct ___Object___ *ptr, int type) { + int i=ptr->type; + do { + if (i==type) + return 1; + i=typearray[i]; + } while(i!=-1); + i=ptr->type; + if (i>NUMCLASSES) { + do { + if (i==type) + return 1; + i=typearray2[i-NUMCLASSES]; + } while(i!=-1); + } + return 0; +} + +void exithandler(int sig, siginfo_t *info, void * uap) { + exit(0); +} + +void initializeexithandler() { + struct sigaction sig; + sig.sa_sigaction=&exithandler; + sig.sa_flags=SA_SIGINFO; + sigemptyset(&sig.sa_mask); + sigaction(SIGUSR2, &sig, 0); +} -int main(int argc, char **argv) { - GC_init(); -#ifdef CONSCHECK - initializemmap(); + +/* This function inject failures */ + +void injectinstructionfailure() { +#ifdef TASK + if (injectinstructionfailures) { + if (numfailures==0) + return; + instructioncount=failurecount; + instaccum+=failurecount; + if ((((double)random())/RAND_MAX)0) + numfailures--; + printf("FAILURE!!! %d\n",numfailures); + longjmp(error_handler,11); + } + } +#else +#ifdef THREADS + if (injectinstructionfailures) { + if (numfailures==0) + return; + instaccum+=failurecount; + if ((((double)random())/RAND_MAX)0) + numfailures--; + printf("FAILURE!!! %d\n",numfailures); + threadexit(); + } + } #endif - { +#endif +} + +#ifdef D___Double______nativeparsedouble____L___String___ +double CALL01(___Double______nativeparsedouble____L___String___,struct ___String___ * ___str___) { + int length=VAR(___str___)->___count___; + int maxlength=(length>60)?60:length; + char str[maxlength+1]; + struct ArrayObject * chararray=VAR(___str___)->___value___; int i; - /* Allocate startup object */ - struct ___StartupObject___ *startupobject=(struct ___StartupObject___*) allocate_new(STARTUPTYPE); - struct ArrayObject * stringarray=allocate_newarray(STRINGARRAYTYPE, argc); - failedtasks=genallocatehashtable((unsigned int (*)(void *)) &hashCodetpd, - (int (*)(void *,void *)) &comparetpd); - - activetasks=createQueue(); - - /* Set flags */ - processtasks(); - flagorand(startupobject,1,0xFFFFFFFF); - - /* Build array of strings */ - - startupobject->___parameters___=stringarray; - - for(i=0;i___length___)+sizeof(int)))[i]=newstring; + int offset=VAR(___str___)->___offset___; + for(i=0; i___length___)+sizeof(int)))[i+offset]; } - executetasks(); + str[i]=0; + double d=atof(str); + return d; +} +#endif + +#ifdef D___String______convertdoubletochar____D__AR_C +int CALL12(___String______convertdoubletochar____D__AR_C, double ___val___, double ___val___, struct ArrayObject ___chararray___) { + int length=VAR(___chararray___)->___length___; + char str[length]; + int i; + int num=snprintf(str, length, "%f",___val___); + if (num>=length) + num=length-1; + for(i=0; i___length___)+sizeof(int)))[i]=(short)str[i]; } + return num; } +#endif -int hashCodetpd(struct taskparamdescriptor *ftd) { - int hash=(int)ftd->task; +void CALL11(___System______exit____I,int ___status___, int ___status___) { +#ifdef TRANSSTATS + printf("numTransCommit = %d\n", numTransCommit); + printf("numTransAbort = %d\n", numTransAbort); + printf("nSoftAbort = %d\n", nSoftAbort); +#ifdef STM + printf("nSoftAbortCommit = %d\n", nSoftAbortCommit); + printf("nSoftAbortAbort = %d\n", nSoftAbortAbort); +#ifdef STMSTATS int i; - for(i=0;inumParameters;i++) { - hash^=(int)ftd->parameterArray[i]; + for(i=0; i___length___))+sizeof(unsigned int)+sizeof(void *)*___index___; + memmove(offset, offset+sizeof(void *),(___size___-___index___-1)*sizeof(void *)); +} +#endif + +void CALL11(___System______printI____I,int ___status___, int ___status___) { + printf("%d\n",___status___); } -int comparetpd(struct taskparamdescriptor *ftd1, struct taskparamdescriptor *ftd2) { +long long CALL00(___System______currentTimeMillis____) { + struct timeval tv; long long retval; + gettimeofday(&tv, NULL); + retval = tv.tv_sec; /* seconds */ + retval*=1000; /* milliseconds */ + retval+= (tv.tv_usec/1000); /* adjust milliseconds & add them in */ + return retval; +} + +void CALL01(___System______printString____L___String___,struct ___String___ * ___s___) { + struct ArrayObject * chararray=VAR(___s___)->___value___; int i; - if (ftd1->task!=ftd2->task) - return 0; - for(i=0;inumParameters;i++) - if (ftd1->parameterArray[i]!=ftd2->parameterArray[i]) - return 0; - return 1; + int offset=VAR(___s___)->___offset___; + for(i=0; i___count___; i++) { + short sc=((short *)(((char *)&chararray->___length___)+sizeof(int)))[i+offset]; + putchar(sc); + } +} + +#ifdef DSTM +void CALL00(___System______clearPrefetchCache____) { + prehashClear(); } -void flagorand(void * ptr, int ormask, int andmask) { - int flag=((int *)ptr)[1]; - struct RuntimeHash *flagptr=(struct RuntimeHash *)(((int*)ptr)[2]); - flag|=ormask; - flag&=andmask; - ((int*)ptr)[1]=flag; - /*Remove from all queues */ - while(flagptr!=NULL) { - struct RuntimeHash *next; - RuntimeHashget(flagptr, (int) ptr, (int *) &next); - RuntimeHashremove(flagptr, (int)ptr, (int) next); - flagptr=next; +#ifdef RANGEPREFETCH +void CALL02(___System______rangePrefetch____L___Object_____AR_S, struct ___Object___ * ___o___, struct ArrayObject * ___offsets___) { + /* Manual Prefetches to be inserted */ + //printf("DEBUG-> %s() ___Object___ * ___o___ = %x\n", __func__, VAR(___o___)); + //printf("DEBUG-> %s() ArrayObject * = %x\n", __func__, VAR(___offsets___)); + int numoffset=VAR(___offsets___)->___length___; + int i; + short offArry[numoffset+2]; + offArry[0] = 0; + offArry[1] = 0; + for(i = 2; i<(numoffset+2); i++) { + offArry[i] = *((short *)(((char *)&VAR(___offsets___)->___length___) + sizeof(int) + (i-2) * sizeof(short))); + //printf("DEBUG-> offArry[%d] = %d\n", i, offArry[i]); } - - { - struct QueueItem *tmpptr; - struct parameterwrapper * parameter=objectqueues[((int *)ptr)[0]]; - int i; - struct RuntimeHash * prevptr=NULL; - while(parameter!=NULL) { - for(i=0;inumberofterms;i++) { - int andmask=parameter->intarray[i*2]; - int checkmask=parameter->intarray[i*2+1]; - if ((flag&andmask)==checkmask) { - RuntimeHashadd(parameter->objectset, (int) ptr, (int) prevptr); - prevptr=parameter->objectset; - { - struct RuntimeIterator iteratorarray[MAXTASKPARAMS]; - void * taskpointerarray[MAXTASKPARAMS]; - int j; - int numparams=parameter->task->numParameters; - int done=1; - struct taskdescriptor * task=parameter->task; - int newindex=-1; - for(j=0;jdescriptorarray[j]->queue; - if (parameter==pw) { - taskpointerarray[j]=ptr; - newindex=j; - } else { - RuntimeHashiterator(pw->objectset, &iteratorarray[j]); - if (RunhasNext(&iteratorarray[j])) - taskpointerarray[j]=(void *) Runnext(&iteratorarray[j]); - else - break; /* No tasks to dispatch */ - } - } - /* Queue task items... */ - - while(done) { - struct taskparamdescriptor *tpd=RUNMALLOC(sizeof(struct taskparamdescriptor)); - tpd->task=task; - tpd->numParameters=numparams; - tpd->parameterArray=RUNMALLOC(sizeof(void *)*numparams); - for(j=0;jparameterArray[j]=taskpointerarray[j]; - /* Queue task */ - if (!gencontains(failedtasks, tpd)) - addNewItem(activetasks, tpd); - - /* This loop iterates to the next paramter combination */ - for(j=0;jdescriptorarray[j]->queue, &iteratorarray[j]); - } else { - done=0; - break; - } - } - } - } - break; - } - } - parameter=parameter->next; - } - ((struct RuntimeHash **)ptr)[2]=prevptr; + unsigned int oid; + if(((unsigned int)(VAR(___o___)) & 1) != 0) { //odd + oid = (unsigned int) VAR(___o___); //outside transaction therefore just an oid + } else { //even + oid = (unsigned int) COMPOID(VAR(___o___)); //inside transaction therefore a pointer to oid } + rangePrefetch(oid, (short)(numoffset+2), offArry); +} +#else +void CALL02(___System______rangePrefetch____L___Object_____AR_S, struct ___Object___ * ___o___, struct ArrayObject * ___offsets___) { + return; } +#endif -/* Handler for signals */ -void myhandler(int sig, struct __siginfo *info, void *uap) { -#ifdef DEBUG - printf("sig=%d\n",sig); - printf("signal\n"); #endif - longjmp(error_handler,1); + +/* STM Barrier constructs */ +#ifdef D___Barrier______setBarrier____I +void CALL11(___Barrier______setBarrier____I, int nthreads, int nthreads) { + // Barrier initialization + int ret; + if((ret = pthread_barrier_init(&barrier, NULL, nthreads)) != 0) { + printf("%s() Could not create a barrier: numthreads = 0 in %s\n", __func__, __FILE__); + exit(-1); + } } +#endif -void executetasks() { - void * taskpointerarray[MAXTASKPARAMS]; +#ifdef D___Barrier______enterBarrier____ +void CALL00(___Barrier______enterBarrier____) { + // Synchronization point + int ret; +#ifdef PRECISE_GC + stopforgc((struct garbagelist *)___params___); +#endif + ret = pthread_barrier_wait(&barrier); +#ifdef PRECISE_GC + restartaftergc(); +#endif + if(ret != 0 && ret != PTHREAD_BARRIER_SERIAL_THREAD) { + printf("%s() Could not wait on barrier: error %d in %s\n", __func__, errno, __FILE__); + exit(-1); + } +} +#endif - /* Set up signal handlers */ - struct sigaction sig; - sig.sa_sigaction=&myhandler; - sig.sa_flags=SA_SIGINFO; - sigemptyset(&sig.sa_mask); +/* Object allocation function */ - /* Catch bus errors, segmentation faults, and floating point exceptions*/ - sigaction(SIGBUS,&sig,0); - sigaction(SIGSEGV,&sig,0); - sigaction(SIGFPE,&sig,0); - - /* Map first block of memory to protected, anonymous page */ - mmap(0, 0x1000, 0, MAP_SHARED|MAP_FIXED|MAP_ANON, -1, 0); - - newtask: - while(!isEmpty(activetasks)) { - struct QueueItem * qi=(struct QueueItem *) getTail(activetasks); - struct taskparamdescriptor *tpd=(struct taskparamdescriptor *) qi->objectptr; - int i; - removeItem(activetasks, qi); - - for(i=0;itask->numParameters;i++) { - void * parameter=tpd->parameterArray[i]; - struct parameterdescriptor * pd=tpd->task->descriptorarray[i]; - struct parameterwrapper *pw=(struct parameterwrapper *) pd->queue; - if (!RuntimeHashcontainskey(pw->objectset, (int) parameter)) - goto newtask; - taskpointerarray[i]=parameter; - } - { - struct RuntimeHash * forward=allocateRuntimeHash(100); - struct RuntimeHash * reverse=allocateRuntimeHash(100); - void ** checkpoint=makecheckpoint(tpd->task->numParameters, taskpointerarray, forward, reverse); - if (setjmp(error_handler)) { - /* Recover */ - int h; -#ifdef DEBUG - printf("Recovering\n"); -#endif - genputtable(failedtasks,tpd,tpd); - restorecheckpoint(tpd->task->numParameters, taskpointerarray, checkpoint, forward, reverse); - } else { - /* Actually call task */ - ((void (*) (void **)) tpd->task->taskptr)(taskpointerarray); - } - } +#ifdef DSTM +__attribute__((malloc)) void * allocate_newglobal(int type) { + struct ___Object___ * v=(struct ___Object___ *) transCreateObj(classsize[type]); + v->type=type; +#ifdef THREADS + v->tid=0; + v->lockentry=0; + v->lockcount=0; +#endif + return v; +} + +/* Array allocation function */ + +__attribute__((malloc)) struct ArrayObject * allocate_newarrayglobal(int type, int length) { + struct ArrayObject * v=(struct ArrayObject *)transCreateObj(sizeof(struct ArrayObject)+length*classsize[type]); + if (length<0) { + printf("ERROR: negative array\n"); + return NULL; } + v->type=type; + v->___length___=length; +#ifdef THREADS + v->tid=0; + v->lockentry=0; + v->lockcount=0; +#endif + return v; } +#endif -void processtasks() { - int i; - for(i=0;inumParameters;j++) { - struct parameterdescriptor *param=task->descriptorarray[j]; - struct parameterwrapper * parameter=RUNMALLOC(sizeof(struct parameterwrapper)); - struct parameterwrapper ** ptr=&objectqueues[param->type]; - - param->queue=parameter; - parameter->objectset=allocateRuntimeHash(10); - parameter->numberofterms=param->numberterms; - parameter->intarray=param->intarray; - parameter->task=task; - /* Link new queue in */ - while((*ptr)!=NULL) - ptr=&((*ptr)->next); - (*ptr)=parameter; - } + +#ifdef STM +// STM Versions of allocation functions + +/* Object allocation function */ +__attribute__((malloc)) void * allocate_newtrans(void * ptr, int type) { + struct ___Object___ * v=(struct ___Object___ *) transCreateObj(ptr, classsize[type]); + v->type=type; + v->___objlocation___=v; + return v; +} + +/* Array allocation function */ +__attribute__((malloc)) struct ArrayObject * allocate_newarraytrans(void * ptr, int type, int length) { + struct ArrayObject * v=(struct ArrayObject *)transCreateObj(ptr, sizeof(struct ArrayObject)+length*classsize[type]); + if (length<0) { + printf("ERROR: negative array\n"); + return NULL; + } + v->___objlocation___=(struct ___Object___*)v; + v->type=type; + v->___length___=length; + return v; +} +__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]; + initdsmlocks(&tmp->lock); + tmp->version = 1; + v->___objlocation___=v; + v->type = type; + return v; +} + +/* Array allocation function */ + +__attribute__((malloc)) struct ArrayObject * allocate_newarray(void * ptr, int type, int length) { + objheader_t *tmp=mygcmalloc((struct garbagelist *) ptr, sizeof(struct ArrayObject)+length*classsize[type]+sizeof(objheader_t)); + struct ArrayObject * v=(struct ArrayObject *) &tmp[1]; + initdsmlocks(&tmp->lock); + tmp->version=1; + v->type=type; + if (length<0) { + printf("ERROR: negative array %d\n", length); + return NULL; } + v->___objlocation___=(struct ___Object___ *)v; + v->___length___=length; + return v; } #endif -int ___Object______hashcode____(struct ___Object___ * ___this___) { - return (int) ___this___; +#ifndef STM +#if defined(PRECISE_GC) +__attribute__((malloc)) void * allocate_new(void * ptr, int type) { + struct ___Object___ * v=(struct ___Object___ *) mygcmalloc((struct garbagelist *) ptr, classsize[type]); + v->type=type; +#ifdef THREADS + v->tid=0; + v->lockentry=0; + v->lockcount=0; +#endif +#ifdef OPTIONAL + v->fses=0; +#endif + return v; } -void ___System______printString____L___String___(struct ___String___ * s) { - struct ArrayObject * chararray=s->___string___; - int i; - for(i=0;i___length___;i++) { - short s= ((short *)(((char *)& chararray->___length___)+sizeof(int)))[i]; - putchar(s); - } +/* Array allocation function */ + +__attribute__((malloc)) struct ArrayObject * allocate_newarray(void * ptr, int type, int length) { + struct ArrayObject * v=mygcmalloc((struct garbagelist *) ptr, sizeof(struct ArrayObject)+length*classsize[type]); + v->type=type; + if (length<0) { + printf("ERROR: negative array\n"); + return NULL; + } + v->___length___=length; +#ifdef THREADS + v->tid=0; + v->lockentry=0; + v->lockcount=0; +#endif +#ifdef OPTIONAL + v->fses=0; +#endif + return v; } -void * allocate_new(int type) { - void * v=FREEMALLOC(classsize[type]); - *((int *)v)=type; +#else +__attribute__((malloc)) void * allocate_new(int type) { + struct ___Object___ * v=FREEMALLOC(classsize[type]); + v->type=type; +#ifdef OPTIONAL + v->fses=0; +#endif return v; } -struct ArrayObject * allocate_newarray(int type, int length) { - struct ArrayObject * v=FREEMALLOC(sizeof(struct ArrayObject)+length*classsize[type]); +/* Array allocation function */ + +__attribute__((malloc)) struct ArrayObject * allocate_newarray(int type, int length) { + __attribute__((malloc)) struct ArrayObject * v=FREEMALLOC(sizeof(struct ArrayObject)+length*classsize[type]); v->type=type; v->___length___=length; +#ifdef OPTIONAL + v->fses=0; +#endif return v; } +#endif +#endif -struct ___String___ * NewString(char *str,int length) { +/* Converts C character arrays into Java strings */ +#ifdef PRECISE_GC +__attribute__((malloc)) struct ___String___ * NewString(void * ptr, const char *str,int length) { +#else +__attribute__((malloc)) struct ___String___ * NewString(const char *str,int length) { +#endif + int i; +#ifdef PRECISE_GC + struct ArrayObject * chararray=allocate_newarray((struct garbagelist *)ptr, CHARARRAYTYPE, length); + INTPTR ptrarray[]={1, (INTPTR) ptr, (INTPTR) chararray}; + struct ___String___ * strobj=allocate_new((struct garbagelist *) &ptrarray, STRINGTYPE); + chararray=(struct ArrayObject *) ptrarray[2]; +#else struct ArrayObject * chararray=allocate_newarray(CHARARRAYTYPE, length); struct ___String___ * strobj=allocate_new(STRINGTYPE); - int i; - strobj->___string___=chararray; - for(i=0;i___length___)+sizeof(int)))[i]=(short)str[i]; } +#endif + strobj->___value___=chararray; + strobj->___count___=length; + strobj->___offset___=0; + + for(i=0; i___length___)+sizeof(int)))[i]=(short)str[i]; + } return strobj; } +/* Generated code calls this if we fail a bounds check */ + void failedboundschk() { #ifndef TASK printf("Array out of bounds\n"); +#ifdef THREADS + threadexit(); +#else exit(-1); +#endif #else longjmp(error_handler,2); #endif } -void failednullptr() { -#ifndef TASK - printf("Dereferenced a null pointer\n"); - exit(-1); +/* Abort task call */ +void abort_task() { +#ifdef TASK + longjmp(error_handler,4); #else - longjmp(error_handler,3); + printf("Aborting\n"); + exit(-1); #endif }