diff --git a/src/task.c b/src/task.c index 9196f26998f22..b5b04d38c6cbe 100644 --- a/src/task.c +++ b/src/task.c @@ -74,6 +74,15 @@ static void jl_swap_fiber(jl_ucontext_t *lastt, jl_ucontext_t *t); static JL_THREAD unw_cursor_t jl_basecursor; #endif +#ifdef ALWAYS_COPY_STACKS +# ifndef COPY_STACKS +# error "ALWAYS_COPY_STACKS requires COPY_STACKS" +# endif +static int always_copy_stacks = 1; +#else +static int always_copy_stacks = 0; +#endif + #ifdef COPY_STACKS static void memcpy_a16(uint64_t *to, uint64_t *from, size_t nb) @@ -323,7 +332,10 @@ static void ctx_switch(jl_ptls_t ptls, jl_task_t **pt) jl_swap_fiber(lastt_ctx, &t->ctx); } else { - jl_start_fiber(lastt_ctx, &t->ctx); + if (always_copy_stacks) + jl_longjmp(ptls->base_ctx.uc_mcontext, 1); + else + jl_start_fiber(lastt_ctx, &t->ctx); } // TODO: mutex unlock the thread we just switched from #ifdef ENABLE_TIMINGS @@ -459,12 +471,13 @@ JL_DLLEXPORT jl_task_t *jl_new_task(jl_function_t *start, jl_value_t *completion t->copy_stack = 0; if (ssize == 0) { // stack size unspecified; use default -#if defined(COPY_STACKS) && defined(ALWAYS_COPY_STACKS) - t->copy_stack = 1; - t->bufsz = 0; -#else - t->bufsz = JL_STACK_SIZE; -#endif + if (always_copy_stacks) { + t->copy_stack = 1; + t->bufsz = 0; + } + else { + t->bufsz = JL_STACK_SIZE; + } } else { // user requested dedicated stack of a certain size @@ -922,7 +935,6 @@ void jl_init_root_task(void *stack_lo, void *stack_hi) jl_ptls_t ptls = jl_get_ptls_states(); ptls->current_task = (jl_task_t*)jl_gc_alloc(ptls, sizeof(jl_task_t), jl_task_type); - ptls->current_task->copy_stack = 0; void *stack = stack_lo; size_t ssize = (char*)stack_hi - (char*)stack_lo; #ifndef _OS_WINDOWS_ @@ -931,8 +943,16 @@ void jl_init_root_task(void *stack_lo, void *stack_hi) ssize += ROOT_TASK_STACK_ADJUSTMENT; // sizeof stack is known exactly, but not where we are in that stack } #endif - ptls->current_task->stkbuf = stack; - ptls->current_task->bufsz = ssize; + if (always_copy_stacks) { + ptls->current_task->copy_stack = 1; + ptls->current_task->stkbuf = NULL; + ptls->current_task->bufsz = 0; + } + else { + ptls->current_task->copy_stack = 0; + ptls->current_task->stkbuf = stack; + ptls->current_task->bufsz = ssize; + } ptls->current_task->started = 1; ptls->current_task->next = jl_nothing; ptls->current_task->queue = jl_nothing; @@ -955,7 +975,15 @@ void jl_init_root_task(void *stack_lo, void *stack_hi) ptls->root_task = ptls->current_task; - jl_init_basefiber(JL_STACK_SIZE); + if (always_copy_stacks) { + ptls->stackbase = stack_hi; + ptls->stacksize = ssize; + if (jl_setjmp(ptls->base_ctx.uc_mcontext, 0)) + start_task(); + } + else { + jl_init_basefiber(JL_STACK_SIZE); + } } JL_DLLEXPORT int jl_is_task_started(jl_task_t *t)