694377f0915994bae0c536c24a3b59383def052c
[charm.git] / src / QuickThreads / md / setjmp64.c
1 /*****************************************************************************
2  * $Source$
3  * $Author$
4  * $Date$
5  * $Revision$
6  *****************************************************************************/
7
8
9 #include "qt.h"
10 #include <setjmp.h>
11 #ifdef ALLOCA_H
12 #include <alloca.h>
13 #endif
14
15 struct helpdesc { qt_helper_t *hfn; qt_t *jb; void *old; void *new; };
16
17 #ifdef __CYGWIN__
18 # ifdef QT_GROW_DOWN
19 #define SHIFTSP(pos) asm ( "mov %0, %%esp\n"::"m"((char*)pos-256));
20 # else
21 #define SHIFTSP(pos) asm ( "mov %0, %%esp\n"::"m"((char*)pos+256));
22 # endif
23 #else
24 # ifdef QT_GROW_DOWN
25 #define SHIFTSP(pos) {char *osp=alloca(0); alloca((osp-((char*)pos))+256); }
26 # else
27 #define SHIFTSP(pos) {char *osp=alloca(0); alloca((((char*)pos)-osp)+256); }
28 # endif
29 #endif
30
31 #define MAXTABLE 1000
32 static void * pbuf[MAXTABLE] = {0};
33 static int    pcounter = 1;
34
35 static int push_buf(void *ptr)
36 {
37   int cur = pcounter;
38   pbuf[pcounter] = ptr;
39   pcounter++;
40   if (pcounter >= MAXTABLE) pcounter = 1;   /* reuse the table */
41   return cur;
42 }
43
44 static void qt_args_1(qt_t *rjb, void *u, void *t,
45                       qt_userf_t *userf, qt_only_t *only)
46 {
47   jmp_buf jb; struct helpdesc *rhelp;
48   int index;
49   index = setjmp(jb);
50   rhelp = (struct helpdesc *)pbuf[index];
51   if (rhelp == 0) {
52     SHIFTSP(rjb);
53     longjmp((unsigned long*)rjb, push_buf((void *)jb));
54   }
55   rhelp->hfn(rhelp->jb, rhelp->old, rhelp->new);
56   only(u, t, userf);
57   write(2,"Never get here 2.\n",18);
58 }
59
60 qt_t *qt_args(qt_t *sp, void *u, void *t,
61               qt_userf_t *userf, qt_only_t *only)
62 {
63   jmp_buf jb; qt_t *result;
64   int index;
65   index = setjmp(jb);
66   result = (qt_t*)pbuf[index];
67   if (result==0) {
68     SHIFTSP(sp);
69     qt_args_1((qt_t*)jb,u,t,userf,only);
70     write(2,"Never get here 1.\n",18);
71   }
72   return result;
73 }
74
75 void *qt_block(qt_helper_t *hfn, void *old, void *new, qt_t *sp)
76 {
77   struct helpdesc help, *rhelp; char *oldsp; int offs;
78   jmp_buf jb;
79   int index;
80   help.hfn = hfn;
81   help.jb  = (qt_t*)&jb;
82   help.old = old;
83   help.new = new;
84   index = setjmp(jb);
85   rhelp = (struct helpdesc *)pbuf[index];
86   if (rhelp==0) {
87     SHIFTSP(sp);
88     longjmp((unsigned long*)sp, push_buf((void *)&help));
89   }
90   rhelp->hfn(rhelp->jb, rhelp->old, rhelp->new);
91 }
92
93 void *qt_abort(qt_helper_t *hfn, void *old, void *new, qt_t *sp)
94 {
95   struct helpdesc help, *rhelp;
96   help.hfn = hfn;
97   help.jb  = (qt_t*)&help;
98   help.old = old;
99   help.new = new;
100   SHIFTSP(sp);
101   longjmp((unsigned long*)sp, push_buf((void *)&help));
102 }