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