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