Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Newer
Older
100644 701 lines (631 sloc) 18.9 kB
aceee00 @JeffBezanson beginning of lightweight task (symmetric coroutine) support
JeffBezanson authored
1 /*
2 task.c
89ec3f0 @JeffBezanson making new GC the default
JeffBezanson authored
3 lightweight processes (symmetric coroutines)
aceee00 @JeffBezanson beginning of lightweight task (symmetric coroutine) support
JeffBezanson authored
4 */
5 #include <stdlib.h>
6 #include <string.h>
7 #include <setjmp.h>
8 #include <assert.h>
f24312d @Keno Windows Support
authored
9 //#include <sys/mman.h>
aceee00 @JeffBezanson beginning of lightweight task (symmetric coroutine) support
JeffBezanson authored
10 #include <signal.h>
11 #include <libgen.h>
12 #include <unistd.h>
00a43f5 @vtjnash stop overriding CFLAGS, CXXFLAGS, LDFLAGS and FFLAGS so they can be p…
vtjnash authored
13 #include <errno.h>
aceee00 @JeffBezanson beginning of lightweight task (symmetric coroutine) support
JeffBezanson authored
14 #include "julia.h"
dd89fc6 @JeffBezanson more code cleanup
JeffBezanson authored
15 #include "builtin_proto.h"
22a0823 @vtjnash backtrace on apple
vtjnash authored
16 #if defined(__APPLE__)
17 #include <execinfo.h>
f24312d @Keno Windows Support
authored
18 #elif defined(__WIN32__)
19 #include <Winbase.h>
4aa95ed @Keno Make Julia compile for Lang.Next talk
authored
20 #include <setjmp.h>
21 #define sigsetjmp(a,b) setjmp(a)
22 #define siglongjmp(a,b) longjmp(a,b)
22a0823 @vtjnash backtrace on apple
vtjnash authored
23 #else
3da86cd @JeffBezanson restoring stuff that seems to have been clobbered by the revert of the
JeffBezanson authored
24 // This gives unwind only local unwinding options ==> faster code
25 #define UNW_LOCAL_ONLY
26 #include <libunwind.h>
22a0823 @vtjnash backtrace on apple
vtjnash authored
27 #endif
aceee00 @JeffBezanson beginning of lightweight task (symmetric coroutine) support
JeffBezanson authored
28
29 /* This probing code is derived from Douglas Jones' user thread library */
30
31 /* true if stack grows up, false if down */
32 static int _stack_grows_up;
33
34 /* the offset of the beginning of the stack frame in a function */
35 static size_t _frame_offset;
36
37 struct _probe_data {
38 intptr_t low_bound; /* below probe on stack */
39 intptr_t probe_local; /* local to probe on stack */
40 intptr_t high_bound; /* above probe on stack */
41 intptr_t prior_local; /* value of probe_local from earlier call */
42
43 jmp_buf probe_env; /* saved environment of probe */
44 jmp_buf probe_sameAR; /* second environment saved by same call */
45 jmp_buf probe_samePC; /* environment saved on previous call */
46
47 jmp_buf * ref_probe; /* switches between probes */
48 };
49
50 static void boundhigh(struct _probe_data *p)
51 {
52 int c;
53 p->high_bound = (intptr_t)&c;
54 }
55
56 static void probe(struct _probe_data *p)
57 {
58 p->prior_local = p->probe_local;
1100fd3 @JeffBezanson some improvements to stack switching
JeffBezanson authored
59 p->probe_local = (intptr_t)&p;
752e1bd @vtjnash mostly fixing SIGINT and other signal handling so that everything wor…
vtjnash authored
60 sigsetjmp( *(p->ref_probe), 1 );
aceee00 @JeffBezanson beginning of lightweight task (symmetric coroutine) support
JeffBezanson authored
61 p->ref_probe = &p->probe_env;
752e1bd @vtjnash mostly fixing SIGINT and other signal handling so that everything wor…
vtjnash authored
62 sigsetjmp( p->probe_sameAR, 1 );
aceee00 @JeffBezanson beginning of lightweight task (symmetric coroutine) support
JeffBezanson authored
63 boundhigh(p);
64 }
65
66 static void boundlow(struct _probe_data *p)
67 {
48f089e @JeffBezanson some Task improvements
JeffBezanson authored
68 p->low_bound = (intptr_t)&p;
aceee00 @JeffBezanson beginning of lightweight task (symmetric coroutine) support
JeffBezanson authored
69 probe(p);
70 }
71
48f089e @JeffBezanson some Task improvements
JeffBezanson authored
72 // we need this function to exist so we can measure its stack frame!
73 static void fill(struct _probe_data *p) __attribute__ ((noinline));
aceee00 @JeffBezanson beginning of lightweight task (symmetric coroutine) support
JeffBezanson authored
74 static void fill(struct _probe_data *p)
75 {
76 boundlow(p);
77 }
78
79 static void _infer_direction_from(int *first_addr)
80 {
81 int second;
82 _stack_grows_up = (first_addr < &second);
83 }
84
9ae8a72 @StefanKarpinski Write zero-args C functions as foo(void) not foo().
StefanKarpinski authored
85 static void _infer_stack_direction(void)
aceee00 @JeffBezanson beginning of lightweight task (symmetric coroutine) support
JeffBezanson authored
86 {
87 int first;
88 _infer_direction_from(&first);
89 }
90
41afff5 @JeffBezanson trying to detect whether jmp_buf pointers are mangled
JeffBezanson authored
91 static int mangle_pointers;
92 extern char *jl_stack_lo;
93 extern char *jl_stack_hi;
94
9ae8a72 @StefanKarpinski Write zero-args C functions as foo(void) not foo().
StefanKarpinski authored
95 static void _probe_arch(void)
aceee00 @JeffBezanson beginning of lightweight task (symmetric coroutine) support
JeffBezanson authored
96 {
97 struct _probe_data p;
98 memset(p.probe_env, 0, sizeof(jmp_buf));
99 memset(p.probe_sameAR, 0, sizeof(jmp_buf));
100 memset(p.probe_samePC, 0, sizeof(jmp_buf));
101 p.ref_probe = &p.probe_samePC;
102
103 _infer_stack_direction();
104
105 /* do a probe with filler on stack */
106 fill(&p);
107 /* do a probe without filler */
108 boundlow(&p);
41afff5 @JeffBezanson trying to detect whether jmp_buf pointers are mangled
JeffBezanson authored
109
73c7aaf @ViralBShah Remove LINUX and MACOSX and use __linux and __APPLE__ instead.
ViralBShah authored
110 #if defined(__linux) && defined(__i386__)
ed25f95 @ViralBShah Fix unused variable compiler warnings. The warning in dirpath.c on mac
ViralBShah authored
111 char **s = (char**)p.ref_probe;
41afff5 @JeffBezanson trying to detect whether jmp_buf pointers are mangled
JeffBezanson authored
112 mangle_pointers = !(s[4] > jl_stack_lo &&
113 s[4] < jl_stack_hi);
73c7aaf @ViralBShah Remove LINUX and MACOSX and use __linux and __APPLE__ instead.
ViralBShah authored
114 #elif defined(__linux) && defined(__x86_64__)
ed25f95 @ViralBShah Fix unused variable compiler warnings. The warning in dirpath.c on mac
ViralBShah authored
115 char **s = (char**)p.ref_probe;
41afff5 @JeffBezanson trying to detect whether jmp_buf pointers are mangled
JeffBezanson authored
116 mangle_pointers = !(s[6] > jl_stack_lo &&
117 s[6] < jl_stack_hi);
118 #else
119 mangle_pointers = 0;
120 #endif
121
dd89fc6 @JeffBezanson more code cleanup
JeffBezanson authored
122 intptr_t prior_diff = p.probe_local - p.prior_local;
abdfb2a @Keno remove extra bytes from _frame_offset that were leftover from testing
authored
123 _frame_offset = labs(prior_diff);
aceee00 @JeffBezanson beginning of lightweight task (symmetric coroutine) support
JeffBezanson authored
124 }
125
126 /* end probing code */
127
7ef1943 @JeffBezanson adding task_done
JeffBezanson authored
128 /*
129 TODO:
130 - per-task storage (scheme-like parameters)
131 - stack growth
132 */
133
a3f9f80 @JeffBezanson making stack overflow detection work for task stacks
JeffBezanson authored
134 extern size_t jl_page_size;
aceee00 @JeffBezanson beginning of lightweight task (symmetric coroutine) support
JeffBezanson authored
135 jl_struct_type_t *jl_task_type;
93b517b @ViralBShah Create a separate ui directory.
ViralBShah authored
136 DLLEXPORT jl_task_t * volatile jl_current_task;
5199c5a @JeffBezanson integrating exceptions with tasks
JeffBezanson authored
137 jl_task_t *jl_root_task;
f44d268 @JeffBezanson alternate implementation of Tasks using stack copying, enable by defi…
JeffBezanson authored
138 jl_value_t * volatile jl_task_arg_in_transit;
0ba7724 @JeffBezanson adding the ability to yield multiple values, and yield values on the
JeffBezanson authored
139 static volatile int n_args_in_transit;
6dfa652 @JeffBezanson adding exceptions and exception handling
JeffBezanson authored
140 jl_value_t *jl_exception_in_transit;
ab77974 @JeffBezanson converting alloc.c for new GC
JeffBezanson authored
141 #ifdef JL_GC_MARKSWEEP
e6ca48c @JeffBezanson more efficient GC frame pointer handling
JeffBezanson authored
142 jl_gcframe_t *jl_pgcstack = NULL;
ab77974 @JeffBezanson converting alloc.c for new GC
JeffBezanson authored
143 #endif
aceee00 @JeffBezanson beginning of lightweight task (symmetric coroutine) support
JeffBezanson authored
144
f44d268 @JeffBezanson alternate implementation of Tasks using stack copying, enable by defi…
JeffBezanson authored
145 static void start_task(jl_task_t *t);
146
147 #ifdef COPY_STACKS
148 jmp_buf * volatile jl_jmp_target;
149
150 static void save_stack(jl_task_t *t)
151 {
152 volatile int _x;
153 size_t nb = (char*)t->stackbase - (char*)&_x;
154 char *buf;
155 if (t->stkbuf == NULL || t->bufsz < nb) {
e6ca48c @JeffBezanson more efficient GC frame pointer handling
JeffBezanson authored
156 buf = allocb(nb);
f44d268 @JeffBezanson alternate implementation of Tasks using stack copying, enable by defi…
JeffBezanson authored
157 t->stkbuf = buf;
158 t->bufsz = nb;
159 }
160 else {
161 buf = t->stkbuf;
162 }
163 t->ssize = nb;
164 memcpy(buf, (char*)&_x, nb);
165 }
166
167 static void restore_stack(jl_task_t *t, jmp_buf *where)
168 {
12ceb84 @JeffBezanson prevent DisconnectException from looping on client
JeffBezanson authored
169 volatile int _x[64];
f44d268 @JeffBezanson alternate implementation of Tasks using stack copying, enable by defi…
JeffBezanson authored
170
7fb3136 @vtjnash fix debug build on Mac (and possibly others) due to an occasional sta…
vtjnash authored
171 if ((char*)&_x[64] > (char*)(t->stackbase-t->ssize)) {
f44d268 @JeffBezanson alternate implementation of Tasks using stack copying, enable by defi…
JeffBezanson authored
172 restore_stack(t, where);
173 }
174 jl_jmp_target = where;
175 if (t->stkbuf != NULL) {
176 memcpy(t->stackbase-t->ssize, t->stkbuf, t->ssize);
177 }
752e1bd @vtjnash mostly fixing SIGINT and other signal handling so that everything wor…
vtjnash authored
178 siglongjmp(*jl_jmp_target, 1);
f44d268 @JeffBezanson alternate implementation of Tasks using stack copying, enable by defi…
JeffBezanson authored
179 }
180
181 static void switch_stack(jl_task_t *t, jmp_buf *where)
182 {
183 assert(t == jl_current_task);
184 if (t->stkbuf == NULL) {
185 start_task(t);
186 // doesn't return
187 }
188 else {
189 restore_stack(t, where);
190 }
191 }
192
193 void jl_switch_stack(jl_task_t *t, jmp_buf *where)
194 {
195 switch_stack(t, where);
196 }
197 #endif
198
498b3ab @JeffBezanson exiting tasks on exceptions when appropriate, preventing crashes
JeffBezanson authored
199 static void ctx_switch(jl_task_t *t, jmp_buf *where)
aceee00 @JeffBezanson beginning of lightweight task (symmetric coroutine) support
JeffBezanson authored
200 {
f44d268 @JeffBezanson alternate implementation of Tasks using stack copying, enable by defi…
JeffBezanson authored
201 if (t == jl_current_task)
202 return;
be5f581 @JeffBezanson adding a ctrl-C (SIGINT) handler, starting work on issue #26.
JeffBezanson authored
203 /*
204 making task switching interrupt-safe is going to be challenging.
205 we need JL_SIGATOMIC_BEGIN in jl_enter_handler, and then
752e1bd @vtjnash mostly fixing SIGINT and other signal handling so that everything wor…
vtjnash authored
206 JL_SIGATOMIC_END after every JL_TRY sigsetjmp that returns zero.
be5f581 @JeffBezanson adding a ctrl-C (SIGINT) handler, starting work on issue #26.
JeffBezanson authored
207 also protect jl_eh_restore_state.
208 then we need JL_SIGATOMIC_BEGIN at the top of this function (ctx_switch).
209 the JL_SIGATOMIC_END at the end of this function handles the case
210 of task switching with yieldto().
211 then we need to handle the case of task switching via raise().
212 to do that, the top of every catch block must do JL_SIGATOMIC_END
213 *IF AND ONLY IF* throwing the exception involved a task switch.
214 */
215 //JL_SIGATOMIC_BEGIN();
752e1bd @vtjnash mostly fixing SIGINT and other signal handling so that everything wor…
vtjnash authored
216 if (!sigsetjmp(jl_current_task->ctx, 1)) {
f44d268 @JeffBezanson alternate implementation of Tasks using stack copying, enable by defi…
JeffBezanson authored
217 #ifdef COPY_STACKS
218 jl_task_t *lastt = jl_current_task;
511f902 @JeffBezanson fixing a GC bug in task switching
JeffBezanson authored
219 save_stack(lastt);
bdc1b3b @JeffBezanson using less memory by freeing some llvm objects
JeffBezanson authored
220 #endif
f44d268 @JeffBezanson alternate implementation of Tasks using stack copying, enable by defi…
JeffBezanson authored
221
222 // set up global state for new task
ab77974 @JeffBezanson converting alloc.c for new GC
JeffBezanson authored
223 #ifdef JL_GC_MARKSWEEP
e6ca48c @JeffBezanson more efficient GC frame pointer handling
JeffBezanson authored
224 jl_current_task->state.gcstack = jl_pgcstack;
225 jl_pgcstack = t->state.gcstack;
ab77974 @JeffBezanson converting alloc.c for new GC
JeffBezanson authored
226 #endif
e6ca48c @JeffBezanson more efficient GC frame pointer handling
JeffBezanson authored
227 jl_current_task = t;
f44d268 @JeffBezanson alternate implementation of Tasks using stack copying, enable by defi…
JeffBezanson authored
228
229 #ifdef COPY_STACKS
230 jl_jmp_target = where;
752e1bd @vtjnash mostly fixing SIGINT and other signal handling so that everything wor…
vtjnash authored
231 siglongjmp(lastt->base_ctx, 1);
f44d268 @JeffBezanson alternate implementation of Tasks using stack copying, enable by defi…
JeffBezanson authored
232 #else
752e1bd @vtjnash mostly fixing SIGINT and other signal handling so that everything wor…
vtjnash authored
233 siglongjmp(*where, 1);
f44d268 @JeffBezanson alternate implementation of Tasks using stack copying, enable by defi…
JeffBezanson authored
234 #endif
aceee00 @JeffBezanson beginning of lightweight task (symmetric coroutine) support
JeffBezanson authored
235 }
be5f581 @JeffBezanson adding a ctrl-C (SIGINT) handler, starting work on issue #26.
JeffBezanson authored
236 //JL_SIGATOMIC_END();
498b3ab @JeffBezanson exiting tasks on exceptions when appropriate, preventing crashes
JeffBezanson authored
237 }
238
239 static jl_value_t *switchto(jl_task_t *t)
240 {
367ecee @JeffBezanson misc. tweaks: making current_task and task_done more first-class,
JeffBezanson authored
241 if (t->done==jl_true) {
f44d268 @JeffBezanson alternate implementation of Tasks using stack copying, enable by defi…
JeffBezanson authored
242 jl_task_arg_in_transit = (jl_value_t*)jl_null;
498b3ab @JeffBezanson exiting tasks on exceptions when appropriate, preventing crashes
JeffBezanson authored
243 return t->result;
244 }
245 ctx_switch(t, &t->ctx);
f44d268 @JeffBezanson alternate implementation of Tasks using stack copying, enable by defi…
JeffBezanson authored
246 jl_value_t *val = jl_task_arg_in_transit;
247 jl_task_arg_in_transit = (jl_value_t*)jl_null;
0ba7724 @JeffBezanson adding the ability to yield multiple values, and yield values on the
JeffBezanson authored
248 return val;
249 }
250
f44d268 @JeffBezanson alternate implementation of Tasks using stack copying, enable by defi…
JeffBezanson authored
251 #ifndef COPY_STACKS
5199c5a @JeffBezanson integrating exceptions with tasks
JeffBezanson authored
252
73c7aaf @ViralBShah Remove LINUX and MACOSX and use __linux and __APPLE__ instead.
ViralBShah authored
253 #ifdef __linux
a604729 @ViralBShah Use __x86_64__ and __i386__ instead of ARCH_X86_64 and ARCH_X86.
ViralBShah authored
254 #if defined(__i386__)
8a39dcb @JeffBezanson attempting linux 64 and darwin 32/64 stack switching
JeffBezanson authored
255 static intptr_t ptr_mangle(intptr_t p)
aceee00 @JeffBezanson beginning of lightweight task (symmetric coroutine) support
JeffBezanson authored
256 {
8a39dcb @JeffBezanson attempting linux 64 and darwin 32/64 stack switching
JeffBezanson authored
257 intptr_t ret;
aceee00 @JeffBezanson beginning of lightweight task (symmetric coroutine) support
JeffBezanson authored
258 asm(" movl %1, %%eax;\n"
259 " xorl %%gs:0x18, %%eax;"
8a39dcb @JeffBezanson attempting linux 64 and darwin 32/64 stack switching
JeffBezanson authored
260 " roll $9, %%eax;"
aceee00 @JeffBezanson beginning of lightweight task (symmetric coroutine) support
JeffBezanson authored
261 " movl %%eax, %0;"
8a39dcb @JeffBezanson attempting linux 64 and darwin 32/64 stack switching
JeffBezanson authored
262 : "=r"(ret) : "r"(p) : "%eax");
aceee00 @JeffBezanson beginning of lightweight task (symmetric coroutine) support
JeffBezanson authored
263 return ret;
264 }
8a39dcb @JeffBezanson attempting linux 64 and darwin 32/64 stack switching
JeffBezanson authored
265 static intptr_t ptr_demangle(intptr_t p)
aceee00 @JeffBezanson beginning of lightweight task (symmetric coroutine) support
JeffBezanson authored
266 {
8a39dcb @JeffBezanson attempting linux 64 and darwin 32/64 stack switching
JeffBezanson authored
267 intptr_t ret;
aceee00 @JeffBezanson beginning of lightweight task (symmetric coroutine) support
JeffBezanson authored
268 asm(" movl %1, %%eax;\n"
8a39dcb @JeffBezanson attempting linux 64 and darwin 32/64 stack switching
JeffBezanson authored
269 " rorl $9, %%eax;"
aceee00 @JeffBezanson beginning of lightweight task (symmetric coroutine) support
JeffBezanson authored
270 " xorl %%gs:0x18, %%eax;"
271 " movl %%eax, %0;"
8a39dcb @JeffBezanson attempting linux 64 and darwin 32/64 stack switching
JeffBezanson authored
272 : "=r"(ret) : "r"(p) : "%eax" );
273 return ret;
274 }
a604729 @ViralBShah Use __x86_64__ and __i386__ instead of ARCH_X86_64 and ARCH_X86.
ViralBShah authored
275 #elif defined(__x86_64__)
8a39dcb @JeffBezanson attempting linux 64 and darwin 32/64 stack switching
JeffBezanson authored
276 static intptr_t ptr_mangle(intptr_t p)
277 {
278 intptr_t ret;
279 asm(" movq %1, %%rax;\n"
280 " xorq %%fs:0x30, %%rax;"
281 " rolq $17, %%rax;"
282 " movq %%rax, %0;"
283 : "=r"(ret) : "r"(p) : "%rax");
284 return ret;
285 }
286 static intptr_t ptr_demangle(intptr_t p)
287 {
288 intptr_t ret;
289 asm(" movq %1, %%rax;\n"
290 " rorq $17, %%rax;"
291 " xorq %%fs:0x30, %%rax;"
292 " movq %%rax, %0;"
293 : "=r"(ret) : "r"(p) : "%rax" );
aceee00 @JeffBezanson beginning of lightweight task (symmetric coroutine) support
JeffBezanson authored
294 return ret;
295 }
296 #endif
73c7aaf @ViralBShah Remove LINUX and MACOSX and use __linux and __APPLE__ instead.
ViralBShah authored
297 #endif //__linux
aceee00 @JeffBezanson beginning of lightweight task (symmetric coroutine) support
JeffBezanson authored
298
299 /* rebase any values in saved state to the new stack */
300 static void rebase_state(jmp_buf *ctx, intptr_t local_sp, intptr_t new_sp)
301 {
302 ptrint_t *s = (ptrint_t*)ctx;
303 ptrint_t diff = new_sp - local_sp; /* subtract old base, and add new base */
73c7aaf @ViralBShah Remove LINUX and MACOSX and use __linux and __APPLE__ instead.
ViralBShah authored
304 #if defined(__linux) && defined(__i386__)
aceee00 @JeffBezanson beginning of lightweight task (symmetric coroutine) support
JeffBezanson authored
305 s[3] += diff;
41afff5 @JeffBezanson trying to detect whether jmp_buf pointers are mangled
JeffBezanson authored
306 if (mangle_pointers)
307 s[4] = ptr_mangle(ptr_demangle(s[4])+diff);
308 else
309 s[4] += diff;
73c7aaf @ViralBShah Remove LINUX and MACOSX and use __linux and __APPLE__ instead.
ViralBShah authored
310 #elif defined(__linux) && defined(__x86_64__)
41afff5 @JeffBezanson trying to detect whether jmp_buf pointers are mangled
JeffBezanson authored
311 if (mangle_pointers) {
312 s[1] = ptr_mangle(ptr_demangle(s[1])+diff);
313 s[6] = ptr_mangle(ptr_demangle(s[6])+diff);
314 }
315 else {
316 s[1] += diff;
317 s[6] += diff;
318 }
73c7aaf @ViralBShah Remove LINUX and MACOSX and use __linux and __APPLE__ instead.
ViralBShah authored
319 #elif defined(__APPLE__) && defined(__i386__)
8a39dcb @JeffBezanson attempting linux 64 and darwin 32/64 stack switching
JeffBezanson authored
320 s[8] += diff;
321 s[9] += diff;
73c7aaf @ViralBShah Remove LINUX and MACOSX and use __linux and __APPLE__ instead.
ViralBShah authored
322 #elif defined(__APPLE__) && defined(__x86_64__)
8a39dcb @JeffBezanson attempting linux 64 and darwin 32/64 stack switching
JeffBezanson authored
323 s[1] += diff;
324 s[2] += diff;
1100fd3 @JeffBezanson some improvements to stack switching
JeffBezanson authored
325 #else
dd89fc6 @JeffBezanson more code cleanup
JeffBezanson authored
326 #error "COPY_STACKS must be defined on this platform."
1100fd3 @JeffBezanson some improvements to stack switching
JeffBezanson authored
327 #endif
aceee00 @JeffBezanson beginning of lightweight task (symmetric coroutine) support
JeffBezanson authored
328 }
329
f44d268 @JeffBezanson alternate implementation of Tasks using stack copying, enable by defi…
JeffBezanson authored
330 #endif /* !COPY_STACKS */
331
332 jl_value_t *jl_switchto(jl_task_t *t, jl_value_t *arg)
333 {
334 jl_task_arg_in_transit = arg;
335 n_args_in_transit = 1;
336 return switchto(t);
337 }
338
339 static void finish_task(jl_task_t *t, jl_value_t *resultval)
340 {
367ecee @JeffBezanson misc. tweaks: making current_task and task_done more first-class,
JeffBezanson authored
341 assert(t->done==jl_false);
342 t->done = jl_true;
f44d268 @JeffBezanson alternate implementation of Tasks using stack copying, enable by defi…
JeffBezanson authored
343 t->result = resultval;
97a9145 @JeffBezanson simplifying some of the REPL and Task stuff
JeffBezanson authored
344 // TODO: early free of t->stkbuf
345 #ifdef COPY_STACKS
346 t->stkbuf = NULL;
347 #endif
f44d268 @JeffBezanson alternate implementation of Tasks using stack copying, enable by defi…
JeffBezanson authored
348 }
349
350 static void start_task(jl_task_t *t)
351 {
0735209 @JeffBezanson another fix to new task stacks: I wasn't copying enough
JeffBezanson authored
352 // this runs the first time we switch to t
353 jl_value_t *arg = jl_task_arg_in_transit;
354 jl_value_t *res;
355 JL_GC_PUSH(&arg);
356
f44d268 @JeffBezanson alternate implementation of Tasks using stack copying, enable by defi…
JeffBezanson authored
357 #ifdef COPY_STACKS
e6ca48c @JeffBezanson more efficient GC frame pointer handling
JeffBezanson authored
358 ptrint_t local_sp = (ptrint_t)jl_pgcstack;
0735209 @JeffBezanson another fix to new task stacks: I wasn't copying enough
JeffBezanson authored
359 // here we attempt to figure out how big our stack frame is, since we
360 // might need to copy all of it later. this is a bit of a fuzzy guess.
361 local_sp += sizeof(jl_gcframe_t);
362 local_sp += 12*sizeof(void*);
f44d268 @JeffBezanson alternate implementation of Tasks using stack copying, enable by defi…
JeffBezanson authored
363 t->stackbase = (void*)(local_sp + _frame_offset);
752e1bd @vtjnash mostly fixing SIGINT and other signal handling so that everything wor…
vtjnash authored
364 if (sigsetjmp(t->base_ctx, 1)) {
f44d268 @JeffBezanson alternate implementation of Tasks using stack copying, enable by defi…
JeffBezanson authored
365 // we get here to remove our data from the process stack
366 switch_stack(jl_current_task, jl_jmp_target);
367 }
368 #endif
369 if (n_args_in_transit == 0) {
370 res = jl_apply(t->start, NULL, 0);
371 }
372 else if (n_args_in_transit == 1) {
373 res = jl_apply(t->start, &arg, 1);
374 }
375 else {
376 assert(jl_is_tuple(jl_task_arg_in_transit));
377 res = jl_apply(t->start, &jl_tupleref(jl_task_arg_in_transit,0),
378 n_args_in_transit);
379 }
380 JL_GC_POP();
381 finish_task(t, res);
382 jl_task_t *cont = t->on_exit;
383 // if parent task has exited, try its parent, and so on
367ecee @JeffBezanson misc. tweaks: making current_task and task_done more first-class,
JeffBezanson authored
384 while (cont->done==jl_true)
f44d268 @JeffBezanson alternate implementation of Tasks using stack copying, enable by defi…
JeffBezanson authored
385 cont = cont->on_exit;
386 jl_switchto(cont, t->result);
387 assert(0);
388 }
389
390 #ifndef COPY_STACKS
aceee00 @JeffBezanson beginning of lightweight task (symmetric coroutine) support
JeffBezanson authored
391 static void init_task(jl_task_t *t)
392 {
4aa95ed @Keno Make Julia compile for Lang.Next talk
authored
393 if (sigsetjmp(t->ctx, 1)) {
f44d268 @JeffBezanson alternate implementation of Tasks using stack copying, enable by defi…
JeffBezanson authored
394 start_task(t);
aceee00 @JeffBezanson beginning of lightweight task (symmetric coroutine) support
JeffBezanson authored
395 }
1100fd3 @JeffBezanson some improvements to stack switching
JeffBezanson authored
396 // this runs when the task is created
397 ptrint_t local_sp = (ptrint_t)&t;
398 ptrint_t new_sp = (ptrint_t)t->stack + t->ssize - _frame_offset;
400efce Use __LP64__ instead of BITS64
Viral Shah authored
399 #ifdef __LP64__
9703fca @JeffBezanson fixing some 64-bit issues. stack pointer needed to be aligned
JeffBezanson authored
400 // SP must be 16-byte aligned
401 new_sp = new_sp&-16;
402 local_sp = local_sp&-16;
403 #endif
1100fd3 @JeffBezanson some improvements to stack switching
JeffBezanson authored
404 memcpy((void*)new_sp, (void*)local_sp, _frame_offset);
aceee00 @JeffBezanson beginning of lightweight task (symmetric coroutine) support
JeffBezanson authored
405 rebase_state(&t->ctx, local_sp, new_sp);
406 }
f44d268 @JeffBezanson alternate implementation of Tasks using stack copying, enable by defi…
JeffBezanson authored
407 #endif
408
0c9464a @zingales Added features to print filenames.
zingales authored
409 void getFunctionInfo(char **name, int *line, const char **filename, size_t pointer);
b1f3d37 @JeffBezanson reporting un-mangled function names
JeffBezanson authored
410
50c4bdd @JeffBezanson abstracting common code in the two backtraces, and removing unused ba…
JeffBezanson authored
411 static void push_frame_info_from_ip(jl_array_t *a, size_t ip)
412 {
413 char *func_name;
414 int line_num;
415 const char *file_name;
416 int i = jl_array_len(a);
417 getFunctionInfo(&func_name, &line_num, &file_name, ip);
418 if (func_name != NULL) {
419 jl_array_grow_end(a, 3);
420 jl_arrayset(a, i, (jl_value_t*)jl_symbol(func_name)); i++;
421 jl_arrayset(a, i, (jl_value_t*)jl_symbol(file_name)); i++;
422 jl_arrayset(a, i, jl_box_long(line_num));
423 }
424 }
425
22a0823 @vtjnash backtrace on apple
vtjnash authored
426 #if defined(__APPLE__)
427 // stacktrace using execinfo
428 static jl_value_t *build_backtrace(void)
429 {
50c4bdd @JeffBezanson abstracting common code in the two backtraces, and removing unused ba…
JeffBezanson authored
430 void *array[1024];
431 size_t ip;
432 size_t *p;
22a0823 @vtjnash backtrace on apple
vtjnash authored
433 jl_array_t *a;
434 a = jl_alloc_cell_1d(0);
435 JL_GC_PUSH(&a);
50c4bdd @JeffBezanson abstracting common code in the two backtraces, and removing unused ba…
JeffBezanson authored
436
437 backtrace(array, 1023);
dd501da @StefanKarpinski Avoid compiler warning in src/task.c.
StefanKarpinski authored
438 p = (size_t*)array;
50c4bdd @JeffBezanson abstracting common code in the two backtraces, and removing unused ba…
JeffBezanson authored
439 while ((ip = *(p++)) != 0) {
440 push_frame_info_from_ip(a, ip);
22a0823 @vtjnash backtrace on apple
vtjnash authored
441 }
442 JL_GC_POP();
443 return (jl_value_t*)a;
444 }
f24312d @Keno Windows Support
authored
445 #elif defined(__WIN32__)
446 static jl_value_t *build_backtrace(void)
447 {
448 void *array[1024];
449 size_t ip;
450 size_t *p;
451 jl_array_t *a;
452 unsigned short num;
453 a = jl_alloc_cell_1d(0);
454 JL_GC_PUSH(&a);
455
456 /** MINGW does not have the necessary declarations for linking CaptureStackBackTrace*/
457 #if defined(__MINGW_H)
458 HINSTANCE kernel32 = LoadLibrary("Kernel32.dll");
459
460 if(kernel32 != NULL){
461 typedef USHORT (*CaptureStackBackTraceType)(ULONG FramesToSkip, ULONG FramesToCapture, void* BackTrace, ULONG* BackTraceHash);
462 CaptureStackBackTraceType func = (CaptureStackBackTraceType) GetProcAddress( kernel32, "RtlCaptureStackBackTrace" );
463
464 if(func==NULL){
465 FreeLibrary(kernel32);
466 kernel32 = NULL;
467 func = NULL;
468 return (jl_value_t*)a;
469 }else
470 {
471 num = func( 0, 1023, array, NULL );
472 }
4db29df @Keno Fix compiler warnings during build on windows
authored
473 }else
474 {
475 jl_puts("Failed to load kernel32.dll",jl_stderr_tty);
476 jl_exit(1);
477 }
f24312d @Keno Windows Support
authored
478 FreeLibrary(kernel32);
479 #else
480 num = RtlCaptureStackBackTrace(0, 1023, array, NULL);
481 #endif
482
483 p = (size_t*)array;
484 while ((ip = *(p++)) != 0 && (num--)>0) {
485 push_frame_info_from_ip(a, ip);
486 }
487 JL_GC_POP();
488 return (jl_value_t*)a;
489 }
22a0823 @vtjnash backtrace on apple
vtjnash authored
490 #else
b1f3d37 @JeffBezanson reporting un-mangled function names
JeffBezanson authored
491 // stacktrace using libunwind
9ae8a72 @StefanKarpinski Write zero-args C functions as foo(void) not foo().
StefanKarpinski authored
492 static jl_value_t *build_backtrace(void)
3d4684e @JeffBezanson construct a BackTrace object for the repl exception handler so it can
JeffBezanson authored
493 {
494 unw_cursor_t cursor; unw_context_t uc;
b1f3d37 @JeffBezanson reporting un-mangled function names
JeffBezanson authored
495 unw_word_t ip;
496 jl_array_t *a;
bb5bb15 @JeffBezanson putting a limit on stack backtrace size.
JeffBezanson authored
497 size_t n=0;
b1f3d37 @JeffBezanson reporting un-mangled function names
JeffBezanson authored
498 a = jl_alloc_cell_1d(0);
499 JL_GC_PUSH(&a);
3d4684e @JeffBezanson construct a BackTrace object for the repl exception handler so it can
JeffBezanson authored
500
501 unw_getcontext(&uc);
502 unw_init_local(&cursor, &uc);
bb5bb15 @JeffBezanson putting a limit on stack backtrace size.
JeffBezanson authored
503 while (unw_step(&cursor) && n < 10000) {
3d4684e @JeffBezanson construct a BackTrace object for the repl exception handler so it can
JeffBezanson authored
504 unw_get_reg(&cursor, UNW_REG_IP, &ip);
50c4bdd @JeffBezanson abstracting common code in the two backtraces, and removing unused ba…
JeffBezanson authored
505 push_frame_info_from_ip(a, ip);
bb5bb15 @JeffBezanson putting a limit on stack backtrace size.
JeffBezanson authored
506 n++;
3d4684e @JeffBezanson construct a BackTrace object for the repl exception handler so it can
JeffBezanson authored
507 }
b1f3d37 @JeffBezanson reporting un-mangled function names
JeffBezanson authored
508 JL_GC_POP();
509 return (jl_value_t*)a;
510 }
22a0823 @vtjnash backtrace on apple
vtjnash authored
511 #endif
b1f3d37 @JeffBezanson reporting un-mangled function names
JeffBezanson authored
512
9ae8a72 @StefanKarpinski Write zero-args C functions as foo(void) not foo().
StefanKarpinski authored
513 DLLEXPORT void jl_register_toplevel_eh(void)
3d4684e @JeffBezanson construct a BackTrace object for the repl exception handler so it can
JeffBezanson authored
514 {
4b2c388 @JeffBezanson fixing backtrace issue from request #456
JeffBezanson authored
515 jl_current_task->state.eh_task->state.bt = 1;
3d4684e @JeffBezanson construct a BackTrace object for the repl exception handler so it can
JeffBezanson authored
516 }
517
67943ac @Keno Linux support. Still weired errors
authored
518
519
f44d268 @JeffBezanson alternate implementation of Tasks using stack copying, enable by defi…
JeffBezanson authored
520 // yield to exception handler
521 void jl_raise(jl_value_t *e)
522 {
523 jl_task_t *eh = jl_current_task->state.eh_task;
524 eh->state.err = 1;
525 jl_exception_in_transit = e;
4b2c388 @JeffBezanson fixing backtrace issue from request #456
JeffBezanson authored
526 if (eh->state.bt) {
3d4684e @JeffBezanson construct a BackTrace object for the repl exception handler so it can
JeffBezanson authored
527 jl_value_t *tracedata, *bt;
528 tracedata = build_backtrace();
529 JL_GC_PUSH(&tracedata);
bb5bb15 @JeffBezanson putting a limit on stack backtrace size.
JeffBezanson authored
530 bt = jl_new_struct(jl_backtrace_type,
531 jl_exception_in_transit, tracedata);
3d4684e @JeffBezanson construct a BackTrace object for the repl exception handler so it can
JeffBezanson authored
532 jl_exception_in_transit = bt;
533 JL_GC_POP();
534 }
b8a0d11 @Keno Starts up, but printing causes exception
authored
535 if (jl_current_task == eh&&eh->state.eh_ctx!=0) {
752e1bd @vtjnash mostly fixing SIGINT and other signal handling so that everything wor…
vtjnash authored
536 siglongjmp(*eh->state.eh_ctx, 1);
f44d268 @JeffBezanson alternate implementation of Tasks using stack copying, enable by defi…
JeffBezanson authored
537 }
538 else {
367ecee @JeffBezanson misc. tweaks: making current_task and task_done more first-class,
JeffBezanson authored
539 if (eh->done==jl_true || eh->state.eh_ctx==NULL) {
f44d268 @JeffBezanson alternate implementation of Tasks using stack copying, enable by defi…
JeffBezanson authored
540 // our handler is not available, use root task
6d49a61 @Keno Async IO. Crashes the debugger though...
authored
541 jl_printf(jl_stderr_tty, "warning: exception handler exited\n");
f44d268 @JeffBezanson alternate implementation of Tasks using stack copying, enable by defi…
JeffBezanson authored
542 eh = jl_root_task;
543 }
544 // for now, exit the task
545 finish_task(jl_current_task, e);
546 ctx_switch(eh, eh->state.eh_ctx);
547 // TODO: continued exception
548 }
4db29df @Keno Fix compiler warnings during build on windows
authored
549 jl_exit(1);
f44d268 @JeffBezanson alternate implementation of Tasks using stack copying, enable by defi…
JeffBezanson authored
550 }
aceee00 @JeffBezanson beginning of lightweight task (symmetric coroutine) support
JeffBezanson authored
551
6898aaf @JeffBezanson add the option of specifying a stack size when creating a Task
JeffBezanson authored
552 jl_task_t *jl_new_task(jl_function_t *start, size_t ssize)
aceee00 @JeffBezanson beginning of lightweight task (symmetric coroutine) support
JeffBezanson authored
553 {
a3f9f80 @JeffBezanson making stack overflow detection work for task stacks
JeffBezanson authored
554 size_t pagesz = jl_page_size;
4359a35 @JeffBezanson squeezing out the GC's 1 word of overhead for small objects
JeffBezanson authored
555 jl_task_t *t = (jl_task_t*)allocobj(sizeof(jl_task_t));
aceee00 @JeffBezanson beginning of lightweight task (symmetric coroutine) support
JeffBezanson authored
556 t->type = (jl_type_t*)jl_task_type;
a3f9f80 @JeffBezanson making stack overflow detection work for task stacks
JeffBezanson authored
557 ssize = LLT_ALIGN(ssize, pagesz);
6898aaf @JeffBezanson add the option of specifying a stack size when creating a Task
JeffBezanson authored
558 t->ssize = ssize;
aceee00 @JeffBezanson beginning of lightweight task (symmetric coroutine) support
JeffBezanson authored
559 t->on_exit = jl_current_task;
93760d9 @JeffBezanson sharing TLS in nested Tasks by default, but not for asynchronous comp…
JeffBezanson authored
560 t->tls = jl_current_task->tls;
367ecee @JeffBezanson misc. tweaks: making current_task and task_done more first-class,
JeffBezanson authored
561 t->done = jl_false;
aceee00 @JeffBezanson beginning of lightweight task (symmetric coroutine) support
JeffBezanson authored
562 t->start = start;
7e07f59 @JeffBezanson fixes related to new GC. mostly making sure all objects are thoroughly
JeffBezanson authored
563 t->result = NULL;
5199c5a @JeffBezanson integrating exceptions with tasks
JeffBezanson authored
564 t->state.err = 0;
4b2c388 @JeffBezanson fixing backtrace issue from request #456
JeffBezanson authored
565 t->state.bt = 0;
5199c5a @JeffBezanson integrating exceptions with tasks
JeffBezanson authored
566 t->state.eh_task = jl_current_task->state.eh_task;
567 // there is no active exception handler available on this stack yet
568 t->state.eh_ctx = NULL;
1512535 @JeffBezanson fixing memory management issues with I/O
JeffBezanson authored
569 t->state.ostream_obj = jl_current_task->state.ostream_obj;
5199c5a @JeffBezanson integrating exceptions with tasks
JeffBezanson authored
570 t->state.current_output_stream = jl_current_task->state.current_output_stream;
1512535 @JeffBezanson fixing memory management issues with I/O
JeffBezanson authored
571 t->state.prev = NULL;
ac0ed78 @JeffBezanson fix to last checkin on local decls.
JeffBezanson authored
572 #ifdef JL_GC_MARKSWEEP
573 t->state.gcstack = NULL;
574 #endif
f44d268 @JeffBezanson alternate implementation of Tasks using stack copying, enable by defi…
JeffBezanson authored
575 t->stkbuf = NULL;
aceee00 @JeffBezanson beginning of lightweight task (symmetric coroutine) support
JeffBezanson authored
576
f44d268 @JeffBezanson alternate implementation of Tasks using stack copying, enable by defi…
JeffBezanson authored
577 #ifdef COPY_STACKS
578 t->bufsz = 0;
579 #else
4932043 @JeffBezanson converting more files for new GC
JeffBezanson authored
580 JL_GC_PUSH(&t);
f44d268 @JeffBezanson alternate implementation of Tasks using stack copying, enable by defi…
JeffBezanson authored
581
4932043 @JeffBezanson converting more files for new GC
JeffBezanson authored
582 char *stk = allocb(ssize+pagesz+(pagesz-1));
f44d268 @JeffBezanson alternate implementation of Tasks using stack copying, enable by defi…
JeffBezanson authored
583 t->stkbuf = stk;
4932043 @JeffBezanson converting more files for new GC
JeffBezanson authored
584 stk = (char*)LLT_ALIGN((uptrint_t)stk, pagesz);
585 // add a guard page to detect stack overflow
586 // the GC might read this area, which is ok, just prevent writes
51b2deb @JeffBezanson adding the GC support needed to mprotect stack pages again
JeffBezanson authored
587 if (mprotect(stk, pagesz-1, PROT_READ) == -1)
588 jl_errorf("mprotect: %s", strerror(errno));
4932043 @JeffBezanson converting more files for new GC
JeffBezanson authored
589 t->stack = stk+pagesz;
590
591 init_task(t);
592 JL_GC_POP();
f44d268 @JeffBezanson alternate implementation of Tasks using stack copying, enable by defi…
JeffBezanson authored
593 jl_gc_add_finalizer((jl_value_t*)t, jl_unprotect_stack_func);
e6ca48c @JeffBezanson more efficient GC frame pointer handling
JeffBezanson authored
594 #endif
f44d268 @JeffBezanson alternate implementation of Tasks using stack copying, enable by defi…
JeffBezanson authored
595
aceee00 @JeffBezanson beginning of lightweight task (symmetric coroutine) support
JeffBezanson authored
596 return t;
597 }
598
51b2deb @JeffBezanson adding the GC support needed to mprotect stack pages again
JeffBezanson authored
599 JL_CALLABLE(jl_unprotect_stack)
600 {
e6ca48c @JeffBezanson more efficient GC frame pointer handling
JeffBezanson authored
601 #ifndef COPY_STACKS
51b2deb @JeffBezanson adding the GC support needed to mprotect stack pages again
JeffBezanson authored
602 jl_task_t *t = (jl_task_t*)args[0];
603 char *stk = t->stack-jl_page_size;
604 // unprotect stack so it can be reallocated for something else
605 mprotect(stk, jl_page_size-1, PROT_READ|PROT_WRITE|PROT_EXEC);
f44d268 @JeffBezanson alternate implementation of Tasks using stack copying, enable by defi…
JeffBezanson authored
606 #endif
51b2deb @JeffBezanson adding the GC support needed to mprotect stack pages again
JeffBezanson authored
607 return (jl_value_t*)jl_null;
608 }
609
4932043 @JeffBezanson converting more files for new GC
JeffBezanson authored
610 #define JL_MIN_STACK (4096*sizeof(void*))
7987f52 @JeffBezanson adding a general-purpose hash table
JeffBezanson authored
611 #define JL_DEFAULT_STACK (2*12288*sizeof(void*))
2036042 @JeffBezanson some task stack fixes:
JeffBezanson authored
612
aceee00 @JeffBezanson beginning of lightweight task (symmetric coroutine) support
JeffBezanson authored
613 JL_CALLABLE(jl_f_task)
614 {
6898aaf @JeffBezanson add the option of specifying a stack size when creating a Task
JeffBezanson authored
615 JL_NARGS(Task, 1, 2);
aceee00 @JeffBezanson beginning of lightweight task (symmetric coroutine) support
JeffBezanson authored
616 JL_TYPECHK(Task, function, args[0]);
7ef1943 @JeffBezanson adding task_done
JeffBezanson authored
617 /*
618 we need a somewhat large stack, because execution can trigger
619 compilation, which uses perhaps too much stack space.
620 */
4932043 @JeffBezanson converting more files for new GC
JeffBezanson authored
621 size_t ssize = JL_DEFAULT_STACK;
6898aaf @JeffBezanson add the option of specifying a stack size when creating a Task
JeffBezanson authored
622 if (nargs == 2) {
39a08ee @JeffBezanson working on issue #127
JeffBezanson authored
623 JL_TYPECHK(Task, long, args[1]);
624 ssize = jl_unbox_long(args[1]);
2036042 @JeffBezanson some task stack fixes:
JeffBezanson authored
625 if (ssize < JL_MIN_STACK)
6898aaf @JeffBezanson add the option of specifying a stack size when creating a Task
JeffBezanson authored
626 jl_error("Task: stack size too small");
627 }
628 return (jl_value_t*)jl_new_task((jl_function_t*)args[0], ssize);
aceee00 @JeffBezanson beginning of lightweight task (symmetric coroutine) support
JeffBezanson authored
629 }
630
631 JL_CALLABLE(jl_f_yieldto)
632 {
0ba7724 @JeffBezanson adding the ability to yield multiple values, and yield values on the
JeffBezanson authored
633 JL_NARGSV(yieldto, 1);
aceee00 @JeffBezanson beginning of lightweight task (symmetric coroutine) support
JeffBezanson authored
634 JL_TYPECHK(yieldto, task, args[0]);
0ba7724 @JeffBezanson adding the ability to yield multiple values, and yield values on the
JeffBezanson authored
635 n_args_in_transit = nargs-1;
636 if (nargs == 2) {
f44d268 @JeffBezanson alternate implementation of Tasks using stack copying, enable by defi…
JeffBezanson authored
637 jl_task_arg_in_transit = args[1];
0ba7724 @JeffBezanson adding the ability to yield multiple values, and yield values on the
JeffBezanson authored
638 }
639 else if (nargs > 2) {
f44d268 @JeffBezanson alternate implementation of Tasks using stack copying, enable by defi…
JeffBezanson authored
640 jl_task_arg_in_transit = jl_f_tuple(NULL, &args[1], n_args_in_transit);
0ba7724 @JeffBezanson adding the ability to yield multiple values, and yield values on the
JeffBezanson authored
641 }
642 else {
f44d268 @JeffBezanson alternate implementation of Tasks using stack copying, enable by defi…
JeffBezanson authored
643 jl_task_arg_in_transit = (jl_value_t*)jl_null;
0ba7724 @JeffBezanson adding the ability to yield multiple values, and yield values on the
JeffBezanson authored
644 }
645 return switchto((jl_task_t*)args[0]);
aceee00 @JeffBezanson beginning of lightweight task (symmetric coroutine) support
JeffBezanson authored
646 }
647
367ecee @JeffBezanson misc. tweaks: making current_task and task_done more first-class,
JeffBezanson authored
648 DLLEXPORT jl_value_t *jl_get_current_task(void)
aceee00 @JeffBezanson beginning of lightweight task (symmetric coroutine) support
JeffBezanson authored
649 {
650 return (jl_value_t*)jl_current_task;
651 }
652
51b2deb @JeffBezanson adding the GC support needed to mprotect stack pages again
JeffBezanson authored
653 jl_function_t *jl_unprotect_stack_func;
654
aceee00 @JeffBezanson beginning of lightweight task (symmetric coroutine) support
JeffBezanson authored
655 void jl_init_tasks(void *stack, size_t ssize)
656 {
657 _probe_arch();
658 jl_task_type = jl_new_struct_type(jl_symbol("Task"), jl_any_type,
659 jl_null,
367ecee @JeffBezanson misc. tweaks: making current_task and task_done more first-class,
JeffBezanson authored
660 jl_tuple(3, jl_symbol("parent"),
661 jl_symbol("tls"),
662 jl_symbol("done")),
663 jl_tuple(3, jl_any_type, jl_any_type,
664 jl_bool_type));
aceee00 @JeffBezanson beginning of lightweight task (symmetric coroutine) support
JeffBezanson authored
665 jl_tupleset(jl_task_type->types, 0, (jl_value_t*)jl_task_type);
666 jl_task_type->fptr = jl_f_task;
667
4359a35 @JeffBezanson squeezing out the GC's 1 word of overhead for small objects
JeffBezanson authored
668 jl_current_task = (jl_task_t*)allocobj(sizeof(jl_task_t));
aceee00 @JeffBezanson beginning of lightweight task (symmetric coroutine) support
JeffBezanson authored
669 jl_current_task->type = (jl_type_t*)jl_task_type;
f44d268 @JeffBezanson alternate implementation of Tasks using stack copying, enable by defi…
JeffBezanson authored
670 #ifdef COPY_STACKS
671 jl_current_task->stackbase = stack+ssize;
672 jl_current_task->ssize = 0; // size of saved piece
673 jl_current_task->bufsz = 0;
674 #else
aceee00 @JeffBezanson beginning of lightweight task (symmetric coroutine) support
JeffBezanson authored
675 jl_current_task->stack = stack;
f44d268 @JeffBezanson alternate implementation of Tasks using stack copying, enable by defi…
JeffBezanson authored
676 jl_current_task->ssize = ssize;
677 #endif
678 jl_current_task->stkbuf = NULL;
aceee00 @JeffBezanson beginning of lightweight task (symmetric coroutine) support
JeffBezanson authored
679 jl_current_task->on_exit = jl_current_task;
6ca8f48 @JeffBezanson adding task-local storage. some bits of global state should be moved …
JeffBezanson authored
680 jl_current_task->tls = NULL;
367ecee @JeffBezanson misc. tweaks: making current_task and task_done more first-class,
JeffBezanson authored
681 jl_current_task->done = jl_false;
6eef572 @JeffBezanson random code cleanup
JeffBezanson authored
682 jl_current_task->start = NULL;
7e07f59 @JeffBezanson fixes related to new GC. mostly making sure all objects are thoroughly
JeffBezanson authored
683 jl_current_task->result = NULL;
5199c5a @JeffBezanson integrating exceptions with tasks
JeffBezanson authored
684 jl_current_task->state.err = 0;
4b2c388 @JeffBezanson fixing backtrace issue from request #456
JeffBezanson authored
685 jl_current_task->state.bt = 0;
5199c5a @JeffBezanson integrating exceptions with tasks
JeffBezanson authored
686 jl_current_task->state.eh_task = jl_current_task;
687 jl_current_task->state.eh_ctx = NULL;
1512535 @JeffBezanson fixing memory management issues with I/O
JeffBezanson authored
688 jl_current_task->state.ostream_obj = (jl_value_t*)jl_null;
6d49a61 @Keno Async IO. Crashes the debugger though...
authored
689 jl_current_task->state.current_output_stream = jl_stdout_tty;
1512535 @JeffBezanson fixing memory management issues with I/O
JeffBezanson authored
690 jl_current_task->state.prev = NULL;
ac0ed78 @JeffBezanson fix to last checkin on local decls.
JeffBezanson authored
691 #ifdef JL_GC_MARKSWEEP
692 jl_current_task->state.gcstack = NULL;
693 #endif
5199c5a @JeffBezanson integrating exceptions with tasks
JeffBezanson authored
694
695 jl_root_task = jl_current_task;
aceee00 @JeffBezanson beginning of lightweight task (symmetric coroutine) support
JeffBezanson authored
696
6dfa652 @JeffBezanson adding exceptions and exception handling
JeffBezanson authored
697 jl_exception_in_transit = (jl_value_t*)jl_null;
f44d268 @JeffBezanson alternate implementation of Tasks using stack copying, enable by defi…
JeffBezanson authored
698 jl_task_arg_in_transit = (jl_value_t*)jl_null;
c12c38a @JeffBezanson eliminate FuncKind; it was not really used at all
JeffBezanson authored
699 jl_unprotect_stack_func = jl_new_closure(jl_unprotect_stack, (jl_value_t*)jl_null, NULL);
aceee00 @JeffBezanson beginning of lightweight task (symmetric coroutine) support
JeffBezanson authored
700 }
Something went wrong with that request. Please try again.