rt: Use an enum to represent the task state

This commit is contained in:
Brian Anderson
2012-03-17 18:12:15 -07:00
parent 0201a03203
commit 05466c6138
4 changed files with 58 additions and 32 deletions

View File

@@ -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

View File

@@ -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; }
}; };

View File

@@ -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();

View File

@@ -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();