e0884c425052ea2eb5bd3384f2b4413d3b1c46ad
[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 #ifdef TRANSSTATS
104   printf("numTransCommit = %d\n", numTransCommit);
105   printf("numTransAbort = %d\n", numTransAbort);
106   printf("nSoftAbort = %d\n", nSoftAbort);
107 #ifdef STM
108   printf("nSoftAbortCommit = %d\n", nSoftAbortCommit);
109   printf("nSoftAbortAbort = %d\n", nSoftAbortAbort);
110 #endif
111 #endif
112   exit(___status___);
113 }
114
115 void CALL11(___System______printI____I,int ___status___, int ___status___) {
116   printf("%d\n",___status___);
117 }
118
119 long CALL00(___System______currentTimeMillis____) {
120   struct timeval tv; long long retval;
121   gettimeofday(&tv, NULL);
122   retval = tv.tv_sec; /* seconds */
123   retval*=1000; /* milliseconds */
124   retval+= (tv.tv_usec/1000); /* adjust milliseconds & add them in */
125   return retval;
126 }
127
128 void CALL01(___System______printString____L___String___,struct ___String___ * ___s___) {
129   struct ArrayObject * chararray=VAR(___s___)->___value___;
130   int i;
131   int offset=VAR(___s___)->___offset___;
132   for(i=0; i<VAR(___s___)->___count___; i++) {
133     short sc=((short *)(((char *)&chararray->___length___)+sizeof(int)))[i+offset];
134     putchar(sc);
135   }
136 }
137
138 #ifdef DSTM
139 void CALL00(___System______clearPrefetchCache____) {
140   prehashClear();
141 }
142
143 #ifdef RANGEPREFETCH
144 void CALL02(___System______rangePrefetch____L___Object_____AR_S, struct ___Object___ * ___o___, struct ArrayObject * ___offsets___) {
145   /* Manual Prefetches to be inserted */
146   //printf("DEBUG-> %s() ___Object___ * ___o___ = %x\n", __func__, VAR(___o___));
147   //printf("DEBUG-> %s() ArrayObject * = %x\n", __func__, VAR(___offsets___));
148   int numoffset=VAR(___offsets___)->___length___;
149   int i;
150   short offArry[numoffset+2];
151   offArry[0] = 0;
152   offArry[1] = 0;
153   for(i = 2; i<(numoffset+2); i++) {
154     offArry[i] = *((short *)(((char *)&VAR(___offsets___)->___length___) + sizeof(int) + (i-2) * sizeof(short)));
155     //printf("DEBUG-> offArry[%d] = %d\n", i, offArry[i]);
156   }
157   unsigned int oid;
158   if(((unsigned int)(VAR(___o___)) & 1) != 0) { //odd
159     oid =  (unsigned int) VAR(___o___); //outside transaction therefore just an oid
160   } else { //even
161     oid = (unsigned int) COMPOID(VAR(___o___)); //inside transaction therefore a pointer to oid
162   }
163   rangePrefetch(oid, (short)(numoffset+2), offArry);
164 }
165 #else
166 void CALL02(___System______rangePrefetch____L___Object_____AR_S, struct ___Object___ * ___o___, struct ArrayObject * ___offsets___) {
167   return;
168 }
169 #endif
170
171 #endif
172
173 /* Object allocation function */
174
175 #ifdef DSTM
176 __attribute__((malloc)) void * allocate_newglobal(int type) {
177   struct ___Object___ * v=(struct ___Object___ *) transCreateObj(classsize[type]);
178   v->type=type;
179 #ifdef THREADS
180   v->tid=0;
181   v->lockentry=0;
182   v->lockcount=0;
183 #endif
184   return v;
185 }
186
187 /* Array allocation function */
188
189 __attribute__((malloc)) struct ArrayObject * allocate_newarrayglobal(int type, int length) {
190   struct ArrayObject * v=(struct ArrayObject *)transCreateObj(sizeof(struct ArrayObject)+length*classsize[type]);
191   if (length<0) {
192     printf("ERROR: negative array\n");
193     return NULL;
194   }
195   v->type=type;
196   v->___length___=length;
197 #ifdef THREADS
198   v->tid=0;
199   v->lockentry=0;
200   v->lockcount=0;
201 #endif
202   return v;
203 }
204 #endif
205
206
207 #ifdef STM
208 // STM Versions of allocation functions
209
210 /* Object allocation function */
211 __attribute__((malloc)) void * allocate_newtrans(void * ptr, int type) {
212   struct ___Object___ * v=(struct ___Object___ *) transCreateObj(ptr, classsize[type]);
213   v->type=type;
214   v->___objlocation___=v;
215   return v;
216 }
217
218 /* Array allocation function */
219 __attribute__((malloc)) struct ArrayObject * allocate_newarraytrans(void * ptr, int type, int length) {
220   struct ArrayObject * v=(struct ArrayObject *)transCreateObj(ptr, sizeof(struct ArrayObject)+length*classsize[type]);
221   if (length<0) {
222     printf("ERROR: negative array\n");
223     return NULL;
224   }
225   v->___objlocation___=(struct ___Object___*)v;
226   v->type=type;
227   v->___length___=length;
228   return v;
229 }
230 __attribute__((malloc)) void * allocate_new(void * ptr, int type) {
231   objheader_t *tmp=mygcmalloc((struct garbagelist *) ptr, classsize[type]+sizeof(objheader_t));
232   struct ___Object___ * v=(struct ___Object___ *) &tmp[1];
233   initdsmlocks(&tmp->lock);
234   tmp->version = 1;
235   v->___objlocation___=v;
236   v->type = type;
237   return v;
238 }
239
240 /* Array allocation function */
241
242 __attribute__((malloc)) struct ArrayObject * allocate_newarray(void * ptr, int type, int length) {
243   objheader_t *tmp=mygcmalloc((struct garbagelist *) ptr, sizeof(struct ArrayObject)+length*classsize[type]+sizeof(objheader_t));
244   struct ArrayObject * v=(struct ArrayObject *) &tmp[1];
245   initdsmlocks(&tmp->lock);
246   tmp->version=1;
247   v->type=type;
248   if (length<0) {
249     printf("ERROR: negative array\n");
250     return NULL;
251   }
252   v->___objlocation___=(struct ___Object___ *)v;
253   v->___length___=length;
254   return v;
255 }
256 #endif
257
258 #ifndef STM
259 #if defined(PRECISE_GC)
260 __attribute__((malloc)) void * allocate_new(void * ptr, int type) {
261   struct ___Object___ * v=(struct ___Object___ *) mygcmalloc((struct garbagelist *) ptr, classsize[type]);
262   v->type=type;
263 #ifdef THREADS
264   v->tid=0;
265   v->lockentry=0;
266   v->lockcount=0;
267 #endif
268 #ifdef OPTIONAL
269   v->fses=0;
270 #endif
271   return v;
272 }
273
274 /* Array allocation function */
275
276 __attribute__((malloc)) struct ArrayObject * allocate_newarray(void * ptr, int type, int length) {
277   struct ArrayObject * v=mygcmalloc((struct garbagelist *) ptr, sizeof(struct ArrayObject)+length*classsize[type]);
278   v->type=type;
279   if (length<0) {
280     printf("ERROR: negative array\n");
281     return NULL;
282   }
283   v->___length___=length;
284 #ifdef THREADS
285   v->tid=0;
286   v->lockentry=0;
287   v->lockcount=0;
288 #endif
289 #ifdef OPTIONAL
290   v->fses=0;
291 #endif
292   return v;
293 }
294
295 #else
296 __attribute__((malloc)) void * allocate_new(int type) {
297   struct ___Object___ * v=FREEMALLOC(classsize[type]);
298   v->type=type;
299 #ifdef OPTIONAL
300   v->fses=0;
301 #endif
302   return v;
303 }
304
305 /* Array allocation function */
306
307 __attribute__((malloc)) struct ArrayObject * allocate_newarray(int type, int length) {
308   __attribute__((malloc))  struct ArrayObject * v=FREEMALLOC(sizeof(struct ArrayObject)+length*classsize[type]);
309   v->type=type;
310   v->___length___=length;
311 #ifdef OPTIONAL
312   v->fses=0;
313 #endif
314   return v;
315 }
316 #endif
317 #endif
318
319
320 /* Converts C character arrays into Java strings */
321 #ifdef PRECISE_GC
322 __attribute__((malloc)) struct ___String___ * NewString(void * ptr, const char *str,int length) {
323 #else
324 __attribute__((malloc)) struct ___String___ * NewString(const char *str,int length) {
325 #endif
326   int i;
327 #ifdef PRECISE_GC
328   struct ArrayObject * chararray=allocate_newarray((struct garbagelist *)ptr, CHARARRAYTYPE, length);
329   INTPTR ptrarray[]={1, (INTPTR) ptr, (INTPTR) chararray};
330   struct ___String___ * strobj=allocate_new((struct garbagelist *) &ptrarray, STRINGTYPE);
331   chararray=(struct ArrayObject *) ptrarray[2];
332 #else
333   struct ArrayObject * chararray=allocate_newarray(CHARARRAYTYPE, length);
334   struct ___String___ * strobj=allocate_new(STRINGTYPE);
335 #endif
336   strobj->___value___=chararray;
337   strobj->___count___=length;
338   strobj->___offset___=0;
339
340   for(i=0; i<length; i++) {
341     ((short *)(((char *)&chararray->___length___)+sizeof(int)))[i]=(short)str[i];
342   }
343   return strobj;
344 }
345
346 /* Generated code calls this if we fail a bounds check */
347
348 void failedboundschk() {
349 #ifndef TASK
350   printf("Array out of bounds\n");
351 #ifdef THREADS
352   threadexit();
353 #else
354   exit(-1);
355 #endif
356 #else
357   longjmp(error_handler,2);
358 #endif
359 }
360
361 /* Abort task call */
362 void abort_task() {
363 #ifdef TASK
364   longjmp(error_handler,4);
365 #else
366   printf("Aborting\n");
367   exit(-1);
368 #endif
369 }