Conservatively serialize nearly all upcalls. Successfuly ran make check with RUST_THREADS=8, so we're probably fairly safe now. In the future we can relax the synchronization to get better performance.

This commit is contained in:
Eric Holk
2011-06-22 15:44:47 -07:00
committed by Graydon Hoare
parent 6367bcf427
commit 681c063ec0
7 changed files with 80 additions and 42 deletions

View File

@@ -131,19 +131,24 @@ void task_start_wrapper(spawn_args *a)
int rval = 42;
a->f(&rval, task, a->a3, a->a4);
LOG(task, task, "task exited with value %d", rval);
// TODO: the old exit glue does some magical argument copying stuff. This
// is probably still needed.
{
scoped_lock with(task->dom->scheduler_lock);
// TODO: the old exit glue does some magical argument copying
// stuff. This is probably still needed.
// This is duplicated from upcall_exit, which is probably dead code by
// now.
LOG(task, task, "task ref_count: %d", task->ref_count);
A(task->dom, task->ref_count >= 0,
"Task ref_count should not be negative on exit!");
task->die();
task->notify_tasks_waiting_to_join();
// This is duplicated from upcall_exit, which is probably dead code by
// now.
LOG(task, task, "task ref_count: %d", task->ref_count);
A(task->dom, task->ref_count >= 0,
"Task ref_count should not be negative on exit!");
task->die();
task->notify_tasks_waiting_to_join();
}
task->yield(1);
}
@@ -154,6 +159,9 @@ rust_task::start(uintptr_t spawnee_fn,
LOGPTR(dom, "from spawnee", spawnee_fn);
I(dom, stk->data != NULL);
I(dom, !dom->scheduler_lock.lock_held_by_current_thread());
scoped_lock with(dom->scheduler_lock);
char *sp = (char *)rust_sp;
@@ -405,7 +413,7 @@ rust_task::free(void *p, bool is_gc)
void
rust_task::transition(rust_task_list *src, rust_task_list *dst) {
scoped_lock sync(dom->scheduler_lock);
I(dom, dom->scheduler_lock.lock_held_by_current_thread());
DLOG(dom, task,
"task %s " PTR " state change '%s' -> '%s' while in '%s'",
name, (uintptr_t)this, src->name, dst->name, state->name);