generic64 did not work with SMP due to using a global pointer mapping table.
[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 #include "conv-config.h"
23
24 struct helpdesc { qt_helper_t *hfn; qt_t *jb; void *old; void *new; };
25
26 #ifdef __CYGWIN__
27 # ifdef QT_GROW_DOWN
28 #define SHIFTSP(pos) asm ( "mov %0, %%esp\n"::"m"((char*)pos-256));
29 # else
30 #define SHIFTSP(pos) asm ( "mov %0, %%esp\n"::"m"((char*)pos+256));
31 # endif
32 #else
33 # ifdef QT_GROW_DOWN
34 #define SHIFTSP(pos) {char *osp=alloca(0); alloca((osp-((char*)pos))+256); }
35 # else
36 #define SHIFTSP(pos) {char *osp=alloca(0); alloca((((char*)pos)-osp)+256); }
37 # endif
38 #endif
39
40 #define MAXTABLE 1000
41
42 #if CMK_SMP && CMK_TLS_THREAD
43 static __thread void * pbuf[MAXTABLE] = {0};
44 static __thread int    pcounter = 1;
45 #else
46 static void * pbuf[MAXTABLE] = {0};
47 static int    pcounter = 1;
48 #endif
49
50 static int push_buf(void *ptr)
51 {
52   int cur = pcounter;
53   pbuf[pcounter] = ptr;
54   pcounter++;
55   if (pcounter >= MAXTABLE) pcounter = 1;   /* reuse the table */
56   return cur;
57 }
58
59 static void qt_args_1(qt_t *rjb, void *u, void *t,
60                       qt_userf_t *userf, qt_only_t *only)
61 {
62   jmp_buf jb; struct helpdesc *rhelp;
63   int index;
64   index = _setjmp(jb);
65   rhelp = (struct helpdesc *)pbuf[index];
66   if (rhelp == 0) {
67     SHIFTSP(rjb);
68     _longjmp((unsigned long*)rjb, push_buf((void *)jb));
69   }
70   rhelp->hfn(rhelp->jb, rhelp->old, rhelp->new);
71   only(u, t, userf);
72   write(2,"Never get here 2.\n",18);
73 }
74
75 qt_t *qt_args(qt_t *sp, void *u, void *t,
76               qt_userf_t *userf, qt_only_t *only)
77 {
78   jmp_buf jb; qt_t *result;
79   int index;
80   index = _setjmp(jb);
81   result = (qt_t*)pbuf[index];
82   if (result==0) {
83     SHIFTSP(sp);
84     qt_args_1((qt_t*)jb,u,t,userf,only);
85     write(2,"Never get here 1.\n",18);
86   }
87   return result;
88 }
89
90 void *qt_block(qt_helper_t *hfn, void *old, void *new, qt_t *sp)
91 {
92   struct helpdesc help, *rhelp; char *oldsp; int offs;
93   jmp_buf jb;
94   int index;
95   help.hfn = hfn;
96   help.jb  = (qt_t*)&jb;
97   help.old = old;
98   help.new = new;
99   index = _setjmp(jb);
100   rhelp = (struct helpdesc *)pbuf[index];
101   if (rhelp==0) {
102     SHIFTSP(sp);
103     _longjmp((unsigned long*)sp, push_buf((void *)&help));
104   }
105   rhelp->hfn(rhelp->jb, rhelp->old, rhelp->new);
106 }
107
108 void *qt_abort(qt_helper_t *hfn, void *old, void *new, qt_t *sp)
109 {
110   struct helpdesc help, *rhelp;
111   help.hfn = hfn;
112   help.jb  = (qt_t*)&help;
113   help.old = old;
114   help.new = new;
115   SHIFTSP(sp);
116   _longjmp((unsigned long*)sp, push_buf((void *)&help));
117 }