diff --git a/src/rt/rust_task.cpp b/src/rt/rust_task.cpp index a8a03362018..ef41e248d5b 100644 --- a/src/rt/rust_task.cpp +++ b/src/rt/rust_task.cpp @@ -61,7 +61,7 @@ extern "C" CDECL void record_sp(void *limit); // Tasks -rust_task::rust_task(rust_task_thread *thread, rust_task_list *state, +rust_task::rust_task(rust_task_thread *thread, rust_task_state state, rust_task *spawner, const char *name, size_t init_stack_sz) : ref_count(1), @@ -231,7 +231,7 @@ rust_task::start(spawn_fn spawnee_fn, void rust_task::start() { - transition(&thread->newborn_tasks, &thread->running_tasks, NULL, "none"); + transition(task_state_newborn, task_state_running, NULL, "none"); } bool @@ -350,14 +350,14 @@ bool rust_task::running() { scoped_lock with(state_lock); - return state == &thread->running_tasks; + return state == task_state_running; } bool rust_task::blocked() { scoped_lock with(state_lock); - return state == &thread->blocked_tasks; + return state == task_state_blocked; } bool @@ -371,7 +371,7 @@ bool rust_task::dead() { scoped_lock with(state_lock); - return state == &thread->dead_tasks; + return state == task_state_dead; } void * @@ -393,13 +393,13 @@ rust_task::free(void *p) } void -rust_task::transition(rust_task_list *src, rust_task_list *dst, +rust_task::transition(rust_task_state src, rust_task_state dst, rust_cond *cond, const char* cond_name) { thread->transition(this, src, dst, cond, cond_name); } void -rust_task::set_state(rust_task_list *state, +rust_task::set_state(rust_task_state state, rust_cond *cond, const char* cond_name) { scoped_lock with(state_lock); this->state = state; @@ -421,7 +421,7 @@ rust_task::block(rust_cond *on, const char* name) { A(thread, cond == NULL, "Cannot block an already blocked task."); A(thread, on != NULL, "Cannot block on a NULL object."); - transition(&thread->running_tasks, &thread->blocked_tasks, on, name); + transition(task_state_running, task_state_blocked, on, name); return true; } @@ -433,12 +433,12 @@ rust_task::wakeup(rust_cond *from) { (uintptr_t) cond, (uintptr_t) from); A(thread, cond == from, "Cannot wake up blocked task on wrong condition."); - transition(&thread->blocked_tasks, &thread->running_tasks, NULL, "none"); + transition(task_state_blocked, task_state_running, NULL, "none"); } void rust_task::die() { - transition(&thread->running_tasks, &thread->dead_tasks, NULL, "none"); + transition(task_state_running, task_state_dead, NULL, "none"); } void diff --git a/src/rt/rust_task.h b/src/rt/rust_task.h index eaa28740236..b96cfea7795 100644 --- a/src/rt/rust_task.h +++ b/src/rt/rust_task.h @@ -90,7 +90,7 @@ private: // Protects state, cond, cond_name lock_and_signal state_lock; - rust_task_list *state; + rust_task_state state; rust_cond *cond; const char *cond_name; @@ -121,7 +121,7 @@ private: void return_c_stack(); - void transition(rust_task_list *src, rust_task_list *dst, + void transition(rust_task_state src, rust_task_state dst, rust_cond *cond, const char* cond_name); bool must_fail_from_being_killed_unlocked(); @@ -134,7 +134,7 @@ public: // Only a pointer to 'name' is kept, so it must live as long as this task. rust_task(rust_task_thread *thread, - rust_task_list *state, + rust_task_state state, rust_task *spawner, const char *name, size_t init_stack_sz); @@ -152,7 +152,7 @@ public: void *realloc(void *data, size_t sz); void free(void *p); - void set_state(rust_task_list *state, + void set_state(rust_task_state state, rust_cond *cond, const char* cond_name); bool block(rust_cond *on, const char* name); @@ -206,7 +206,7 @@ public: rust_port_selector *get_port_selector() { return &port_selector; } - rust_task_list *get_state() { return state; } + rust_task_state get_state() { return state; } rust_cond *get_cond() { return cond; } const char *get_cond_name() { return cond_name; } }; diff --git a/src/rt/rust_task_thread.cpp b/src/rt/rust_task_thread.cpp index d8fb28d5791..0388d48c906 100644 --- a/src/rt/rust_task_thread.cpp +++ b/src/rt/rust_task_thread.cpp @@ -27,13 +27,13 @@ rust_task_thread::rust_task_thread(rust_scheduler *sched, id(id), should_exit(false), cached_c_stack(NULL), - kernel(sched->kernel), - sched(sched), - srv(srv), newborn_tasks(this, "newborn"), running_tasks(this, "running"), blocked_tasks(this, "blocked"), dead_tasks(this, "dead"), + kernel(sched->kernel), + sched(sched), + srv(srv), log_lvl(log_debug), min_stack_size(kernel->env->min_stack_size), env(kernel->env), @@ -248,7 +248,7 @@ rust_task_thread::start_main_loop() { ", state: %s", scheduled_task->name, (uintptr_t)scheduled_task, - scheduled_task->get_state()->name); + state_list(scheduled_task->get_state())->name); place_task_in_tls(scheduled_task); @@ -262,7 +262,7 @@ rust_task_thread::start_main_loop() { " in state '%s', worker id=%d" PRIxPTR, scheduled_task->name, (uintptr_t)scheduled_task, - scheduled_task->get_state()->name, + state_list(scheduled_task->get_state())->name, id); reap_dead_tasks(); @@ -289,7 +289,7 @@ rust_task_thread::create_task(rust_task *spawner, const char *name, size_t init_stack_sz) { rust_task *task = new (this->kernel, "rust_task") - rust_task (this, &newborn_tasks, spawner, name, init_stack_sz); + rust_task (this, task_state_newborn, spawner, name, init_stack_sz); DLOG(this, task, "created task: " PTR ", spawner: %s, name: %s", task, spawner ? spawner->name : "null", name); @@ -302,18 +302,34 @@ rust_task_thread::create_task(rust_task *spawner, const char *name, return task; } +rust_task_list * +rust_task_thread::state_list(rust_task_state state) { + switch (state) { + case task_state_newborn: + return &newborn_tasks; + case task_state_running: + return &running_tasks; + case task_state_blocked: + return &blocked_tasks; + case task_state_dead: + return &dead_tasks; + } +} + void rust_task_thread::transition(rust_task *task, - rust_task_list *src, rust_task_list *dst, + rust_task_state src, rust_task_state dst, rust_cond *cond, const char* cond_name) { scoped_lock with(lock); + rust_task_list *src_list = state_list(src); + rust_task_list *dst_list = state_list(dst); DLOG(this, task, "task %s " PTR " state change '%s' -> '%s' while in '%s'", - name, (uintptr_t)this, src->name, dst->name, - task->get_state()->name); + name, (uintptr_t)this, src_list->name, dst_list->name, + state_list(task->get_state())->name); I(this, task->get_state() == src); - src->remove(task); - dst->append(task); + src_list->remove(task); + dst_list->append(task); task->set_state(dst, cond, cond_name); lock.signal(); diff --git a/src/rt/rust_task_thread.h b/src/rt/rust_task_thread.h index 20f37ab7bcc..190b3656cc5 100644 --- a/src/rt/rust_task_thread.h +++ b/src/rt/rust_task_thread.h @@ -1,6 +1,7 @@ #ifndef RUST_TASK_THREAD_H #define RUST_TASK_THREAD_H +#include "rust_internal.h" #include "sync/rust_thread.h" #include "rust_stack.h" #include "context.h" @@ -11,6 +12,13 @@ #include #endif +enum rust_task_state { + task_state_newborn, + task_state_running, + task_state_blocked, + task_state_dead +}; + struct rust_task_thread : public kernel_owned, rust_thread { @@ -37,19 +45,21 @@ private: stk_seg *cached_c_stack; stk_seg *extra_c_stack; + rust_task_list newborn_tasks; + rust_task_list running_tasks; + rust_task_list blocked_tasks; + rust_task_list dead_tasks; + void prepare_c_stack(rust_task *task); void unprepare_c_stack(); + rust_task_list *state_list(rust_task_state state); + public: rust_kernel *kernel; rust_scheduler *sched; rust_srv *srv; - rust_task_list newborn_tasks; - rust_task_list running_tasks; - rust_task_list blocked_tasks; - rust_task_list dead_tasks; - // NB: this is used to filter *runtime-originating* debug // logging, on a per-scheduler basis. It's not likely what // you want to expose to the user in terms of per-task @@ -90,7 +100,7 @@ public: size_t init_stack_sz); void transition(rust_task *task, - rust_task_list *src, rust_task_list *dst, + rust_task_state src, rust_task_state dst, rust_cond *cond, const char* cond_name); virtual void run();