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