diff --git a/src/jl_exported_funcs.inc b/src/jl_exported_funcs.inc index 8ea9fa74eb5f0..e2527e3d7aeab 100644 --- a/src/jl_exported_funcs.inc +++ b/src/jl_exported_funcs.inc @@ -454,6 +454,7 @@ XX(jl_tagged_gensym) \ XX(jl_take_buffer) \ XX(jl_task_get_next) \ + XX(jl_task_stack_buffer) \ XX(jl_termios_size) \ XX(jl_test_cpu_feature) \ XX(jl_threadid) \ diff --git a/src/julia_gcext.h b/src/julia_gcext.h index 2b29641151cf4..c65586b85547a 100644 --- a/src/julia_gcext.h +++ b/src/julia_gcext.h @@ -135,6 +135,15 @@ JL_DLLEXPORT int jl_gc_conservative_gc_support_enabled(void); // NOTE: Only valid to call from within a GC context. JL_DLLEXPORT jl_value_t *jl_gc_internal_obj_base_ptr(void *p); +// Return a non-null pointer to the start of the stack area if the task +// has an associated stack buffer. In that case, *size will also contain +// the size of that stack buffer upon return. Also, if task is a thread's +// current task, that thread's id will be stored in *tid; otherwise, +// *tid will be set to -1. +// +// DEPRECATED: use jl_active_task_stack() instead. +JL_DLLEXPORT void *jl_task_stack_buffer(jl_task_t *task, size_t *size, int *tid); + // Query the active and total stack range for the given task, and set // *active_start and *active_end respectively *total_start and *total_end // accordingly. The range for the active part is a best-effort approximation diff --git a/src/task.c b/src/task.c index 4c1ff4a6ee2a5..5f28c3c243bfe 100644 --- a/src/task.c +++ b/src/task.c @@ -326,6 +326,34 @@ void JL_NORETURN jl_finish_task(jl_task_t *ct) abort(); } +JL_DLLEXPORT void *jl_task_stack_buffer(jl_task_t *task, size_t *size, int *ptid) +{ + size_t off = 0; +#ifndef _OS_WINDOWS_ + jl_ptls_t ptls0 = jl_atomic_load_relaxed(&jl_all_tls_states)[0]; + if (ptls0->root_task == task) { + // See jl_init_root_task(). The root task of the main thread + // has its buffer enlarged by an artificial 3000000 bytes, but + // that means that the start of the buffer usually points to + // inaccessible memory. We need to correct for this. + off = ROOT_TASK_STACK_ADJUSTMENT; + } +#endif + jl_ptls_t ptls2 = task->ptls; + *ptid = -1; + if (ptls2) { + *ptid = jl_atomic_load_relaxed(&task->tid); +#ifdef COPY_STACKS + if (task->copy_stack) { + *size = ptls2->stacksize; + return (char *)ptls2->stackbase - *size; + } +#endif + } + *size = task->bufsz - off; + return (void *)((char *)task->stkbuf + off); +} + JL_DLLEXPORT void jl_active_task_stack(jl_task_t *task, char **active_start, char **active_end, char **total_start, char **total_end)