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