2 #include "structdefs.h"
14 extern int classsize[];
15 jmp_buf error_handler;
20 float failurechance=0;
22 int injectinstructionfailures;
24 float instfailurechance=0;
31 #include "checkpoint.h"
33 #include "SimpleHash.h"
34 #include "GenericHashtable.h"
35 #include <sys/select.h>
38 #include "instrument.h"
41 struct Queue * activetasks;
42 struct parameterwrapper * objectqueues[NUMCLASSES];
43 struct genhashtable * failedtasks;
44 struct RuntimeHash * forward;
45 struct RuntimeHash * reverse;
48 int main(int argc, char **argv) {
50 GC_init(); // Initialize the garbage collector
57 /* Create table for failed tasks */
58 failedtasks=genallocatehashtable((unsigned int (*)(void *)) &hashCodetpd,
59 (int (*)(void *,void *)) &comparetpd);
60 /* Create queue of active tasks */
61 activetasks=createQueue();
63 /* Process task information */
66 /* Create startup object */
67 createstartupobject(argc, argv);
69 /* Start executing the tasks */
73 void createstartupobject(int argc, char ** argv) {
76 /* Allocate startup object */
78 struct ___StartupObject___ *startupobject=(struct ___StartupObject___*) allocate_new(NULL, STARTUPTYPE);
79 struct ArrayObject * stringarray=allocate_newarray(NULL, STRINGARRAYTYPE, argc-1);
81 struct ___StartupObject___ *startupobject=(struct ___StartupObject___*) allocate_new(STARTUPTYPE);
82 struct ArrayObject * stringarray=allocate_newarray(STRINGARRAYTYPE, argc-1);
84 /* Build array of strings */
85 startupobject->___parameters___=stringarray;
87 int length=strlen(argv[i]);
89 struct ___String___ *newstring=NewString(NULL, argv[i],length);
91 struct ___String___ *newstring=NewString(argv[i],length);
93 ((void **)(((char *)& stringarray->___length___)+sizeof(int)))[i-1]=newstring;
96 /* Set initialized flag for startup object */
97 flagorand(startupobject,1,0xFFFFFFFF);
100 int hashCodetpd(struct taskparamdescriptor *ftd) {
101 int hash=(int)ftd->task;
103 for(i=0;i<ftd->numParameters;i++) {
104 hash^=(int)ftd->parameterArray[i];
109 int comparetpd(struct taskparamdescriptor *ftd1, struct taskparamdescriptor *ftd2) {
111 if (ftd1->task!=ftd2->task)
113 for(i=0;i<ftd1->numParameters;i++)
114 if (ftd1->parameterArray[i]!=ftd2->parameterArray[i])
119 /* This function updates the flag for object ptr. It or's the flag
120 with the or mask and and's it with the andmask. */
122 void flagorand(void * ptr, int ormask, int andmask) {
123 int flag=((int *)ptr)[1];
124 struct RuntimeHash *flagptr=(struct RuntimeHash *)(((int*)ptr)[2]);
129 /*Remove object from all queues */
130 while(flagptr!=NULL) {
131 struct RuntimeHash *next;
132 RuntimeHashget(flagptr, (int) ptr, (int *) &next);
133 RuntimeHashremove(flagptr, (int)ptr, (int) next);
138 struct QueueItem *tmpptr;
139 struct parameterwrapper * parameter=objectqueues[((int *)ptr)[0]];
141 struct RuntimeHash * prevptr=NULL;
142 while(parameter!=NULL) {
143 for(i=0;i<parameter->numberofterms;i++) {
144 int andmask=parameter->intarray[i*2];
145 int checkmask=parameter->intarray[i*2+1];
146 if ((flag&andmask)==checkmask) {
147 RuntimeHashadd(parameter->objectset, (int) ptr, (int) prevptr);
148 prevptr=parameter->objectset;
150 struct RuntimeIterator iteratorarray[MAXTASKPARAMS];
151 void * taskpointerarray[MAXTASKPARAMS];
153 int numparams=parameter->task->numParameters;
155 struct taskdescriptor * task=parameter->task;
157 for(j=0;j<numparams;j++) {
158 struct parameterwrapper *pw=(struct parameterwrapper *)task->descriptorarray[j]->queue;
160 taskpointerarray[j]=ptr;
163 RuntimeHashiterator(pw->objectset, &iteratorarray[j]);
164 if (RunhasNext(&iteratorarray[j])) {
165 taskpointerarray[j]=(void *) Runkey(&iteratorarray[j]);
166 Runnext(&iteratorarray[j]);
169 break; /* No tasks to dispatch */
173 /* Queue task items... */
176 struct taskparamdescriptor *tpd=RUNMALLOC(sizeof(struct taskparamdescriptor));
178 tpd->numParameters=numparams;
179 tpd->parameterArray=RUNMALLOC(sizeof(void *)*numparams);
180 for(j=0;j<numparams;j++)
181 tpd->parameterArray[j]=taskpointerarray[j];
183 if (!gencontains(failedtasks, tpd))
184 addNewItem(activetasks, tpd);
186 /* This loop iterates to the next parameter combination */
187 for(j=0;j<numparams;j++) {
189 if ((j+1)==numparams)
193 if (RunhasNext(&iteratorarray[j])) {
194 taskpointerarray[j]=(void *) Runkey(&iteratorarray[j]);
195 Runnext(&iteratorarray[j]);
197 } else if ((j+1)!=numparams) {
198 RuntimeHashiterator(task->descriptorarray[j]->queue, &iteratorarray[j]);
209 parameter=parameter->next;
211 ((struct RuntimeHash **)ptr)[2]=prevptr;
215 /* Handler for signals. The signals catch null pointer errors and
216 arithmatic errors. */
218 void myhandler(int sig, siginfo_t *info, void *uap) {
220 printf("sig=%d\n",sig);
223 longjmp(error_handler,1);
228 struct RuntimeHash *fdtoobject;
230 void addreadfd(int fd) {
233 FD_SET(fd, &readfds);
236 void removereadfd(int fd) {
237 FD_CLR(fd, &readfds);
238 if (maxreadfd==(fd+1)) {
240 while(maxreadfd>0&&!FD_ISSET(maxreadfd-1, &readfds))
251 void executetasks() {
252 void * taskpointerarray[MAXTASKPARAMS+OFFSET];
254 /* Set up signal handlers */
255 struct sigaction sig;
256 sig.sa_sigaction=&myhandler;
257 sig.sa_flags=SA_SIGINFO;
258 sigemptyset(&sig.sa_mask);
260 /* Catch bus errors, segmentation faults, and floating point exceptions*/
261 sigaction(SIGBUS,&sig,0);
262 sigaction(SIGSEGV,&sig,0);
263 sigaction(SIGFPE,&sig,0);
268 fdtoobject=allocateRuntimeHash(100);
270 /* Map first block of memory to protected, anonymous page */
271 mmap(0, 0x1000, 0, MAP_SHARED|MAP_FIXED|MAP_ANON, -1, 0);
274 while(!isEmpty(activetasks)||(maxreadfd>0)) {
276 /* Check if any filedescriptors have IO pending */
279 struct timeval timeout={0,0};
283 numselect=select(maxreadfd, &tmpreadfds, NULL, NULL, &timeout);
285 /* Process ready fd's */
287 for(fd=0;fd<maxreadfd;fd++) {
288 if (FD_ISSET(fd, &tmpreadfds)) {
289 /* Set ready flag on object */
291 if (RuntimeHashget(fdtoobject, fd,(int *) &objptr)) {
292 flagorand(objptr,1,0xFFFFFFFF); /* Set the first flag to 1 */
299 /* See if there are any active tasks */
300 if (!isEmpty(activetasks)) {
302 struct QueueItem * qi=(struct QueueItem *) getTail(activetasks);
303 struct taskparamdescriptor *tpd=(struct taskparamdescriptor *) qi->objectptr;
304 removeItem(activetasks, qi);
306 /* Check if this task has failed */
307 if (gencontains(failedtasks, tpd))
310 /* Make sure that the parameters are still in the queues */
311 for(i=0;i<tpd->task->numParameters;i++) {
312 void * parameter=tpd->parameterArray[i];
313 struct parameterdescriptor * pd=tpd->task->descriptorarray[i];
314 struct parameterwrapper *pw=(struct parameterwrapper *) pd->queue;
315 if (!RuntimeHashcontainskey(pw->objectset, (int) parameter))
317 taskpointerarray[i+OFFSET]=parameter;
320 /* Checkpoint the state */
321 forward=allocateRuntimeHash(100);
322 reverse=allocateRuntimeHash(100);
323 void ** checkpoint=makecheckpoint(tpd->task->numParameters, &taskpointerarray[OFFSET], forward, reverse);
325 if (x=setjmp(error_handler)) {
329 printf("Fatal Error=%d, Recovering!\n",x);
331 genputtable(failedtasks,tpd,tpd);
332 restorecheckpoint(tpd->task->numParameters, &taskpointerarray[OFFSET], checkpoint, forward, reverse);
333 freeRuntimeHash(forward);
334 freeRuntimeHash(reverse);
339 if (injectfailures) {
340 if ((((double)random())/RAND_MAX)<failurechance) {
341 printf("\nINJECTING TASK FAILURE to %s\n", tpd->task->name);
342 longjmp(error_handler,10);
345 /* Actually call task */
347 ((int *)taskpointerarray)[0]=tpd->task->numParameters;
348 taskpointerarray[1]=NULL;
352 printf("ENTER %s count=%d\n",tpd->task->name, (instaccum-instructioncount));
353 ((void (*) (void **)) tpd->task->taskptr)(taskpointerarray);
354 printf("EXIT %s count=%d\n",tpd->task->name, (instaccum-instructioncount));
356 ((void (*) (void **)) tpd->task->taskptr)(taskpointerarray);
357 freeRuntimeHash(forward);
358 freeRuntimeHash(reverse);
368 /* This function processes the task information to create queues for
369 each parameter type. */
371 void processtasks() {
373 for(i=0;i<numtasks;i++) {
374 struct taskdescriptor * task=taskarray[i];
377 for(j=0;j<task->numParameters;j++) {
378 struct parameterdescriptor *param=task->descriptorarray[j];
379 struct parameterwrapper * parameter=RUNMALLOC(sizeof(struct parameterwrapper));
380 struct parameterwrapper ** ptr=&objectqueues[param->type];
382 param->queue=parameter;
383 parameter->objectset=allocateRuntimeHash(10);
384 parameter->numberofterms=param->numberterms;
385 parameter->intarray=param->intarray;
386 parameter->task=task;
387 /* Link new queue in */
397 /* This function inject failures */
399 void injectinstructionfailure() {
401 if (injectinstructionfailures) {
404 instructioncount=failurecount;
405 instaccum+=failurecount;
406 if ((((double)random())/RAND_MAX)<instfailurechance) {
409 printf("FAILURE!!!\n");
410 longjmp(error_handler,11);
417 void CALL01(___System______printString____L___String___,struct ___String___ * ___s___) {
418 struct ArrayObject * chararray=VAR(___s___)->___value___;
420 int offset=VAR(___s___)->___offset___;
421 for(i=0;i<VAR(___s___)->___count___;i++) {
422 short sc=((short *)(((char *)& chararray->___length___)+sizeof(int)))[i+offset];
427 /* Object allocation function */
430 void * allocate_new(void * ptr, int type) {
431 struct ___Object___ * v=(struct ___Object___ *) mygcmalloc((struct garbagelist *) ptr, classsize[type]);
440 /* Array allocation function */
442 struct ArrayObject * allocate_newarray(void * ptr, int type, int length) {
443 struct ArrayObject * v=mygcmalloc((struct garbagelist *) ptr, sizeof(struct ArrayObject)+length*classsize[type]);
445 v->___length___=length;
454 void * allocate_new(int type) {
455 void * v=FREEMALLOC(classsize[type]);
460 /* Array allocation function */
462 struct ArrayObject * allocate_newarray(int type, int length) {
463 struct ArrayObject * v=FREEMALLOC(sizeof(struct ArrayObject)+length*classsize[type]);
465 v->___length___=length;
471 /* Converts C character arrays into Java strings */
473 struct ___String___ * NewString(void * ptr, const char *str,int length) {
475 struct ___String___ * NewString(const char *str,int length) {
478 struct ArrayObject * chararray=allocate_newarray((struct garbagelist *)ptr, CHARARRAYTYPE, length);
479 struct ___String___ * strobj=allocate_new((struct garbagelist *) ptr, STRINGTYPE);
481 struct ArrayObject * chararray=allocate_newarray(CHARARRAYTYPE, length);
482 struct ___String___ * strobj=allocate_new(STRINGTYPE);
485 strobj->___value___=chararray;
486 strobj->___count___=length;
487 strobj->___offset___=0;
489 for(i=0;i<length;i++) {
490 ((short *)(((char *)& chararray->___length___)+sizeof(int)))[i]=(short)str[i]; }
494 /* Generated code calls this if we fail a bounds check */
496 void failedboundschk() {
498 printf("Array out of bounds\n");
501 longjmp(error_handler,2);
505 /* Abort task call */
508 longjmp(error_handler,4);
510 printf("Aborting\n");