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);
// 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

View File

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

View File

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

View File

@ -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 <windows.h>
#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>,
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();