add generichashtable
[IRC.git] / Robust / src / Runtime / runtime.c
1 #include "runtime.h"
2 #include "structdefs.h"
3 #include <string.h>
4 #include <signal.h>
5 #include "mem.h"
6 #include<fcntl.h>
7 #include<sys/types.h>
8 #include<sys/mman.h>
9 #include<errno.h>
10 #include<signal.h>
11 #include<stdio.h>
12
13 extern int classsize[];
14 jmp_buf error_handler;
15
16 #ifdef TASK
17 #include "checkpoint.h"
18 #include "Queue.h"
19 #include "SimpleHash.h"
20 #include "task.h"
21 #include "GenericHashtable.h"
22
23 struct SimpleHash * activetasks;
24 struct parameterwrapper * objectqueues[NUMCLASSES];
25
26 int main(int argc, char **argv) {
27   int i;
28   /* Allocate startup object */
29   struct ___StartupObject___ *startupobject=(struct ___StartupObject___*) allocate_new(STARTUPTYPE);
30   struct ArrayObject * stringarray=allocate_newarray(STRINGARRAYTYPE, argc); 
31
32   activetasks=allocateSimpleHash(50);
33
34   /* Set flags */
35   processtasks();
36   flagorand(startupobject,1,0xFFFFFFFF);
37
38   /* Build array of strings */
39
40   startupobject->___parameters___=stringarray;
41
42   for(i=0;i<argc;i++) {
43     int length=strlen(argv[i]);
44     struct ___String___ *newstring=NewString(argv[i],length);
45     ((void **)(((char *)& stringarray->___length___)+sizeof(int)))[i]=newstring;
46   }
47   executetasks();
48 }
49
50 int hashCodeftd(struct failedtaskdescriptor *ftd) {
51   int hash=ftd->task;
52   int i;
53   for(i=0;i<ftd->numParameters;i++) {
54     hash^=(int)parameterArray[i];
55   }
56   return hash;
57 }
58
59 int compareftd(struct failedtaskdescriptor *ftd1, failedtaskdescriptor *ftd2) {
60   int i;
61   if (ftd1->task!=ftd2->task)
62     return 0;
63   for(i=0;i<ftd1->numParameters;i++)
64     if (ftd1->parameterArray[i]!=ftd2->parameterArray[i])
65       return 0;
66   return 1;
67 }
68
69 void flagorand(void * ptr, int ormask, int andmask) {
70   int flag=((int *)ptr)[1];
71   struct QueueItem *flagptr=(struct QueueItem *)(((int*)ptr)[2]);
72   flag|=ormask;
73   flag&=andmask;
74   ((int*)ptr)[1]=flag;
75   /*Remove from all queues */
76   while(flagptr!=NULL) {
77     struct QueueItem * next=flagptr->nextqueue;
78     removeItem(flagptr->queue, flagptr);
79     flagptr=next;
80   }
81   
82   {
83     struct QueueItem *tmpptr;
84     struct parameterwrapper * parameter=objectqueues[((int *)ptr)[0]];
85     int i;
86     flagptr=NULL;
87     while(parameter!=NULL) {
88       for(i=0;i<parameter->numberofterms;i++) {
89         int andmask=parameter->intarray[i*2];
90         int checkmask=parameter->intarray[i*2+1];
91         if ((flag&andmask)==checkmask) {
92           struct QueueItem * qitem=addNewItem(parameter->queue, ptr);
93           if (flagptr==NULL) {
94             flagptr=qitem;
95             tmpptr=flagptr;
96           } else {
97             tmpptr->nextqueue=qitem;
98             tmpptr=qitem;
99           }
100           SimpleHashadd(activetasks, (int)parameter->task, (int)parameter->task);
101           break;
102         }
103       }
104       parameter=parameter->next;
105     }
106     ((struct QueueItem **)ptr)[2]=flagptr;
107   }
108 }
109
110 /* Handler for signals */
111 void myhandler(int sig, struct __siginfo *info, void *uap) {
112   printf("sig=%d\n",sig);
113   printf("signal\n");
114   longjmp(error_handler,1);
115 }
116
117 void executetasks() {
118   void * pointerarray[MAXTASKPARAMS];
119   struct genhashtable * failedtasks=genallocatehashtable(&hashCodeftd, &compareftd);
120
121   /* Set up signal handlers */
122   struct sigaction sig;
123   sig.sa_sigaction=&myhandler;
124   sig.sa_flags=SA_SIGINFO;
125   sig.sa_mask=0;
126
127   /* Catch bus errors, segmentation faults, and floating point exceptions*/
128   sigaction(SIGBUS,&sig,0);
129   sigaction(SIGSEGV,&sig,0);
130   sigaction(SIGFPE,&sig,0);
131
132   /* Map first block of memory to protected, anonymous page */
133   mmap(0, 0x1000, 0, MAP_SHARED|MAP_FIXED|MAP_ANON, -1, 0);
134
135   newtask:
136   while(SimpleHashcountset(activetasks)!=0) {
137     struct taskdescriptor * task=(struct taskdescriptor *) SimpleHashfirstkey(activetasks);
138     int i;
139     for(i=0;i<task->numParameters;i++) {
140       struct parameterwrapper * parameter=(struct parameterwrapper *) task->descriptorarray[i]->queue;
141       struct Queue * queue=parameter->queue;
142       if (isEmpty(queue)) {
143         SimpleHashremove(activetasks, (int)task, (int)task);
144         goto newtask;
145       }
146       pointerarray[i]=getTail(queue)->objectptr;
147     }
148     {
149       struct SimpleHash * forward=allocateSimpleHash(100);
150       struct SimpleHash * reverse=allocateSimpleHash(100);
151       void ** checkpoint=makecheckpoint(task->numParameters, pointerarray, forward, reverse);
152       if (setjmp(error_handler)) {
153         /* Recover */
154         struct failedtaskdescriptor *ftd=RUNMALLOC(sizeof(struct failedtaskdescriptor));
155         int h;
156         ftd->task=task;
157         ftd->numParameters=task->numParameters;
158         ftd->parameterArray=RUNMALLOC(task->numParameters*sizeof(void *));
159         for(j=0;j<task->numParameters;j++) {
160           ftd->parameterArray[j]=pointerarray[j];
161         }
162         genputtable(failedtasks,ftd,ftd);
163         restorecheckpoint(task->numParameters, pointerarray, checkpoint, forward, reverse);
164         /* TODO: REMOVE TASK FROM QUEUE */
165       } else {
166         /* Actually call task */
167         ((void (*) (void **)) task->taskptr)(pointerarray);
168       }
169     }
170   }
171 }
172
173 void processtasks() {
174   int i;
175   for(i=0;i<numtasks;i++) {
176     struct taskdescriptor * task=taskarray[i];
177     int j;
178
179     for(j=0;j<task->numParameters;j++) {
180       struct parameterdescriptor *param=task->descriptorarray[j];
181       struct parameterwrapper * parameter=RUNMALLOC(sizeof(struct parameterwrapper));
182       struct parameterwrapper ** ptr=&objectqueues[param->type];
183
184       param->queue=parameter;
185       parameter->queue=createQueue();
186       parameter->numberofterms=param->numberterms;
187       parameter->intarray=param->intarray;
188       parameter->task=task;
189       /* Link new queue in */
190       while((*ptr)!=NULL)
191         ptr=&((*ptr)->next);
192       (*ptr)=parameter;
193     }
194   }
195 }
196 #endif
197
198 int ___Object______hashcode____(struct ___Object___ * ___this___) {
199   return (int) ___this___;
200 }
201
202 void ___System______printString____L___String___(struct ___String___ * s) {
203     struct ArrayObject * chararray=s->___string___;
204     int i;
205     for(i=0;i<chararray->___length___;i++) {
206         short s= ((short *)(((char *)& chararray->___length___)+sizeof(int)))[i];
207         putchar(s);
208     }
209 }
210
211 void * allocate_new(int type) {
212   void * v=FREEMALLOC(classsize[type]);
213   *((int *)v)=type;
214   return v;
215 }
216
217 struct ArrayObject * allocate_newarray(int type, int length) {
218   struct ArrayObject * v=FREEMALLOC(sizeof(struct ArrayObject)+length*classsize[type]);
219   v->type=type;
220   v->___length___=length;
221   return v;
222 }
223
224 struct ___String___ * NewString(char *str,int length) {
225   struct ArrayObject * chararray=allocate_newarray(CHARARRAYTYPE, length);
226   struct ___String___ * strobj=allocate_new(STRINGTYPE);
227   int i;
228   strobj->___string___=chararray;
229   for(i=0;i<length;i++) {
230     ((short *)(((char *)& chararray->___length___)+sizeof(int)))[i]=(short)str[i];  }
231   return strobj;
232 }
233
234 void failedboundschk() {
235 #ifndef TASK
236   printf("Array out of bounds\n");
237   exit(-1);
238 #else
239   longjmp(error_handler,2);
240 #endif
241 }
242
243 void failednullptr() {
244 #ifndef TASK
245   printf("Dereferenced a null pointer\n");
246   exit(-1);
247 #else
248   longjmp(error_handler,3);
249 #endif
250 }