diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/rt/rust_builtin.cpp | 6 | ||||
| -rw-r--r-- | src/rt/rust_globals.h | 2 | ||||
| -rw-r--r-- | src/rt/rust_kernel.cpp | 2 | ||||
| -rw-r--r-- | src/rt/rust_task.cpp | 8 |
4 files changed, 15 insertions, 3 deletions
diff --git a/src/rt/rust_builtin.cpp b/src/rt/rust_builtin.cpp index 66337d6c8ea..001fcd6198b 100644 --- a/src/rt/rust_builtin.cpp +++ b/src/rt/rust_builtin.cpp @@ -864,8 +864,12 @@ rust_task_kill_other(rust_task *task) { /* Used for linked failure */ } extern "C" void -rust_task_kill_all(rust_task *task) { +rust_task_kill_all(rust_task *task) { /* Used for linked failure */ task->fail_sched_loop(); + // This must not happen twice. + static bool main_taskgroup_failed = false; + assert(!main_taskgroup_failed); + main_taskgroup_failed = true; } extern "C" rust_cond_lock* diff --git a/src/rt/rust_globals.h b/src/rt/rust_globals.h index 54b80ee7908..7056f7f4a27 100644 --- a/src/rt/rust_globals.h +++ b/src/rt/rust_globals.h @@ -90,6 +90,8 @@ extern "C" int check_claims; // This accounts for logging buffers. static size_t const BUF_BYTES = 2048; +#define INIT_TASK_ID 1 + // The error status to use when the process fails #define PROC_FAIL_CODE 101 diff --git a/src/rt/rust_kernel.cpp b/src/rt/rust_kernel.cpp index 82fec98e86a..cbe0bb21199 100644 --- a/src/rt/rust_kernel.cpp +++ b/src/rt/rust_kernel.cpp @@ -15,7 +15,7 @@ rust_kernel::rust_kernel(rust_env *env) : _region(env, true), _log(NULL), - max_task_id(1), + max_task_id(INIT_TASK_ID-1), // sync_add_and_fetch increments first max_port_id(1), rval(0), max_sched_id(1), diff --git a/src/rt/rust_task.cpp b/src/rt/rust_task.cpp index a6c9b791fda..db4db51d3cf 100644 --- a/src/rt/rust_task.cpp +++ b/src/rt/rust_task.cpp @@ -129,11 +129,17 @@ cleanup_task(cleanup_args *args) { // assert(task->task_local_data != NULL); task->task_local_data_cleanup(task->task_local_data); task->task_local_data = NULL; - } else if (threw_exception) { + } else if (threw_exception && task->id == INIT_TASK_ID) { // Edge case: If main never spawns any tasks, but fails anyway, TLS // won't be around to take down the kernel (task.rs:kill_taskgroup, // rust_task_kill_all). Do it here instead. + // (Note that children tasks can not init their TLS if they were + // killed too early, so we need to check main's task id too.) task->fail_sched_loop(); + // This must not happen twice. + static bool main_task_failed_without_spawning = false; + assert(!main_task_failed_without_spawning); + main_task_failed_without_spawning = true; } // FIXME (#2676): For performance we should do the annihilator |
