diff options
| author | Brian Anderson <banderson@mozilla.com> | 2012-02-07 22:24:56 -0800 |
|---|---|---|
| committer | Brian Anderson <banderson@mozilla.com> | 2012-02-08 15:42:51 -0800 |
| commit | 149d1d4a6e3bb8a439eff78cc6edb25f16aa47c5 (patch) | |
| tree | 8cf83c0d9cc29e4d7a71aadcb7d209aef6d23179 | |
| parent | 35ba9715fafe14c96081049327c808fd0c5a2792 (diff) | |
| download | rust-149d1d4a6e3bb8a439eff78cc6edb25f16aa47c5.tar.gz rust-149d1d4a6e3bb8a439eff78cc6edb25f16aa47c5.zip | |
core: Add a test for blocking in native code
| -rw-r--r-- | src/libcore/task.rs | 68 | ||||
| -rw-r--r-- | src/rt/rust_builtin.cpp | 40 | ||||
| -rw-r--r-- | src/rt/rustrt.def.in | 6 |
3 files changed, 114 insertions, 0 deletions
diff --git a/src/libcore/task.rs b/src/libcore/task.rs index a62dafbadaf..637a684b8d8 100644 --- a/src/libcore/task.rs +++ b/src/libcore/task.rs @@ -504,6 +504,74 @@ mod tests { comm::recv(po); } + #[nolink] + native mod rt { + fn rust_dbg_lock_create() -> *ctypes::void; + fn rust_dbg_lock_destroy(lock: *ctypes::void); + fn rust_dbg_lock_lock(lock: *ctypes::void); + fn rust_dbg_lock_unlock(lock: *ctypes::void); + fn rust_dbg_lock_wait(lock: *ctypes::void); + fn rust_dbg_lock_signal(lock: *ctypes::void); + } + + #[test] + fn spawn_sched_blocking() { + + // Testing that a task in one scheduler can block natively + // without affecting other schedulers + iter::repeat(20u) {|| + + let start_po = comm::port(); + let start_ch = comm::chan(start_po); + let fin_po = comm::port(); + let fin_ch = comm::chan(fin_po); + + let lock = rt::rust_dbg_lock_create(); + + spawn_sched(1u) {|| + rt::rust_dbg_lock_lock(lock); + + comm::send(start_ch, ()); + + // Block the scheduler thread + rt::rust_dbg_lock_wait(lock); + rt::rust_dbg_lock_unlock(lock); + + comm::send(fin_ch, ()); + }; + + // Wait until the other task has its lock + comm::recv(start_po); + + fn pingpong(po: comm::port<int>, ch: comm::chan<int>) { + let val = 20; + while val > 0 { + val = comm::recv(po); + comm::send(ch, val - 1); + } + } + + let setup_po = comm::port(); + let setup_ch = comm::chan(setup_po); + let parent_po = comm::port(); + let parent_ch = comm::chan(parent_po); + spawn {|| + let child_po = comm::port(); + comm::send(setup_ch, comm::chan(child_po)); + pingpong(child_po, parent_ch); + }; + + let child_ch = comm::recv(setup_po); + comm::send(child_ch, 20); + pingpong(parent_po, child_ch); + rt::rust_dbg_lock_lock(lock); + rt::rust_dbg_lock_signal(lock); + rt::rust_dbg_lock_unlock(lock); + comm::recv(fin_po); + rt::rust_dbg_lock_destroy(lock); + } + } + } diff --git a/src/rt/rust_builtin.cpp b/src/rt/rust_builtin.cpp index c228aa9159f..19295167518 100644 --- a/src/rt/rust_builtin.cpp +++ b/src/rt/rust_builtin.cpp @@ -626,6 +626,46 @@ rust_log_console_off() { log_console_off(task->kernel->env); } +extern "C" CDECL lock_and_signal * +rust_dbg_lock_create() { + return new lock_and_signal(); +} + +extern "C" CDECL void +rust_dbg_lock_destroy(lock_and_signal *lock) { + rust_task *task = rust_task_thread::get_task(); + I(task->thread, lock); + delete lock; +} + +extern "C" CDECL void +rust_dbg_lock_lock(lock_and_signal *lock) { + rust_task *task = rust_task_thread::get_task(); + I(task->thread, lock); + lock->lock(); +} + +extern "C" CDECL void +rust_dbg_lock_unlock(lock_and_signal *lock) { + rust_task *task = rust_task_thread::get_task(); + I(task->thread, lock); + lock->unlock(); +} + +extern "C" CDECL void +rust_dbg_lock_wait(lock_and_signal *lock) { + rust_task *task = rust_task_thread::get_task(); + I(task->thread, lock); + lock->wait(); +} + +extern "C" CDECL void +rust_dbg_lock_signal(lock_and_signal *lock) { + rust_task *task = rust_task_thread::get_task(); + I(task->thread, lock); + lock->signal(); +} + // // Local Variables: // mode: C++ diff --git a/src/rt/rustrt.def.in b/src/rt/rustrt.def.in index e51d47065f6..b0acbacf4e3 100644 --- a/src/rt/rustrt.def.in +++ b/src/rt/rustrt.def.in @@ -100,3 +100,9 @@ rust_uvtmp_read_start rust_uvtmp_timer rust_uvtmp_delete_buf rust_uvtmp_get_req_id +rust_dbg_lock_create +rust_dbg_lock_destroy +rust_dbg_lock_lock +rust_dbg_lock_unlock +rust_dbg_lock_wait +rust_dbg_lock_signal |
