disable compiler over-optimization on qt_args(), in which the SHIFTSP fails to move...
[charm.git] / src / QuickThreads / md / setjmp64_.c
1 /*
2 _setjmp/_longjmp is much light weighted than setjmp/longjmp
3 because it does not store signal mask, which is not a problem for netpoll
4 versions of charm.
5 */
6
7
8 #include "qt.h"
9 #include <setjmp.h>
10
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_HAS_TLS_VARIABLES
36 #define TLS_SPECIFIER         __thread
37 #else
38 #define TLS_SPECIFIER
39 #endif
40
41 static TLS_SPECIFIER void * pbuf[MAXTABLE] = {0};
42 static TLS_SPECIFIER int    pcounter = 1;
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, qt_userf_t *userf, qt_only_t *only)  __attribute__((optimize(0)));
70
71 qt_t *qt_args(qt_t *sp, void *u, void *t,
72               qt_userf_t *userf, qt_only_t *only)
73 {
74   jmp_buf jb; qt_t *result;
75   int index;
76   index = _setjmp(jb);
77   result = (qt_t*)pbuf[index];
78   if (result==0) {
79     SHIFTSP(sp);
80     qt_args_1((qt_t*)jb,u,t,userf,only);
81     write(2,"Never get here 1.\n",18);
82   }
83   return result;
84 }
85
86 void *qt_block(qt_helper_t *hfn, void *old, void *new, qt_t *sp)
87 {
88   struct helpdesc help, *rhelp; char *oldsp; int offs;
89   jmp_buf jb;
90   int index;
91   help.hfn = hfn;
92   help.jb  = (qt_t*)&jb;
93   help.old = old;
94   help.new = new;
95   index = _setjmp(jb);
96   rhelp = (struct helpdesc *)pbuf[index];
97   if (rhelp==0) {
98     SHIFTSP(sp);
99     _longjmp((unsigned long*)sp, push_buf((void *)&help));
100   }
101   rhelp->hfn(rhelp->jb, rhelp->old, rhelp->new);
102 }
103
104 void *qt_abort(qt_helper_t *hfn, void *old, void *new, qt_t *sp)
105 {
106   struct helpdesc help, *rhelp;
107   help.hfn = hfn;
108   help.jb  = (qt_t*)&help;
109   help.old = old;
110   help.new = new;
111   SHIFTSP(sp);
112   _longjmp((unsigned long*)sp, push_buf((void *)&help));
113 }