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