diff options
| author | Eric Holk <eholk@mozilla.com> | 2011-06-20 17:19:50 -0700 |
|---|---|---|
| committer | Graydon Hoare <graydon@mozilla.com> | 2011-06-27 09:58:39 -0700 |
| commit | 4bc773465fe95da37b8c867979786b190de6197c (patch) | |
| tree | 668f9398ab5f977a5dfac6c9e9b807540fe745d1 /src/rt/rust_task.cpp | |
| parent | 91eadfd1ea1544513258fc30bf94ef384db2ad90 (diff) | |
| download | rust-4bc773465fe95da37b8c867979786b190de6197c.tar.gz rust-4bc773465fe95da37b8c867979786b190de6197c.zip | |
Basic multithreading support. The infinite loops test successfully maxes out the CPU.
Diffstat (limited to 'src/rt/rust_task.cpp')
| -rw-r--r-- | src/rt/rust_task.cpp | 29 |
1 files changed, 20 insertions, 9 deletions
diff --git a/src/rt/rust_task.cpp b/src/rt/rust_task.cpp index bb8261bb78a..f42f40510bd 100644 --- a/src/rt/rust_task.cpp +++ b/src/rt/rust_task.cpp @@ -70,7 +70,8 @@ rust_task::rust_task(rust_dom *dom, rust_task_list *state, list_index(-1), rendezvous_ptr(0), alarm(this), - handle(NULL) + handle(NULL), + active(false) { LOGPTR(dom, "new task", (uintptr_t)this); DLOG(dom, task, "sizeof(task) = %d (0x%x)", sizeof *this, sizeof *this); @@ -123,17 +124,12 @@ struct spawn_args { uintptr_t, uintptr_t); }; -// TODO: rewrite this in LLVM assembly so we can be sure the calling -// conventions will match. extern "C" CDECL void task_start_wrapper(spawn_args *a) { rust_task *task = a->task; int rval = 42; - // This is used by the context switching code. LLVM generates fastcall - // functions, but ucontext needs cdecl functions. This massages the - // calling conventions into the right form. a->f(&rval, task, a->a3, a->a4); LOG(task, task, "task exited with value %d", rval); @@ -174,7 +170,10 @@ rust_task::start(uintptr_t spawnee_fn, ctx.call((void *)task_start_wrapper, a, sp); yield_timer.reset(0); - transition(&dom->newborn_tasks, &dom->running_tasks); + { + scoped_lock sync(dom->scheduler_lock); + transition(&dom->newborn_tasks, &dom->running_tasks); + } } void @@ -425,7 +424,10 @@ rust_task::block(rust_cond *on, const char* name) { A(dom, cond == NULL, "Cannot block an already blocked task."); A(dom, on != NULL, "Cannot block on a NULL object."); - transition(&dom->running_tasks, &dom->blocked_tasks); + { + scoped_lock sync(dom->scheduler_lock); + transition(&dom->running_tasks, &dom->blocked_tasks); + } cond = on; cond_name = name; } @@ -437,7 +439,10 @@ rust_task::wakeup(rust_cond *from) { (uintptr_t) cond, (uintptr_t) from); A(dom, cond == from, "Cannot wake up blocked task on wrong condition."); - transition(&dom->blocked_tasks, &dom->running_tasks); + { + scoped_lock sync(dom->scheduler_lock); + transition(&dom->blocked_tasks, &dom->running_tasks); + } I(dom, cond == from); cond = NULL; cond_name = "none"; @@ -445,6 +450,7 @@ rust_task::wakeup(rust_cond *from) { void rust_task::die() { + scoped_lock sync(dom->scheduler_lock); transition(&dom->running_tasks, &dom->dead_tasks); } @@ -482,6 +488,11 @@ rust_task::get_handle() { return handle; } +bool rust_task::can_schedule() +{ + return yield_timer.has_timed_out() && !active; +} + // // Local Variables: // mode: C++ |
