more stm options
[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 #ifdef RECOVERY
12 #include "DSTM/interface_recovery/dstm.h"
13 #include "DSTM/interface_recovery/prelookup.h"
14 #else
15 #include "DSTM/interface/dstm.h"
16 #include "DSTM/interface/prelookup.h"
17 #include "DSTM/interface/prefetch.h"
18 #endif
19 #endif
20 #ifdef STM
21 #include "tm.h"
22 #include <pthread.h>
23 #endif
24 #ifdef STMLOG
25 #define ARRAY_LENGTH 700003
26 __thread int counter;
27 __thread int event[ARRAY_LENGTH];
28 __thread unsigned long long clkticks[ARRAY_LENGTH];
29 unsigned long long beginClock=0;
30 #define FILENAME  "log"
31 #endif
32
33 #if defined(THREADS)||defined(STM)
34 /* Global barrier for STM */
35 pthread_barrier_t barrier;
36 pthread_barrierattr_t attr;
37 #endif
38
39 #include <string.h>
40
41 extern int classsize[];
42 extern int typearray[];
43 extern int typearray2[];
44 jmp_buf error_handler;
45 int instructioncount;
46
47 char *options;
48 int injectfailures=0;
49 float failurechance=0;
50 int errors=0;
51 int debugtask=0;
52 int injectinstructionfailures;
53 int failurecount;
54 float instfailurechance=0;
55 int numfailures;
56 int instaccum=0;
57 typedef unsigned long long ticks;
58 #ifdef DMALLOC
59 #include "dmalloc.h"
60 #endif
61
62 int instanceof(struct ___Object___ *ptr, int type) {
63   int i=ptr->type;
64   do {
65     if (i==type)
66       return 1;
67     i=typearray[i];
68   } while(i!=-1);
69   i=ptr->type;
70   if (i>NUMCLASSES) {
71     do {
72       if (i==type)
73         return 1;
74       i=typearray2[i-NUMCLASSES];
75     } while(i!=-1);
76   }
77   return 0;
78 }
79
80 void exithandler(int sig, siginfo_t *info, void * uap) {
81   exit(0);
82 }
83
84 void initializeexithandler() {
85   struct sigaction sig;
86   sig.sa_sigaction=&exithandler;
87   sig.sa_flags=SA_SIGINFO;
88   sigemptyset(&sig.sa_mask);
89   sigaction(SIGUSR2, &sig, 0);
90 }
91
92
93 /* This function inject failures */
94
95 void injectinstructionfailure() {
96 #ifdef TASK
97   if (injectinstructionfailures) {
98     if (numfailures==0)
99       return;
100     instructioncount=failurecount;
101     instaccum+=failurecount;
102     if ((((double)random())/RAND_MAX)<instfailurechance) {
103       if (numfailures>0)
104         numfailures--;
105       printf("FAILURE!!! %d\n",numfailures);
106       longjmp(error_handler,11);
107     }
108   }
109 #else
110 #ifdef THREADS
111   if (injectinstructionfailures) {
112     if (numfailures==0)
113       return;
114     instaccum+=failurecount;
115     if ((((double)random())/RAND_MAX)<instfailurechance) {
116       if (numfailures>0)
117         numfailures--;
118       printf("FAILURE!!! %d\n",numfailures);
119       threadexit();
120     }
121   }
122 #endif
123 #endif
124 }
125
126 #ifdef D___Double______nativeparsedouble____L___String___
127 double CALL01(___Double______nativeparsedouble____L___String___,struct ___String___ * ___str___) {
128   int length=VAR(___str___)->___count___;
129   int maxlength=(length>60)?60:length;
130   char str[maxlength+1];
131   struct ArrayObject * chararray=VAR(___str___)->___value___;
132   int i;
133   int offset=VAR(___str___)->___offset___;
134   for(i=0; i<maxlength; i++) {
135     str[i]=((short *)(((char *)&chararray->___length___)+sizeof(int)))[i+offset];
136   }
137   str[i]=0;
138   double d=atof(str);
139   return d;
140 }
141 #endif
142
143 #ifdef D___Double______nativeparsedouble_____AR_B_I_I 
144 double CALL23(___Double______nativeparsedouble_____AR_B_I_I, int start, int length,int start,int length,struct ArrayObject * ___str___) {
145   int maxlength=(length>60)?60:length;
146   char str[maxlength+1];
147   struct ArrayObject * bytearray=VAR(___str___);
148   int i;
149   for(i=0; i<maxlength; i++) {
150     str[i]=(((char *)&bytearray->___length___)+sizeof(int))[i+start];
151   }
152   str[i]=0;
153   double d=atof(str);
154   return d;
155 }
156 #endif
157
158 #ifdef D___String______convertdoubletochar____D__AR_C
159 int CALL12(___String______convertdoubletochar____D__AR_C, double ___val___, double ___val___, struct ArrayObject ___chararray___) {
160   int length=VAR(___chararray___)->___length___;
161   char str[length];
162   int i;
163   int num=snprintf(str, length, "%f",___val___);
164   if (num>=length)
165     num=length-1;
166   for(i=0; i<length; i++) {
167     ((short *)(((char *)&VAR(___chararray___)->___length___)+sizeof(int)))[i]=(short)str[i];
168   }
169   return num;
170 }
171 #endif
172 #ifdef D___System______deepArrayCopy____L___Object____L___Object___
173 void deepArrayCopy(struct ___Object___ * dst, struct ___Object___ * src) {
174   int dsttype=((int *)dst)[0];
175   int srctype=((int *)src)[0];
176 #ifdef STMARRAY
177   src=src->___objlocation___;
178 #endif
179   if (dsttype<NUMCLASSES||srctype<NUMCLASSES||srctype!=dsttype)
180     return;
181   struct ArrayObject *aodst=(struct ArrayObject *)dst;
182   struct ArrayObject *aosrc=(struct ArrayObject *)src;
183   int dstlength=aodst->___length___;
184   int srclength=aosrc->___length___;
185   if (dstlength!=srclength)
186     return;
187   unsigned INTPTR *pointer=pointerarray[srctype];
188   if (pointer==0) {
189     int elementsize=classsize[srctype];
190     int size=srclength*elementsize;
191     //primitives
192     memcpy(((char *)&aodst->___length___)+sizeof(int) , ((char *)&aosrc->___length___)+sizeof(int), size);
193   } else {
194     //objects
195     int i;
196     for(i=0;i<srclength;i++) {
197       struct ___Object___ * ptr=((struct ___Object___**)(((char*) &aosrc->___length___)+sizeof(int)))[i];
198       int ptrtype=((int *)ptr)[0];
199       if (ptrtype>=NUMCLASSES) {
200         struct ___Object___ * dstptr=((struct ___Object___**)(((char*) &aodst->___length___)+sizeof(int)))[i];
201         deepArrayCopy(dstptr,ptr);
202       } else {
203         //hit an object
204         ((struct ___Object___ **)(((char*) &aodst->___length___)+sizeof(int)))[i]=ptr;
205       }
206     }
207   }
208 }
209
210 void CALL02(___System______deepArrayCopy____L___Object____L___Object___, struct ___Object___ * ___dst___, struct ___Object___ * ___src___) {
211   deepArrayCopy(VAR(___dst___), VAR(___src___));
212 }
213 #endif
214
215 void CALL11(___System______exit____I,int ___status___, int ___status___) {
216 #ifdef TRANSSTATS
217   printf("numTransCommit = %d\n", numTransCommit);
218   printf("numTransAbort = %d\n", numTransAbort);
219   printf("nSoftAbort = %d\n", nSoftAbort);
220 #ifdef STM
221   printf("nSoftAbortCommit = %d\n", nSoftAbortCommit);
222   printf("nSoftAbortAbort = %d\n", nSoftAbortAbort);
223 #ifdef STMSTATS
224   int i;
225   for(i=0; i<TOTALNUMCLASSANDARRAY; i++) {
226     printf("typesCausingAbort[%2d] numaccess= %5d numabort= %3d\n", i, typesCausingAbort[i].numaccess, typesCausingAbort[i].numabort);
227   }
228 #endif
229 #endif
230 #endif
231   exit(___status___);
232 }
233
234 #if defined(__i386__)
235
236 static __inline__ unsigned long long rdtsc(void)
237 {
238   unsigned long long int x;
239   __asm__ volatile (".byte 0x0f, 0x31" : "=A" (x));
240   return x;
241 }
242 #elif defined(__x86_64__)
243
244 static __inline__ unsigned long long rdtsc(void)
245 {
246   unsigned hi, lo;
247   __asm__ __volatile__ ("rdtsc" : "=a"(lo), "=d"(hi));
248   return ( (unsigned long long)lo)|( ((unsigned long long)hi)<<32 );
249 }
250
251 #elif defined(__powerpc__)
252
253 typedef unsigned long long int unsigned long long;
254
255 static __inline__ unsigned long long rdtsc(void)
256 {
257   unsigned long long int result=0;
258   unsigned long int upper, lower,tmp;
259   __asm__ volatile(
260       "0:                  \n"
261       "\tmftbu   %0           \n"
262       "\tmftb    %1           \n"
263       "\tmftbu   %2           \n"
264       "\tcmpw    %2,%0        \n"
265       "\tbne     0b         \n"
266       : "=r"(upper),"=r"(lower),"=r"(tmp)
267       );
268   result = upper;
269   result = result<<32;
270   result = result|lower;
271
272   return(result);
273 }
274 #endif
275
276 void CALL11(___System______logevent____I,int ___event___, int ___event___) {
277 #ifdef STMLOG
278   event[counter] = ___event___;
279   clkticks[counter] = rdtsc();
280   counter++;
281 #endif
282   return;
283 }
284
285 void CALL00(___System______logevent____) {
286 #ifdef STMLOG
287   beginClock= rdtsc();
288 #endif
289   return;
290 }
291
292 void CALL11(___System______flushToFile____I, int ___threadid___, int ___threadid___) {
293 #ifdef STMLOG
294   FILE *fp;
295   /* Flush to file */
296   char filename[20];
297   memset(filename, 0, 20);
298   sprintf(filename, "%s_%d", FILENAME, ___threadid___);
299   if ((fp = fopen(filename, "w+")) == NULL) {
300     perror("fopen");
301     return;
302   }
303   int i;
304   for (i = 0; i < counter-1; i++) {
305     fprintf(fp, "%d %lld %lld\n", event[i], clkticks[i]-beginClock, clkticks[i+1]-beginClock);
306   }
307   fprintf(fp, "%d %lld\n", event[i], clkticks[i]-beginClock);
308
309   fclose(fp);
310 #endif
311   return;
312 }
313
314 void CALL00(___System______initLog____) {
315 #ifdef STMLOG
316   counter=0;
317   int i;
318   for(i=0; i<ARRAY_LENGTH; i++) {
319     event[i] = 0;
320     clkticks[i] = 0;
321   }
322
323 #endif
324   return;
325 }
326
327 #ifdef D___Vector______removeElement_____AR_L___Object____I_I
328 void CALL23(___Vector______removeElement_____AR_L___Object____I_I, int ___index___, int ___size___, struct ArrayObject * ___array___, int ___index___, int ___size___) {
329   char* offset=((char *)(&VAR(___array___)->___length___))+sizeof(unsigned int)+sizeof(void *)*___index___;
330   memmove(offset, offset+sizeof(void *),(___size___-___index___-1)*sizeof(void *));
331 }
332 #endif
333
334 void CALL11(___System______printI____I,int ___status___, int ___status___) {
335   printf("%d\n",___status___);
336 }
337
338 long long CALL00(___System______currentTimeMillis____) {
339   struct timeval tv; long long retval;
340   gettimeofday(&tv, NULL);
341   retval = tv.tv_sec; /* seconds */
342   retval*=1000; /* milliseconds */
343   retval+= (tv.tv_usec/1000); /* adjust milliseconds & add them in */
344   return retval;
345 }
346
347 long long CALL00(___System______microTimes____) {
348   struct timeval tv; 
349   long long retval;
350   gettimeofday(&tv, NULL);
351   retval = tv.tv_sec; /* seconds */
352   retval*=1000000; /* microsecs */
353   retval+= (tv.tv_usec); /* adjust microseconds & add them in */
354   return retval;
355 }
356
357 long long CALL00(___System______getticks____) {
358   unsigned a, d;
359   asm("cpuid");
360   asm volatile("rdtsc" : "=a" (a), "=d" (d));
361   return (((ticks)a) | (((ticks)d) << 32));
362 }
363
364 void CALL01(___System______printString____L___String___,struct ___String___ * ___s___) {
365   struct ArrayObject * chararray=VAR(___s___)->___value___;
366   int i;
367   int offset=VAR(___s___)->___offset___;
368   for(i=0; i<VAR(___s___)->___count___; i++) {
369     short sc=((short *)(((char *)&chararray->___length___)+sizeof(int)))[i+offset];
370     putchar(sc);
371   }
372 }
373
374 #ifdef DSTM
375 void CALL00(___System______clearPrefetchCache____) {
376   prehashClear();
377 }
378
379 #ifdef RANGEPREFETCH
380 void CALL02(___System______rangePrefetch____L___Object_____AR_S, struct ___Object___ * ___o___, struct ArrayObject * ___offsets___) {
381   /* Manual Prefetches to be inserted */
382   //printf("DEBUG-> %s() ___Object___ * ___o___ = %x\n", __func__, VAR(___o___));
383   //printf("DEBUG-> %s() ArrayObject * = %x\n", __func__, VAR(___offsets___));
384   int numoffset=VAR(___offsets___)->___length___;
385   int i;
386   short offArry[numoffset+2];
387   offArry[0] = 0;
388   offArry[1] = 0;
389   for(i = 2; i<(numoffset+2); i++) {
390     offArry[i] = *((short *)(((char *)&VAR(___offsets___)->___length___) + sizeof(int) + (i-2) * sizeof(short)));
391     //printf("DEBUG-> offArry[%d] = %d\n", i, offArry[i]);
392   }
393   unsigned int oid;
394   if(((unsigned int)(VAR(___o___)) & 1) != 0) { //odd
395     oid =  (unsigned int) VAR(___o___); //outside transaction therefore just an oid
396   } else { //even
397     oid = (unsigned int) COMPOID(VAR(___o___)); //inside transaction therefore a pointer to oid
398   }
399   rangePrefetch(oid, (short)(numoffset+2), offArry);
400 }
401 #else
402 void CALL02(___System______rangePrefetch____L___Object_____AR_S, struct ___Object___ * ___o___, struct ArrayObject * ___offsets___) {
403   return;
404 }
405 #endif
406
407 #ifdef D___Task______execution____ 
408 extern void* virtualtable[];
409 // associated with Task.execution(). finds proper execute method and call it
410 void CALL01(___Task______execution____,struct ___Task___ * ___this___)
411 {
412   unsigned int oid;
413   oid = (unsigned int) VAR(___this___);   // object id
414   int type = getObjType(oid);             // object type
415
416 #ifdef PRECISE_GC
417   int p[] = {1,0 , oid};
418    
419   ((void(*) (void *))virtualtable[type*MAXCOUNT + EXECUTEMETHOD])(p);
420 #else
421   // call the proper execute method
422   ((void(*) (void *))virtualtable[type*MAXCOUNT + EXECUTEMETHOD])(oid);
423 #endif
424 }
425 #endif
426
427 #endif // DSTM
428
429 /* STM Barrier constructs */
430 #ifdef D___Barrier______setBarrier____I
431 void CALL11(___Barrier______setBarrier____I, int nthreads, int nthreads) {
432   // Barrier initialization
433   int ret;
434   if((ret = pthread_barrier_init(&barrier, NULL, nthreads)) != 0) {
435     printf("%s() Could not create a barrier: numthreads = 0 in %s\n", __func__, __FILE__);
436     exit(-1);
437   }
438 }
439 #endif
440
441 #ifdef D___Barrier______enterBarrier____
442 void CALL00(___Barrier______enterBarrier____) {
443   // Synchronization point
444   int ret;
445 #ifdef PRECISE_GC
446   stopforgc((struct garbagelist *)___params___);
447 #endif
448   ret = pthread_barrier_wait(&barrier);
449 #ifdef PRECISE_GC
450   restartaftergc();
451 #endif
452   if(ret != 0 && ret != PTHREAD_BARRIER_SERIAL_THREAD) {
453     printf("%s() Could not wait on barrier: error %d in %s\n", __func__, errno, __FILE__);
454     exit(-1);
455   }
456 }
457 #endif
458
459 /* Object allocation function */
460
461 #ifdef DSTM
462 __attribute__((malloc)) void * allocate_newglobal(int type) {
463   struct ___Object___ * v=(struct ___Object___ *) transCreateObj(classsize[type]);
464   v->type=type;
465   //printf("DEBUG %s(), type= %x\n", __func__, type);
466 #ifdef THREADS
467   v->tid=0;
468   v->lockentry=0;
469   v->lockcount=0;
470 #endif
471   return v;
472 }
473
474 /* Array allocation function */
475
476 __attribute__((malloc)) struct ArrayObject * allocate_newarrayglobal(int type, int length) {
477   struct ArrayObject * v=(struct ArrayObject *)transCreateObj(sizeof(struct ArrayObject)+length*classsize[type]);
478   if (length<0) {
479     printf("ERROR: negative array\n");
480     return NULL;
481   }
482   v->type=type;
483   v->___length___=length;
484 #ifdef THREADS
485   v->tid=0;
486   v->lockentry=0;
487   v->lockcount=0;
488 #endif
489   return v;
490 }
491 #endif
492
493
494 #ifdef STM
495 // STM Versions of allocation functions
496
497 /* Object allocation function */
498 __attribute__((malloc)) void * allocate_newtrans(void * ptr, int type) {
499 #ifdef STMARRAY
500   struct ___Object___ * v=(struct ___Object___ *) transCreateObj(ptr, classsize[type], 0);
501 #else
502   struct ___Object___ * v=(struct ___Object___ *) transCreateObj(ptr, classsize[type]);
503 #endif
504   v->type=type;
505   v->___objlocation___=v;
506   return v;
507 }
508
509 /* Array allocation function */
510 __attribute__((malloc)) struct ArrayObject * allocate_newarraytrans(void * ptr, int type, int length) {
511 #ifdef STMARRAY
512   int basesize=length*classsize[type];
513   //round the base size up
514   basesize=(basesize+LOWMASK)&HIGHMASK;
515   int numlocks=basesize>>INDEXSHIFT;
516   int bookkeepsize=numlocks*2*sizeof(int);
517   struct ArrayObject * v=(struct ArrayObject *)transCreateObj(ptr, sizeof(struct ArrayObject)+basesize+bookkeepsize, bookkeepsize);
518   unsigned int *intptr=(unsigned int *)(((char *)v)-sizeof(objheader_t));
519   for(;numlocks>0;numlocks--) {
520     intptr-=2;
521     intptr[0]=1;
522   }
523   v->highindex=-1;
524   v->lowindex=MAXARRAYSIZE;
525 #else
526   struct ArrayObject * v=(struct ArrayObject *)transCreateObj(ptr, sizeof(struct ArrayObject)+length*classsize[type]);
527 #endif
528   if (length<0) {
529     printf("ERROR: negative array\n");
530     return NULL;
531   }
532   v->___objlocation___=(struct ___Object___*)v;
533   v->type=type;
534   v->___length___=length;
535   return v;
536 }
537
538 __attribute__((malloc)) void * allocate_new(void * ptr, int type) {
539   objheader_t *tmp=mygcmalloc((struct garbagelist *) ptr, classsize[type]+sizeof(objheader_t));
540   struct ___Object___ * v=(struct ___Object___ *) &tmp[1];
541   initdsmlocks(&tmp->lock);
542   tmp->version = 1;
543   v->___objlocation___=v;
544   v->type = type;
545   return v;
546 }
547
548 /* Array allocation function */
549
550 __attribute__((malloc)) struct ArrayObject * allocate_newarray(void * ptr, int type, int length) {
551 #ifdef STMARRAY
552   int basesize=length*classsize[type];
553   //round the base size up
554   basesize=(basesize+LOWMASK)&HIGHMASK;
555   int numlocks=basesize>>INDEXSHIFT;
556   int bookkeepsize=(numlocks)*2*sizeof(int);
557   int *tmpint=mygcmalloc((struct garbagelist *) ptr, sizeof(struct ArrayObject)+basesize+sizeof(objheader_t)+bookkeepsize);
558   for(;numlocks>0;numlocks--) {
559     tmpint[0]=1;
560     tmpint+=2;
561   }
562   objheader_t *tmp=(objheader_t *)tmpint;
563   struct ArrayObject * v=(struct ArrayObject *) &tmp[1];
564   v->highindex=-1;
565   v->lowindex=MAXARRAYSIZE;
566 #else
567   objheader_t *tmp=mygcmalloc((struct garbagelist *) ptr, sizeof(struct ArrayObject)+length*classsize[type]+sizeof(objheader_t));
568   struct ArrayObject * v=(struct ArrayObject *) &tmp[1];
569 #endif
570 #ifdef DUALVIEW
571   tmp->lock=RW_LOCK_BIAS;
572 #else
573   initdsmlocks(&tmp->lock);
574 #endif
575   tmp->version=1;
576   v->type=type;
577   if (length<0) {
578     printf("ERROR: negative array %d\n", length);
579     return NULL;
580   }
581   v->___objlocation___=(struct ___Object___ *)v;
582   v->___length___=length;
583   return v;
584 }
585 #endif
586
587 #ifndef STM
588 #if defined(PRECISE_GC)
589 __attribute__((malloc)) void * allocate_new(void * ptr, int type) {
590   struct ___Object___ * v=(struct ___Object___ *) mygcmalloc((struct garbagelist *) ptr, classsize[type]);
591   v->type=type;
592 #ifdef THREADS
593   v->tid=0;
594   v->lockentry=0;
595   v->lockcount=0;
596 #endif
597 #ifdef OPTIONAL
598   v->fses=0;
599 #endif
600   return v;
601 }
602
603 /* Array allocation function */
604
605 __attribute__((malloc)) struct ArrayObject * allocate_newarray(void * ptr, int type, int length) {
606   struct ArrayObject * v=mygcmalloc((struct garbagelist *) ptr, sizeof(struct ArrayObject)+length*classsize[type]);
607   v->type=type;
608   if (length<0) {
609     printf("ERROR: negative array\n");
610     return NULL;
611   }
612   v->___length___=length;
613 #ifdef THREADS
614   v->tid=0;
615   v->lockentry=0;
616   v->lockcount=0;
617 #endif
618 #ifdef OPTIONAL
619   v->fses=0;
620 #endif
621   return v;
622 }
623
624 #else
625 __attribute__((malloc)) void * allocate_new(int type) {
626   struct ___Object___ * v=FREEMALLOC(classsize[type]);
627   v->type=type;
628 #ifdef OPTIONAL
629   v->fses=0;
630 #endif
631   return v;
632 }
633
634 /* Array allocation function */
635
636 __attribute__((malloc)) struct ArrayObject * allocate_newarray(int type, int length) {
637   __attribute__((malloc))  struct ArrayObject * v=FREEMALLOC(sizeof(struct ArrayObject)+length*classsize[type]);
638   v->type=type;
639   v->___length___=length;
640 #ifdef OPTIONAL
641   v->fses=0;
642 #endif
643   return v;
644 }
645 #endif
646 #endif
647
648 /* Converts C character arrays into Java strings */
649 #ifdef PRECISE_GC
650 __attribute__((malloc)) struct ___String___ * NewString(void * ptr, const char *str,int length) {
651 #else
652 __attribute__((malloc)) struct ___String___ * NewString(const char *str,int length) {
653 #endif
654   int i;
655 #ifdef PRECISE_GC
656   struct ArrayObject * chararray=allocate_newarray((struct garbagelist *)ptr, CHARARRAYTYPE, length);
657   INTPTR ptrarray[]={1, (INTPTR) ptr, (INTPTR) chararray};
658   struct ___String___ * strobj=allocate_new((struct garbagelist *) &ptrarray, STRINGTYPE);
659   chararray=(struct ArrayObject *) ptrarray[2];
660 #else
661   struct ArrayObject * chararray=allocate_newarray(CHARARRAYTYPE, length);
662   struct ___String___ * strobj=allocate_new(STRINGTYPE);
663 #endif
664   strobj->___value___=chararray;
665   strobj->___count___=length;
666   strobj->___offset___=0;
667
668   for(i=0; i<length; i++) {
669     ((short *)(((char *)&chararray->___length___)+sizeof(int)))[i]=(short)str[i];
670   }
671   return strobj;
672 }
673
674 /* Generated code calls this if we fail a bounds check */
675
676 void failedboundschk() {
677 #ifndef TASK
678   printf("Array out of bounds\n");
679 #ifdef THREADS
680   threadexit();
681 #else
682   exit(-1);
683 #endif
684 #else
685   longjmp(error_handler,2);
686 #endif
687 }
688
689 /* Abort task call */
690 void abort_task() {
691 #ifdef TASK
692   longjmp(error_handler,4);
693 #else
694   printf("Aborting\n");
695   exit(-1);
696 #endif
697 }
698
699 #ifndef SANDBOX
700 #ifdef D___System______Assert____Z
701  void CALL11(___System______Assert____Z, int ___status___, int ___status___) {
702    if (!___status___) {
703      printf("Assertion violation\n");
704      *((int *)(NULL)); //force stack trace error
705    }
706  }
707 #endif
708 #endif