rt: Protect cond and cond_name with the state_lock

This commit is contained in:
Brian Anderson 2012-03-02 23:40:27 -08:00
parent 0432030c27
commit 237652299e
3 changed files with 21 additions and 16 deletions

@ -74,8 +74,6 @@ rust_task::rust_task(rust_task_thread *thread, rust_task_list *state,
cache(NULL), cache(NULL),
kernel(thread->kernel), kernel(thread->kernel),
name(name), name(name),
cond(NULL),
cond_name("none"),
list_index(-1), list_index(-1),
next_port_id(0), next_port_id(0),
rendezvous_ptr(0), rendezvous_ptr(0),
@ -87,6 +85,8 @@ rust_task::rust_task(rust_task_thread *thread, rust_task_list *state,
cc_counter(0), cc_counter(0),
total_stack_sz(0), total_stack_sz(0),
state(state), state(state),
cond(NULL),
cond_name("none"),
killed(false), killed(false),
reentered_rust_stack(false), reentered_rust_stack(false),
c_stack(NULL), c_stack(NULL),
@ -242,7 +242,7 @@ rust_task::start(spawn_fn spawnee_fn,
void rust_task::start() void rust_task::start()
{ {
transition(&thread->newborn_tasks, &thread->running_tasks); transition(&thread->newborn_tasks, &thread->running_tasks, NULL, "none");
} }
bool bool
@ -369,7 +369,8 @@ rust_task::blocked()
bool bool
rust_task::blocked_on(rust_cond *on) rust_task::blocked_on(rust_cond *on)
{ {
return blocked() && cond == on; scoped_lock with(state_lock);
return cond == on;
} }
bool bool
@ -398,7 +399,8 @@ rust_task::free(void *p)
} }
void void
rust_task::transition(rust_task_list *src, rust_task_list *dst) { rust_task::transition(rust_task_list *src, rust_task_list *dst,
rust_cond *cond, const char* cond_name) {
bool unlock = false; bool unlock = false;
if(!thread->lock.lock_held_by_current_thread()) { if(!thread->lock.lock_held_by_current_thread()) {
unlock = true; unlock = true;
@ -413,6 +415,8 @@ rust_task::transition(rust_task_list *src, rust_task_list *dst) {
{ {
scoped_lock with(state_lock); scoped_lock with(state_lock);
state = dst; state = dst;
this->cond = cond;
this->cond_name = cond_name;
} }
thread->lock.signal(); thread->lock.signal();
if(unlock) if(unlock)
@ -426,9 +430,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); transition(&thread->running_tasks, &thread->blocked_tasks, on, name);
cond = on;
cond_name = name;
} }
void void
@ -438,14 +440,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.");
cond = NULL; transition(&thread->blocked_tasks, &thread->running_tasks, NULL, "none");
cond_name = "none";
transition(&thread->blocked_tasks, &thread->running_tasks);
} }
void void
rust_task::die() { rust_task::die() {
transition(&thread->running_tasks, &thread->dead_tasks); transition(&thread->running_tasks, &thread->dead_tasks, NULL, "none");
} }
void void

@ -68,8 +68,6 @@ rust_task : public kernel_owned<rust_task>, rust_cond
// Fields known only to the runtime. // Fields known only to the runtime.
rust_kernel *kernel; rust_kernel *kernel;
const char *const name; const char *const name;
rust_cond *cond;
const char *cond_name;
int32_t list_index; int32_t list_index;
rust_port_id next_port_id; rust_port_id next_port_id;
@ -106,8 +104,11 @@ rust_task : public kernel_owned<rust_task>, rust_cond
private: private:
// Protects state, cond, cond_name
lock_and_signal state_lock; lock_and_signal state_lock;
rust_task_list *state; rust_task_list *state;
rust_cond *cond;
const char *cond_name;
// Protects the killed flag // Protects the killed flag
lock_and_signal kill_lock; lock_and_signal kill_lock;
@ -162,7 +163,8 @@ public:
void *realloc(void *data, size_t sz); void *realloc(void *data, size_t sz);
void free(void *p); void free(void *p);
void transition(rust_task_list *src, rust_task_list *dst); void transition(rust_task_list *src, rust_task_list *dst,
rust_cond *cond, const char* cond_name);
void block(rust_cond *on, const char* name); void block(rust_cond *on, const char* name);
void wakeup(rust_cond *from); void wakeup(rust_cond *from);
@ -222,6 +224,8 @@ 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_list *get_state() { return state; }
rust_cond *get_cond() { return cond; }
const char *get_cond_name() { return cond_name; }
}; };
// This stuff is on the stack-switching fast path // This stuff is on the stack-switching fast path

@ -209,7 +209,8 @@ rust_task_thread::log_state() {
log(NULL, log_debug, "\t task: %s @0x%" PRIxPTR ", blocked on: 0x%" log(NULL, log_debug, "\t task: %s @0x%" PRIxPTR ", blocked on: 0x%"
PRIxPTR " '%s'", PRIxPTR " '%s'",
blocked_tasks[i]->name, blocked_tasks[i], blocked_tasks[i]->name, blocked_tasks[i],
blocked_tasks[i]->cond, blocked_tasks[i]->cond_name); blocked_tasks[i]->get_cond(),
blocked_tasks[i]->get_cond_name());
} }
} }