small differences
[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   if (dsttype<NUMCLASSES||srctype<NUMCLASSES||srctype!=dsttype)
177     return;
178   struct ArrayObject *aodst=(struct ArrayObject *)dst;
179   struct ArrayObject *aosrc=(struct ArrayObject *)src;
180   int dstlength=aodst->___length___;
181   int srclength=aosrc->___length___;
182   if (dstlength!=srclength)
183     return;
184   unsigned INTPTR *pointer=pointerarray[srctype];
185   if (pointer==0) {
186     int elementsize=classsize[srctype];
187     int size=srclength*elementsize;
188     //primitives
189     memcpy(((char *)&aodst->___length___)+sizeof(int) , ((char *)&aosrc->___length___)+sizeof(int), size);
190   } else {
191     //objects
192     int i;
193     for(i=0;i<srclength;i++) {
194       struct ___Object___ * ptr=((struct ___Object___**)(((char*) &aosrc->___length___)+sizeof(int)))[i];
195       int ptrtype=((int *)ptr)[0];
196       if (ptrtype>=NUMCLASSES) {
197         struct ___Object___ * dstptr=((struct ___Object___**)(((char*) &aodst->___length___)+sizeof(int)))[i];
198         deepArrayCopy(dstptr,ptr);
199       } else {
200         //hit an object
201         ((struct ___Object___ **)(((char*) &aodst->___length___)+sizeof(int)))[i]=ptr;
202       }
203     }
204   }
205 }
206
207 void CALL02(___System______deepArrayCopy____L___Object____L___Object___, struct ___Object___ * ___dst___, struct ___Object___ * ___src___) {
208   deepArrayCopy(VAR(___dst___), VAR(___src___));
209 }
210 #endif
211
212 void CALL11(___System______exit____I,int ___status___, int ___status___) {
213 #ifdef TRANSSTATS
214   printf("numTransCommit = %d\n", numTransCommit);
215   printf("numTransAbort = %d\n", numTransAbort);
216   printf("nSoftAbort = %d\n", nSoftAbort);
217 #ifdef STM
218   printf("nSoftAbortCommit = %d\n", nSoftAbortCommit);
219   printf("nSoftAbortAbort = %d\n", nSoftAbortAbort);
220 #ifdef STMSTATS
221   int i;
222   for(i=0; i<TOTALNUMCLASSANDARRAY; i++) {
223     printf("typesCausingAbort[%2d] numaccess= %5d numabort= %3d\n", i, typesCausingAbort[i].numaccess, typesCausingAbort[i].numabort);
224   }
225 #endif
226 #endif
227 #endif
228   exit(___status___);
229 }
230
231 #if defined(__i386__)
232
233 static __inline__ unsigned long long rdtsc(void)
234 {
235   unsigned long long int x;
236   __asm__ volatile (".byte 0x0f, 0x31" : "=A" (x));
237   return x;
238 }
239 #elif defined(__x86_64__)
240
241 static __inline__ unsigned long long rdtsc(void)
242 {
243   unsigned hi, lo;
244   __asm__ __volatile__ ("rdtsc" : "=a"(lo), "=d"(hi));
245   return ( (unsigned long long)lo)|( ((unsigned long long)hi)<<32 );
246 }
247
248 #elif defined(__powerpc__)
249
250 typedef unsigned long long int unsigned long long;
251
252 static __inline__ unsigned long long rdtsc(void)
253 {
254   unsigned long long int result=0;
255   unsigned long int upper, lower,tmp;
256   __asm__ volatile(
257       "0:                  \n"
258       "\tmftbu   %0           \n"
259       "\tmftb    %1           \n"
260       "\tmftbu   %2           \n"
261       "\tcmpw    %2,%0        \n"
262       "\tbne     0b         \n"
263       : "=r"(upper),"=r"(lower),"=r"(tmp)
264       );
265   result = upper;
266   result = result<<32;
267   result = result|lower;
268
269   return(result);
270 }
271 #endif
272
273 void CALL11(___System______logevent____I,int ___event___, int ___event___) {
274 #ifdef STMLOG
275   event[counter] = ___event___;
276   clkticks[counter] = rdtsc();
277   counter++;
278 #endif
279   return;
280 }
281
282 void CALL00(___System______logevent____) {
283 #ifdef STMLOG
284   beginClock= rdtsc();
285 #endif
286   return;
287 }
288
289 void CALL11(___System______flushToFile____I, int ___threadid___, int ___threadid___) {
290 #ifdef STMLOG
291   FILE *fp;
292   /* Flush to file */
293   char filename[20];
294   memset(filename, 0, 20);
295   sprintf(filename, "%s_%d", FILENAME, ___threadid___);
296   if ((fp = fopen(filename, "w+")) == NULL) {
297     perror("fopen");
298     return;
299   }
300   int i;
301   for (i = 0; i < counter-1; i++) {
302     fprintf(fp, "%d %lld %lld\n", event[i], clkticks[i]-beginClock, clkticks[i+1]-beginClock);
303   }
304   fprintf(fp, "%d %lld\n", event[i], clkticks[i]-beginClock);
305
306   fclose(fp);
307 #endif
308   return;
309 }
310
311 void CALL00(___System______initLog____) {
312 #ifdef STMLOG
313   counter=0;
314   int i;
315   for(i=0; i<ARRAY_LENGTH; i++) {
316     event[i] = 0;
317     clkticks[i] = 0;
318   }
319
320 #endif
321   return;
322 }
323
324 #ifdef D___Vector______removeElement_____AR_L___Object____I_I
325 void CALL23(___Vector______removeElement_____AR_L___Object____I_I, int ___index___, int ___size___, struct ArrayObject * ___array___, int ___index___, int ___size___) {
326   char* offset=((char *)(&VAR(___array___)->___length___))+sizeof(unsigned int)+sizeof(void *)*___index___;
327   memmove(offset, offset+sizeof(void *),(___size___-___index___-1)*sizeof(void *));
328 }
329 #endif
330
331 void CALL11(___System______printI____I,int ___status___, int ___status___) {
332   printf("%d\n",___status___);
333 }
334
335 long long CALL00(___System______currentTimeMillis____) {
336   struct timeval tv; long long retval;
337   gettimeofday(&tv, NULL);
338   retval = tv.tv_sec; /* seconds */
339   retval*=1000; /* milliseconds */
340   retval+= (tv.tv_usec/1000); /* adjust milliseconds & add them in */
341   return retval;
342 }
343
344 long long CALL00(___System______microTimes____) {
345   struct timeval tv; 
346   long long retval;
347   gettimeofday(&tv, NULL);
348   retval = tv.tv_sec; /* seconds */
349   retval*=1000000; /* microsecs */
350   retval+= (tv.tv_usec); /* adjust microseconds & add them in */
351   return retval;
352 }
353
354 long long CALL00(___System______getticks____) {
355   unsigned a, d;
356   asm("cpuid");
357   asm volatile("rdtsc" : "=a" (a), "=d" (d));
358   return (((ticks)a) | (((ticks)d) << 32));
359 }
360
361 void CALL01(___System______printString____L___String___,struct ___String___ * ___s___) {
362   struct ArrayObject * chararray=VAR(___s___)->___value___;
363   int i;
364   int offset=VAR(___s___)->___offset___;
365   for(i=0; i<VAR(___s___)->___count___; i++) {
366     short sc=((short *)(((char *)&chararray->___length___)+sizeof(int)))[i+offset];
367     putchar(sc);
368   }
369 }
370
371 #ifdef DSTM
372 void CALL00(___System______clearPrefetchCache____) {
373   prehashClear();
374 }
375
376 #ifdef RANGEPREFETCH
377 void CALL02(___System______rangePrefetch____L___Object_____AR_S, struct ___Object___ * ___o___, struct ArrayObject * ___offsets___) {
378   /* Manual Prefetches to be inserted */
379   //printf("DEBUG-> %s() ___Object___ * ___o___ = %x\n", __func__, VAR(___o___));
380   //printf("DEBUG-> %s() ArrayObject * = %x\n", __func__, VAR(___offsets___));
381   int numoffset=VAR(___offsets___)->___length___;
382   int i;
383   short offArry[numoffset+2];
384   offArry[0] = 0;
385   offArry[1] = 0;
386   for(i = 2; i<(numoffset+2); i++) {
387     offArry[i] = *((short *)(((char *)&VAR(___offsets___)->___length___) + sizeof(int) + (i-2) * sizeof(short)));
388     //printf("DEBUG-> offArry[%d] = %d\n", i, offArry[i]);
389   }
390   unsigned int oid;
391   if(((unsigned int)(VAR(___o___)) & 1) != 0) { //odd
392     oid =  (unsigned int) VAR(___o___); //outside transaction therefore just an oid
393   } else { //even
394     oid = (unsigned int) COMPOID(VAR(___o___)); //inside transaction therefore a pointer to oid
395   }
396   rangePrefetch(oid, (short)(numoffset+2), offArry);
397 }
398 #else
399 void CALL02(___System______rangePrefetch____L___Object_____AR_S, struct ___Object___ * ___o___, struct ArrayObject * ___offsets___) {
400   return;
401 }
402 #endif
403
404 #ifdef D___Task______execution____ 
405 extern void* virtualtable[];
406 // associated with Task.execution(). finds proper execute method and call it
407 void CALL01(___Task______execution____,struct ___Task___ * ___this___)
408 {
409   unsigned int oid;
410   oid = (unsigned int) VAR(___this___);   // object id
411   int type = getObjType(oid);             // object type
412
413 #ifdef PRECISE_GC
414   int p[] = {1,0 , oid};
415    
416   ((void(*) (void *))virtualtable[type*MAXCOUNT + EXECUTEMETHOD])(p);
417 #else
418   // call the proper execute method
419   ((void(*) (void *))virtualtable[type*MAXCOUNT + EXECUTEMETHOD])(oid);
420 #endif
421 }
422 #endif
423
424 #endif // DSTM
425
426 /* STM Barrier constructs */
427 #ifdef D___Barrier______setBarrier____I
428 void CALL11(___Barrier______setBarrier____I, int nthreads, int nthreads) {
429   // Barrier initialization
430   int ret;
431   if((ret = pthread_barrier_init(&barrier, NULL, nthreads)) != 0) {
432     printf("%s() Could not create a barrier: numthreads = 0 in %s\n", __func__, __FILE__);
433     exit(-1);
434   }
435 }
436 #endif
437
438 #ifdef D___Barrier______enterBarrier____
439 void CALL00(___Barrier______enterBarrier____) {
440   // Synchronization point
441   int ret;
442 #ifdef PRECISE_GC
443   stopforgc((struct garbagelist *)___params___);
444 #endif
445   ret = pthread_barrier_wait(&barrier);
446 #ifdef PRECISE_GC
447   restartaftergc();
448 #endif
449   if(ret != 0 && ret != PTHREAD_BARRIER_SERIAL_THREAD) {
450     printf("%s() Could not wait on barrier: error %d in %s\n", __func__, errno, __FILE__);
451     exit(-1);
452   }
453 }
454 #endif
455
456 /* Object allocation function */
457
458 #ifdef DSTM
459 __attribute__((malloc)) void * allocate_newglobal(int type) {
460   struct ___Object___ * v=(struct ___Object___ *) transCreateObj(classsize[type]);
461   v->type=type;
462   //printf("DEBUG %s(), type= %x\n", __func__, type);
463 #ifdef THREADS
464   v->tid=0;
465   v->lockentry=0;
466   v->lockcount=0;
467 #endif
468   return v;
469 }
470
471 /* Array allocation function */
472
473 __attribute__((malloc)) struct ArrayObject * allocate_newarrayglobal(int type, int length) {
474   struct ArrayObject * v=(struct ArrayObject *)transCreateObj(sizeof(struct ArrayObject)+length*classsize[type]);
475   if (length<0) {
476     printf("ERROR: negative array\n");
477     return NULL;
478   }
479   v->type=type;
480   v->___length___=length;
481 #ifdef THREADS
482   v->tid=0;
483   v->lockentry=0;
484   v->lockcount=0;
485 #endif
486   return v;
487 }
488 #endif
489
490
491 #ifdef STM
492 // STM Versions of allocation functions
493
494 /* Object allocation function */
495 __attribute__((malloc)) void * allocate_newtrans(void * ptr, int type) {
496 #ifdef STMARRAY
497   struct ___Object___ * v=(struct ___Object___ *) transCreateObj(ptr, classsize[type], 0);
498 #else
499   struct ___Object___ * v=(struct ___Object___ *) transCreateObj(ptr, classsize[type]);
500 #endif
501   v->type=type;
502   v->___objlocation___=v;
503   return v;
504 }
505
506 /* Array allocation function */
507 __attribute__((malloc)) struct ArrayObject * allocate_newarraytrans(void * ptr, int type, int length) {
508 #ifdef STMARRAY
509   int basesize=length*classsize[type];
510   //round the base size up
511   basesize=(basesize+LOWMASK)&HIGHMASK;
512   int numlocks=basesize>>INDEXSHIFT;
513   int bookkeepsize=numlocks*2*sizeof(int);
514   struct ArrayObject * v=(struct ArrayObject *)transCreateObj(ptr, sizeof(struct ArrayObject)+basesize+bookkeepsize, bookkeepsize);
515   unsigned int *intptr=(unsigned int *)(((char *)v)-sizeof(objheader_t));
516   for(;numlocks>0;numlocks--) {
517     intptr-=2;
518     intptr[0]=1;
519   }
520   v->highindex=-1;
521   v->lowindex=MAXARRAYSIZE;
522 #else
523   struct ArrayObject * v=(struct ArrayObject *)transCreateObj(ptr, sizeof(struct ArrayObject)+length*classsize[type]);
524 #endif
525   if (length<0) {
526     printf("ERROR: negative array\n");
527     return NULL;
528   }
529   v->___objlocation___=(struct ___Object___*)v;
530   v->type=type;
531   v->___length___=length;
532   return v;
533 }
534
535 __attribute__((malloc)) void * allocate_new(void * ptr, int type) {
536   objheader_t *tmp=mygcmalloc((struct garbagelist *) ptr, classsize[type]+sizeof(objheader_t));
537   struct ___Object___ * v=(struct ___Object___ *) &tmp[1];
538   initdsmlocks(&tmp->lock);
539   tmp->version = 1;
540   v->___objlocation___=v;
541   v->type = type;
542   return v;
543 }
544
545 /* Array allocation function */
546
547 __attribute__((malloc)) struct ArrayObject * allocate_newarray(void * ptr, int type, int length) {
548 #ifdef STMARRAY
549   int basesize=length*classsize[type];
550   //round the base size up
551   basesize=(basesize+LOWMASK)&HIGHMASK;
552   int numlocks=basesize>>INDEXSHIFT;
553   int bookkeepsize=(numlocks)*2*sizeof(int);
554   int *tmpint=mygcmalloc((struct garbagelist *) ptr, sizeof(struct ArrayObject)+basesize+sizeof(objheader_t)+bookkeepsize);
555   for(;numlocks>0;numlocks--) {
556     tmpint[0]=1;
557     tmpint+=2;
558   }
559   objheader_t *tmp=(objheader_t *)tmpint;
560   struct ArrayObject * v=(struct ArrayObject *) &tmp[1];
561   v->highindex=-1;
562   v->lowindex=MAXARRAYSIZE;
563 #else
564   objheader_t *tmp=mygcmalloc((struct garbagelist *) ptr, sizeof(struct ArrayObject)+length*classsize[type]+sizeof(objheader_t));
565   struct ArrayObject * v=(struct ArrayObject *) &tmp[1];
566 #endif
567   initdsmlocks(&tmp->lock);
568   tmp->version=1;
569   v->type=type;
570   if (length<0) {
571     printf("ERROR: negative array %d\n", length);
572     return NULL;
573   }
574   v->___objlocation___=(struct ___Object___ *)v;
575   v->___length___=length;
576   return v;
577 }
578 #endif
579
580 #ifndef STM
581 #if defined(PRECISE_GC)
582 __attribute__((malloc)) void * allocate_new(void * ptr, int type) {
583   struct ___Object___ * v=(struct ___Object___ *) mygcmalloc((struct garbagelist *) ptr, classsize[type]);
584   v->type=type;
585 #ifdef THREADS
586   v->tid=0;
587   v->lockentry=0;
588   v->lockcount=0;
589 #endif
590 #ifdef OPTIONAL
591   v->fses=0;
592 #endif
593   return v;
594 }
595
596 /* Array allocation function */
597
598 __attribute__((malloc)) struct ArrayObject * allocate_newarray(void * ptr, int type, int length) {
599   struct ArrayObject * v=mygcmalloc((struct garbagelist *) ptr, sizeof(struct ArrayObject)+length*classsize[type]);
600   v->type=type;
601   if (length<0) {
602     printf("ERROR: negative array\n");
603     return NULL;
604   }
605   v->___length___=length;
606 #ifdef THREADS
607   v->tid=0;
608   v->lockentry=0;
609   v->lockcount=0;
610 #endif
611 #ifdef OPTIONAL
612   v->fses=0;
613 #endif
614   return v;
615 }
616
617 #else
618 __attribute__((malloc)) void * allocate_new(int type) {
619   struct ___Object___ * v=FREEMALLOC(classsize[type]);
620   v->type=type;
621 #ifdef OPTIONAL
622   v->fses=0;
623 #endif
624   return v;
625 }
626
627 /* Array allocation function */
628
629 __attribute__((malloc)) struct ArrayObject * allocate_newarray(int type, int length) {
630   __attribute__((malloc))  struct ArrayObject * v=FREEMALLOC(sizeof(struct ArrayObject)+length*classsize[type]);
631   v->type=type;
632   v->___length___=length;
633 #ifdef OPTIONAL
634   v->fses=0;
635 #endif
636   return v;
637 }
638 #endif
639 #endif
640
641 /* Converts C character arrays into Java strings */
642 #ifdef PRECISE_GC
643 __attribute__((malloc)) struct ___String___ * NewString(void * ptr, const char *str,int length) {
644 #else
645 __attribute__((malloc)) struct ___String___ * NewString(const char *str,int length) {
646 #endif
647   int i;
648 #ifdef PRECISE_GC
649   struct ArrayObject * chararray=allocate_newarray((struct garbagelist *)ptr, CHARARRAYTYPE, length);
650   INTPTR ptrarray[]={1, (INTPTR) ptr, (INTPTR) chararray};
651   struct ___String___ * strobj=allocate_new((struct garbagelist *) &ptrarray, STRINGTYPE);
652   chararray=(struct ArrayObject *) ptrarray[2];
653 #else
654   struct ArrayObject * chararray=allocate_newarray(CHARARRAYTYPE, length);
655   struct ___String___ * strobj=allocate_new(STRINGTYPE);
656 #endif
657   strobj->___value___=chararray;
658   strobj->___count___=length;
659   strobj->___offset___=0;
660
661   for(i=0; i<length; i++) {
662     ((short *)(((char *)&chararray->___length___)+sizeof(int)))[i]=(short)str[i];
663   }
664   return strobj;
665 }
666
667 /* Generated code calls this if we fail a bounds check */
668
669 void failedboundschk() {
670 #ifndef TASK
671   printf("Array out of bounds\n");
672 #ifdef THREADS
673   threadexit();
674 #else
675   exit(-1);
676 #endif
677 #else
678   longjmp(error_handler,2);
679 #endif
680 }
681
682 /* Abort task call */
683 void abort_task() {
684 #ifdef TASK
685   longjmp(error_handler,4);
686 #else
687   printf("Aborting\n");
688   exit(-1);
689 #endif
690 }