rt: Protect cond and cond_name with the state_lock
This commit is contained in:
parent
0432030c27
commit
237652299e
@ -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());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user