changes to use floats
[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 #include "methodheaders.h"
10 #ifdef DSTM
11 #include "dstm.h"
12 #include "prelookup.h"
13 #include "prefetch.h"
14 #endif
15 #ifdef STM
16 #include "tm.h"
17 #include <pthread.h>
18 #endif
19
20 #if defined(THREADS)||defined(STM)
21 /* Global barrier for STM */
22 pthread_barrier_t barrier;
23 pthread_barrierattr_t attr;
24 #endif
25
26 #include <string.h>
27
28 extern int classsize[];
29 extern int typearray[];
30 extern int typearray2[];
31 jmp_buf error_handler;
32 int instructioncount;
33
34 char *options;
35 int injectfailures=0;
36 float failurechance=0;
37 int errors=0;
38 int debugtask=0;
39 int injectinstructionfailures;
40 int failurecount;
41 float instfailurechance=0;
42 int numfailures;
43 int instaccum=0;
44 #ifdef DMALLOC
45 #include "dmalloc.h"
46 #endif
47
48 int instanceof(struct ___Object___ *ptr, int type) {
49   int i=ptr->type;
50   do {
51     if (i==type)
52       return 1;
53     i=typearray[i];
54   } while(i!=-1);
55   i=ptr->type;
56   if (i>NUMCLASSES) {
57     do {
58       if (i==type)
59         return 1;
60       i=typearray2[i-NUMCLASSES];
61     } while(i!=-1);
62   }
63   return 0;
64 }
65
66 void exithandler(int sig, siginfo_t *info, void * uap) {
67   exit(0);
68 }
69
70 void initializeexithandler() {
71   struct sigaction sig;
72   sig.sa_sigaction=&exithandler;
73   sig.sa_flags=SA_SIGINFO;
74   sigemptyset(&sig.sa_mask);
75   sigaction(SIGUSR2, &sig, 0);
76 }
77
78
79 /* This function inject failures */
80
81 void injectinstructionfailure() {
82 #ifdef TASK
83   if (injectinstructionfailures) {
84     if (numfailures==0)
85       return;
86     instructioncount=failurecount;
87     instaccum+=failurecount;
88     if ((((double)random())/RAND_MAX)<instfailurechance) {
89       if (numfailures>0)
90         numfailures--;
91       printf("FAILURE!!! %d\n",numfailures);
92       longjmp(error_handler,11);
93     }
94   }
95 #else
96 #ifdef THREADS
97   if (injectinstructionfailures) {
98     if (numfailures==0)
99       return;
100     instaccum+=failurecount;
101     if ((((double)random())/RAND_MAX)<instfailurechance) {
102       if (numfailures>0)
103         numfailures--;
104       printf("FAILURE!!! %d\n",numfailures);
105       threadexit();
106     }
107   }
108 #endif
109 #endif
110 }
111
112 #ifdef D___Double______nativeparsedouble____L___String___
113 double CALL01(___Double______nativeparsedouble____L___String___,struct ___String___ * ___str___) {
114   int length=VAR(___str___)->___count___;
115   int maxlength=(length>60)?60:length;
116   char str[maxlength+1];
117   struct ArrayObject * chararray=VAR(___str___)->___value___;
118   int i;
119   int offset=VAR(___str___)->___offset___;
120   for(i=0; i<maxlength; i++) {
121     str[i]=((short *)(((char *)&chararray->___length___)+sizeof(int)))[i+offset];
122   }
123   str[i]=0;
124   double d=atof(str);
125   return d;
126 }
127 #endif
128
129 #ifdef D___String______convertdoubletochar____D__AR_C
130 int CALL12(___String______convertdoubletochar____D__AR_C, double ___val___, double ___val___, struct ArrayObject ___chararray___) {
131   int length=VAR(___chararray___)->___length___;
132   char str[length];
133   int i;
134   int num=snprintf(str, length, "%f",___val___);
135   if (num>=length)
136     num=length-1;
137   for(i=0; i<length; i++) {
138     ((short *)(((char *)&VAR(___chararray___)->___length___)+sizeof(int)))[i]=(short)str[i];
139   }
140   return num;
141 }
142 #endif
143
144 void CALL11(___System______exit____I,int ___status___, int ___status___) {
145 #ifdef TRANSSTATS
146   printf("numTransCommit = %d\n", numTransCommit);
147   printf("numTransAbort = %d\n", numTransAbort);
148   printf("nSoftAbort = %d\n", nSoftAbort);
149 #ifdef STM
150   printf("nSoftAbortCommit = %d\n", nSoftAbortCommit);
151   printf("nSoftAbortAbort = %d\n", nSoftAbortAbort);
152 #ifdef STMSTATS
153   int i;
154   for(i=0; i<TOTALNUMCLASSANDARRAY; i++) {
155     printf("typesCausingAbort[%d]= %d\n", i, typesCausingAbort[i]);
156   }
157 #endif
158 #endif
159 #endif
160   exit(___status___);
161 }
162
163 #ifdef D___Vector______removeElement_____AR_L___Object____I_I
164 void CALL23(___Vector______removeElement_____AR_L___Object____I_I, int ___index___, int ___size___, struct ArrayObject * ___array___, int ___index___, int ___size___) {
165   char* offset=((char *)(&VAR(___array___)->___length___))+sizeof(unsigned int)+sizeof(void *)*___index___;
166   memmove(offset, offset+sizeof(void *),(___size___-___index___-1)*sizeof(void *));
167 }
168 #endif
169
170 void CALL11(___System______printI____I,int ___status___, int ___status___) {
171   printf("%d\n",___status___);
172 }
173
174 long long CALL00(___System______currentTimeMillis____) {
175   struct timeval tv; long long retval;
176   gettimeofday(&tv, NULL);
177   retval = tv.tv_sec; /* seconds */
178   retval*=1000; /* milliseconds */
179   retval+= (tv.tv_usec/1000); /* adjust milliseconds & add them in */
180   return retval;
181 }
182
183 void CALL01(___System______printString____L___String___,struct ___String___ * ___s___) {
184   struct ArrayObject * chararray=VAR(___s___)->___value___;
185   int i;
186   int offset=VAR(___s___)->___offset___;
187   for(i=0; i<VAR(___s___)->___count___; i++) {
188     short sc=((short *)(((char *)&chararray->___length___)+sizeof(int)))[i+offset];
189     putchar(sc);
190   }
191 }
192
193 #ifdef DSTM
194 void CALL00(___System______clearPrefetchCache____) {
195   prehashClear();
196 }
197
198 #ifdef RANGEPREFETCH
199 void CALL02(___System______rangePrefetch____L___Object_____AR_S, struct ___Object___ * ___o___, struct ArrayObject * ___offsets___) {
200   /* Manual Prefetches to be inserted */
201   //printf("DEBUG-> %s() ___Object___ * ___o___ = %x\n", __func__, VAR(___o___));
202   //printf("DEBUG-> %s() ArrayObject * = %x\n", __func__, VAR(___offsets___));
203   int numoffset=VAR(___offsets___)->___length___;
204   int i;
205   short offArry[numoffset+2];
206   offArry[0] = 0;
207   offArry[1] = 0;
208   for(i = 2; i<(numoffset+2); i++) {
209     offArry[i] = *((short *)(((char *)&VAR(___offsets___)->___length___) + sizeof(int) + (i-2) * sizeof(short)));
210     //printf("DEBUG-> offArry[%d] = %d\n", i, offArry[i]);
211   }
212   unsigned int oid;
213   if(((unsigned int)(VAR(___o___)) & 1) != 0) { //odd
214     oid =  (unsigned int) VAR(___o___); //outside transaction therefore just an oid
215   } else { //even
216     oid = (unsigned int) COMPOID(VAR(___o___)); //inside transaction therefore a pointer to oid
217   }
218   rangePrefetch(oid, (short)(numoffset+2), offArry);
219 }
220 #else
221 void CALL02(___System______rangePrefetch____L___Object_____AR_S, struct ___Object___ * ___o___, struct ArrayObject * ___offsets___) {
222   return;
223 }
224 #endif
225
226 #endif
227
228 /* STM Barrier constructs */
229 #ifdef D___Barrier______setBarrier____I
230 void CALL11(___Barrier______setBarrier____I, int nthreads, int nthreads) {
231   // Barrier initialization
232   int ret;
233   if((ret = pthread_barrier_init(&barrier, NULL, nthreads)) != 0) {
234     printf("%s() Could not create a barrier: numthreads = 0 in %s\n", __func__, __FILE__);
235     exit(-1);
236   }
237 }
238 #endif
239
240 #ifdef D___Barrier______enterBarrier____
241 void CALL00(___Barrier______enterBarrier____) {
242   // Synchronization point
243   int ret;
244 #ifdef PRECISE_GC
245   stopforgc((struct garbagelist *)___params___);
246 #endif
247   ret = pthread_barrier_wait(&barrier);
248 #ifdef PRECISE_GC
249   restartaftergc();
250 #endif
251   if(ret != 0 && ret != PTHREAD_BARRIER_SERIAL_THREAD) {
252     printf("%s() Could not wait on barrier: error %d in %s\n", __func__, errno, __FILE__);
253     exit(-1);
254   }
255 }
256 #endif
257
258 /* Object allocation function */
259
260 #ifdef DSTM
261 __attribute__((malloc)) void * allocate_newglobal(int type) {
262   struct ___Object___ * v=(struct ___Object___ *) transCreateObj(classsize[type]);
263   v->type=type;
264 #ifdef THREADS
265   v->tid=0;
266   v->lockentry=0;
267   v->lockcount=0;
268 #endif
269   return v;
270 }
271
272 /* Array allocation function */
273
274 __attribute__((malloc)) struct ArrayObject * allocate_newarrayglobal(int type, int length) {
275   struct ArrayObject * v=(struct ArrayObject *)transCreateObj(sizeof(struct ArrayObject)+length*classsize[type]);
276   if (length<0) {
277     printf("ERROR: negative array\n");
278     return NULL;
279   }
280   v->type=type;
281   v->___length___=length;
282 #ifdef THREADS
283   v->tid=0;
284   v->lockentry=0;
285   v->lockcount=0;
286 #endif
287   return v;
288 }
289 #endif
290
291
292 #ifdef STM
293 // STM Versions of allocation functions
294
295 /* Object allocation function */
296 __attribute__((malloc)) void * allocate_newtrans(void * ptr, int type) {
297   struct ___Object___ * v=(struct ___Object___ *) transCreateObj(ptr, classsize[type]);
298   v->type=type;
299   v->___objlocation___=v;
300   return v;
301 }
302
303 /* Array allocation function */
304 __attribute__((malloc)) struct ArrayObject * allocate_newarraytrans(void * ptr, int type, int length) {
305   struct ArrayObject * v=(struct ArrayObject *)transCreateObj(ptr, sizeof(struct ArrayObject)+length*classsize[type]);
306   if (length<0) {
307     printf("ERROR: negative array\n");
308     return NULL;
309   }
310   v->___objlocation___=(struct ___Object___*)v;
311   v->type=type;
312   v->___length___=length;
313   return v;
314 }
315 __attribute__((malloc)) void * allocate_new(void * ptr, int type) {
316   objheader_t *tmp=mygcmalloc((struct garbagelist *) ptr, classsize[type]+sizeof(objheader_t));
317   struct ___Object___ * v=(struct ___Object___ *) &tmp[1];
318   initdsmlocks(&tmp->lock);
319   tmp->version = 1;
320   v->___objlocation___=v;
321   v->type = type;
322   return v;
323 }
324
325 /* Array allocation function */
326
327 __attribute__((malloc)) struct ArrayObject * allocate_newarray(void * ptr, int type, int length) {
328   objheader_t *tmp=mygcmalloc((struct garbagelist *) ptr, sizeof(struct ArrayObject)+length*classsize[type]+sizeof(objheader_t));
329   struct ArrayObject * v=(struct ArrayObject *) &tmp[1];
330   initdsmlocks(&tmp->lock);
331   tmp->version=1;
332   v->type=type;
333   if (length<0) {
334     printf("ERROR: negative array %d\n", length);
335     return NULL;
336   }
337   v->___objlocation___=(struct ___Object___ *)v;
338   v->___length___=length;
339   return v;
340 }
341 #endif
342
343 #ifndef STM
344 #if defined(PRECISE_GC)
345 __attribute__((malloc)) void * allocate_new(void * ptr, int type) {
346   struct ___Object___ * v=(struct ___Object___ *) mygcmalloc((struct garbagelist *) ptr, classsize[type]);
347   v->type=type;
348 #ifdef THREADS
349   v->tid=0;
350   v->lockentry=0;
351   v->lockcount=0;
352 #endif
353 #ifdef OPTIONAL
354   v->fses=0;
355 #endif
356   return v;
357 }
358
359 /* Array allocation function */
360
361 __attribute__((malloc)) struct ArrayObject * allocate_newarray(void * ptr, int type, int length) {
362   struct ArrayObject * v=mygcmalloc((struct garbagelist *) ptr, sizeof(struct ArrayObject)+length*classsize[type]);
363   v->type=type;
364   if (length<0) {
365     printf("ERROR: negative array\n");
366     return NULL;
367   }
368   v->___length___=length;
369 #ifdef THREADS
370   v->tid=0;
371   v->lockentry=0;
372   v->lockcount=0;
373 #endif
374 #ifdef OPTIONAL
375   v->fses=0;
376 #endif
377   return v;
378 }
379
380 #else
381 __attribute__((malloc)) void * allocate_new(int type) {
382   struct ___Object___ * v=FREEMALLOC(classsize[type]);
383   v->type=type;
384 #ifdef OPTIONAL
385   v->fses=0;
386 #endif
387   return v;
388 }
389
390 /* Array allocation function */
391
392 __attribute__((malloc)) struct ArrayObject * allocate_newarray(int type, int length) {
393   __attribute__((malloc))  struct ArrayObject * v=FREEMALLOC(sizeof(struct ArrayObject)+length*classsize[type]);
394   v->type=type;
395   v->___length___=length;
396 #ifdef OPTIONAL
397   v->fses=0;
398 #endif
399   return v;
400 }
401 #endif
402 #endif
403
404 /* Converts C character arrays into Java strings */
405 #ifdef PRECISE_GC
406 __attribute__((malloc)) struct ___String___ * NewString(void * ptr, const char *str,int length) {
407 #else
408 __attribute__((malloc)) struct ___String___ * NewString(const char *str,int length) {
409 #endif
410   int i;
411 #ifdef PRECISE_GC
412   struct ArrayObject * chararray=allocate_newarray((struct garbagelist *)ptr, CHARARRAYTYPE, length);
413   INTPTR ptrarray[]={1, (INTPTR) ptr, (INTPTR) chararray};
414   struct ___String___ * strobj=allocate_new((struct garbagelist *) &ptrarray, STRINGTYPE);
415   chararray=(struct ArrayObject *) ptrarray[2];
416 #else
417   struct ArrayObject * chararray=allocate_newarray(CHARARRAYTYPE, length);
418   struct ___String___ * strobj=allocate_new(STRINGTYPE);
419 #endif
420   strobj->___value___=chararray;
421   strobj->___count___=length;
422   strobj->___offset___=0;
423
424   for(i=0; i<length; i++) {
425     ((short *)(((char *)&chararray->___length___)+sizeof(int)))[i]=(short)str[i];
426   }
427   return strobj;
428 }
429
430 /* Generated code calls this if we fail a bounds check */
431
432 void failedboundschk() {
433 #ifndef TASK
434   printf("Array out of bounds\n");
435 #ifdef THREADS
436   threadexit();
437 #else
438   exit(-1);
439 #endif
440 #else
441   longjmp(error_handler,2);
442 #endif
443 }
444
445 /* Abort task call */
446 void abort_task() {
447 #ifdef TASK
448   longjmp(error_handler,4);
449 #else
450   printf("Aborting\n");
451   exit(-1);
452 #endif
453 }