STM testcase works...plenty of bugs still
[IRC.git] / Robust / src / Runtime / runtime.c
1 #include "runtime.h"
2 #include "structdefs.h"
3 #include <signal.h>
4 #include "mem.h"
5 #include <fcntl.h>
6 #include <errno.h>
7 #include <stdio.h>
8 #include "option.h"
9 #ifdef DSTM
10 #include "dstm.h"
11 #include "prelookup.h"
12 #include "prefetch.h"
13 #endif
14 #ifdef STM
15 #include "tm.h"
16 #endif
17
18 extern int classsize[];
19 extern int typearray[];
20 extern int typearray2[];
21 jmp_buf error_handler;
22 int instructioncount;
23
24 char *options;
25 int injectfailures=0;
26 float failurechance=0;
27 int errors=0;
28 int debugtask=0;
29 int injectinstructionfailures;
30 int failurecount;
31 float instfailurechance=0;
32 int numfailures;
33 int instaccum=0;
34 #ifdef DMALLOC
35 #include "dmalloc.h"
36 #endif
37
38 int instanceof(struct ___Object___ *ptr, int type) {
39   int i=ptr->type;
40   do {
41     if (i==type)
42       return 1;
43     i=typearray[i];
44   } while(i!=-1);
45   i=ptr->type;
46   if (i>NUMCLASSES) {
47     do {
48       if (i==type)
49         return 1;
50       i=typearray2[i-NUMCLASSES];
51     } while(i!=-1);
52   }
53   return 0;
54 }
55
56 void exithandler(int sig, siginfo_t *info, void * uap) {
57   exit(0);
58 }
59
60 void initializeexithandler() {
61   struct sigaction sig;
62   sig.sa_sigaction=&exithandler;
63   sig.sa_flags=SA_SIGINFO;
64   sigemptyset(&sig.sa_mask);
65   sigaction(SIGUSR2, &sig, 0);
66 }
67
68
69 /* This function inject failures */
70
71 void injectinstructionfailure() {
72 #ifdef TASK
73   if (injectinstructionfailures) {
74     if (numfailures==0)
75       return;
76     instructioncount=failurecount;
77     instaccum+=failurecount;
78     if ((((double)random())/RAND_MAX)<instfailurechance) {
79       if (numfailures>0)
80         numfailures--;
81       printf("FAILURE!!! %d\n",numfailures);
82       longjmp(error_handler,11);
83     }
84   }
85 #else
86 #ifdef THREADS
87   if (injectinstructionfailures) {
88     if (numfailures==0)
89       return;
90     instaccum+=failurecount;
91     if ((((double)random())/RAND_MAX)<instfailurechance) {
92       if (numfailures>0)
93         numfailures--;
94       printf("FAILURE!!! %d\n",numfailures);
95       threadexit();
96     }
97   }
98 #endif
99 #endif
100 }
101
102 void CALL11(___System______exit____I,int ___status___, int ___status___) {
103   exit(___status___);
104 }
105
106 void CALL11(___System______printI____I,int ___status___, int ___status___) {
107   printf("%d\n",___status___);
108 }
109
110 long CALL00(___System______currentTimeMillis____) {
111   struct timeval tv; long long retval;
112   gettimeofday(&tv, NULL);
113   retval = tv.tv_sec; /* seconds */
114   retval*=1000; /* milliseconds */
115   retval+= (tv.tv_usec/1000); /* adjust milliseconds & add them in */
116   return retval;
117 }
118
119 void CALL01(___System______printString____L___String___,struct ___String___ * ___s___) {
120   struct ArrayObject * chararray=VAR(___s___)->___value___;
121   int i;
122   int offset=VAR(___s___)->___offset___;
123   for(i=0; i<VAR(___s___)->___count___; i++) {
124     short sc=((short *)(((char *)&chararray->___length___)+sizeof(int)))[i+offset];
125     putchar(sc);
126   }
127 }
128
129 #ifdef DSTM
130 void CALL00(___System______clearPrefetchCache____) {
131   prehashClear();
132 }
133
134 #ifdef RANGEPREFETCH
135 void CALL02(___System______rangePrefetch____L___Object_____AR_S, struct ___Object___ * ___o___, struct ArrayObject * ___offsets___) {
136   /* Manual Prefetches to be inserted */
137   //printf("DEBUG-> %s() ___Object___ * ___o___ = %x\n", __func__, VAR(___o___));
138   //printf("DEBUG-> %s() ArrayObject * = %x\n", __func__, VAR(___offsets___));
139   int numoffset=VAR(___offsets___)->___length___;
140   int i;
141   short offArry[numoffset+2];
142   offArry[0] = 0;
143   offArry[1] = 0;
144   for(i = 2; i<(numoffset+2); i++) {
145     offArry[i] = *((short *)(((char *)&VAR(___offsets___)->___length___) + sizeof(int) + (i-2) * sizeof(short)));
146     //printf("DEBUG-> offArry[%d] = %d\n", i, offArry[i]);
147   }
148   unsigned int oid;
149   if(((unsigned int)(VAR(___o___)) & 1) != 0) { //odd
150     oid =  (unsigned int) VAR(___o___); //outside transaction therefore just an oid
151   } else { //even
152     oid = (unsigned int) COMPOID(VAR(___o___)); //inside transaction therefore a pointer to oid
153   }
154   rangePrefetch(oid, (short)(numoffset+2), offArry);
155 }
156 #else
157 void CALL02(___System______rangePrefetch____L___Object_____AR_S, struct ___Object___ * ___o___, struct ArrayObject * ___offsets___) {
158   return;
159 }
160 #endif
161
162 #endif
163
164 /* Object allocation function */
165
166 #ifdef DSTM
167 __attribute__((malloc)) void * allocate_newglobal(int type) {
168   struct ___Object___ * v=(struct ___Object___ *) transCreateObj(classsize[type]);
169   v->type=type;
170 #ifdef THREADS
171   v->tid=0;
172   v->lockentry=0;
173   v->lockcount=0;
174 #endif
175   return v;
176 }
177
178 /* Array allocation function */
179
180 __attribute__((malloc)) struct ArrayObject * allocate_newarrayglobal(int type, int length) {
181   struct ArrayObject * v=(struct ArrayObject *)transCreateObj(sizeof(struct ArrayObject)+length*classsize[type]);
182   if (length<0) {
183     printf("ERROR: negative array\n");
184     return NULL;
185   }
186   v->type=type;
187   v->___length___=length;
188 #ifdef THREADS
189   v->tid=0;
190   v->lockentry=0;
191   v->lockcount=0;
192 #endif
193   return v;
194 }
195 #endif
196
197
198 #ifdef STM
199 // STM Versions of allocation functions
200
201 /* Object allocation function */
202 __attribute__((malloc)) void * allocate_newtrans(void * ptr, int type) {
203   struct ___Object___ * v=(struct ___Object___ *) transCreateObj(ptr, classsize[type]);
204   v->type=type;
205   v->___objlocation___=v;
206   return v;
207 }
208
209 /* Array allocation function */
210 __attribute__((malloc)) struct ArrayObject * allocate_newarraytrans(void * ptr, int type, int length) {
211   struct ArrayObject * v=(struct ArrayObject *)transCreateObj(ptr, sizeof(struct ArrayObject)+length*classsize[type]);
212   if (length<0) {
213     printf("ERROR: negative array\n");
214     return NULL;
215   }
216   v->___objlocation___=(struct ___Object___*)v;
217   v->type=type;
218   v->___length___=length;
219   return v;
220 }
221 __attribute__((malloc)) void * allocate_new(void * ptr, int type) {
222   objheader_t *tmp=mygcmalloc((struct garbagelist *) ptr, classsize[type]+sizeof(objheader_t));
223   struct ___Object___ * v=(struct ___Object___ *) &tmp[1];
224   initdsmlocks(&tmp->lock);
225   tmp->version = 1;
226   v->___objlocation___=v;
227   v->type = type;
228   return v;
229 }
230
231 /* Array allocation function */
232
233 __attribute__((malloc)) struct ArrayObject * allocate_newarray(void * ptr, int type, int length) {
234   objheader_t *tmp=mygcmalloc((struct garbagelist *) ptr, sizeof(struct ArrayObject)+length*classsize[type]+sizeof(objheader_t));
235   struct ArrayObject * v=(struct ArrayObject *) &tmp[1];
236   initdsmlocks(&tmp->lock);
237   tmp->version=1;
238   v->type=type;
239   if (length<0) {
240     printf("ERROR: negative array\n");
241     return NULL;
242   }
243   v->___objlocation___=(struct ___Object___ *)v;
244   v->___length___=length;
245   return v;
246 }
247 #endif
248
249 #ifndef STM
250 #if defined(PRECISE_GC)
251 __attribute__((malloc)) void * allocate_new(void * ptr, int type) {
252   struct ___Object___ * v=(struct ___Object___ *) mygcmalloc((struct garbagelist *) ptr, classsize[type]);
253   v->type=type;
254 #ifdef THREADS
255   v->tid=0;
256   v->lockentry=0;
257   v->lockcount=0;
258 #endif
259 #ifdef OPTIONAL
260   v->fses=0;
261 #endif
262   return v;
263 }
264
265 /* Array allocation function */
266
267 __attribute__((malloc)) struct ArrayObject * allocate_newarray(void * ptr, int type, int length) {
268   struct ArrayObject * v=mygcmalloc((struct garbagelist *) ptr, sizeof(struct ArrayObject)+length*classsize[type]);
269   v->type=type;
270   if (length<0) {
271     printf("ERROR: negative array\n");
272     return NULL;
273   }
274   v->___length___=length;
275 #ifdef THREADS
276   v->tid=0;
277   v->lockentry=0;
278   v->lockcount=0;
279 #endif
280 #ifdef OPTIONAL
281   v->fses=0;
282 #endif
283   return v;
284 }
285
286 #else
287 __attribute__((malloc)) void * allocate_new(int type) {
288   struct ___Object___ * v=FREEMALLOC(classsize[type]);
289   v->type=type;
290 #ifdef OPTIONAL
291   v->fses=0;
292 #endif
293   return v;
294 }
295
296 /* Array allocation function */
297
298 __attribute__((malloc)) struct ArrayObject * allocate_newarray(int type, int length) {
299   __attribute__((malloc))  struct ArrayObject * v=FREEMALLOC(sizeof(struct ArrayObject)+length*classsize[type]);
300   v->type=type;
301   v->___length___=length;
302 #ifdef OPTIONAL
303   v->fses=0;
304 #endif
305   return v;
306 }
307 #endif
308 #endif
309
310
311 /* Converts C character arrays into Java strings */
312 #ifdef PRECISE_GC
313 __attribute__((malloc)) struct ___String___ * NewString(void * ptr, const char *str,int length) {
314 #else
315 __attribute__((malloc)) struct ___String___ * NewString(const char *str,int length) {
316 #endif
317   int i;
318 #ifdef PRECISE_GC
319   struct ArrayObject * chararray=allocate_newarray((struct garbagelist *)ptr, CHARARRAYTYPE, length);
320   int ptrarray[]={1, (int) ptr, (int) chararray};
321   struct ___String___ * strobj=allocate_new((struct garbagelist *) &ptrarray, STRINGTYPE);
322   chararray=(struct ArrayObject *) ptrarray[2];
323 #else
324   struct ArrayObject * chararray=allocate_newarray(CHARARRAYTYPE, length);
325   struct ___String___ * strobj=allocate_new(STRINGTYPE);
326 #endif
327   strobj->___value___=chararray;
328   strobj->___count___=length;
329   strobj->___offset___=0;
330
331   for(i=0; i<length; i++) {
332     ((short *)(((char *)&chararray->___length___)+sizeof(int)))[i]=(short)str[i];
333   }
334   return strobj;
335 }
336
337 /* Generated code calls this if we fail a bounds check */
338
339 void failedboundschk() {
340 #ifndef TASK
341   printf("Array out of bounds\n");
342 #ifdef THREADS
343   threadexit();
344 #else
345   exit(-1);
346 #endif
347 #else
348   longjmp(error_handler,2);
349 #endif
350 }
351
352 /* Abort task call */
353 void abort_task() {
354 #ifdef TASK
355   longjmp(error_handler,4);
356 #else
357   printf("Aborting\n");
358   exit(-1);
359 #endif
360 }