core: Add a test for blocking in native code
This commit is contained in:
parent
35ba9715fa
commit
149d1d4a6e
3 changed files with 114 additions and 0 deletions
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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++
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue