Working on more spawn test cases.
This commit is contained in:
parent
a332043561
commit
2f23405a60
8 changed files with 55 additions and 20 deletions
|
@ -3,7 +3,7 @@ import cast = unsafe::reinterpret_cast;
|
|||
native "rust" mod rustrt {
|
||||
fn task_sleep(time_in_us: uint);
|
||||
fn task_yield();
|
||||
fn task_join(t: task) -> int;
|
||||
fn task_join(t: task_id) -> int;
|
||||
fn unsupervise();
|
||||
fn pin_task();
|
||||
fn unpin_task();
|
||||
|
@ -20,6 +20,8 @@ native "rust" mod rustrt {
|
|||
fn get_task_context(id : task_id) -> *x86_registers;
|
||||
fn start_task(id : task_id);
|
||||
fn get_task_trampoline() -> u32;
|
||||
|
||||
fn leak[@T](thing : -T);
|
||||
}
|
||||
|
||||
type task_id = int;
|
||||
|
@ -40,6 +42,10 @@ fn yield() { ret rustrt::task_yield(); }
|
|||
tag task_result { tr_success; tr_failure; }
|
||||
|
||||
fn join(t: task) -> task_result {
|
||||
join_id(cast(t))
|
||||
}
|
||||
|
||||
fn join_id(t : task_id) -> task_result {
|
||||
alt rustrt::task_join(t) { 0 { tr_success } _ { tr_failure } }
|
||||
}
|
||||
|
||||
|
@ -64,7 +70,7 @@ fn set_min_stack(stack_size : uint) {
|
|||
}
|
||||
|
||||
// FIXME: make this a fn~ once those are supported.
|
||||
fn _spawn(thunk : -fn() -> ()) -> task_id {
|
||||
fn _spawn(thunk : fn() -> ()) -> task_id {
|
||||
let id = rustrt::new_task();
|
||||
|
||||
// the order of arguments are outptr, taskptr, envptr.
|
||||
|
@ -80,8 +86,6 @@ fn _spawn(thunk : -fn() -> ()) -> task_id {
|
|||
let raw_thunk : { code: u32, env: u32 } = cast(thunk);
|
||||
(*regs).eip = raw_thunk.code;
|
||||
|
||||
log_err #fmt("{ %u, %u }", raw_thunk.code as uint, raw_thunk.env as uint);
|
||||
|
||||
// okay, now we align the stack and add the environment pointer and a fake
|
||||
// return address.
|
||||
|
||||
|
@ -102,6 +106,8 @@ fn _spawn(thunk : -fn() -> ()) -> task_id {
|
|||
|
||||
rustrt::start_task(id);
|
||||
|
||||
rustrt::leak(thunk);
|
||||
|
||||
ret id;
|
||||
}
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
// NB: please do not commit code with this uncommented. It's
|
||||
// hugely expensive and should only be used as a last resort.
|
||||
//
|
||||
// #define TRACK_ALLOCATIONS
|
||||
#define TRACK_ALLOCATIONS
|
||||
|
||||
#define MAGIC 0xbadc0ffe
|
||||
|
||||
|
|
|
@ -99,6 +99,12 @@ align_of(rust_task *task, type_desc *t) {
|
|||
return t->align;
|
||||
}
|
||||
|
||||
extern "C" CDECL void
|
||||
leak(rust_task *task, type_desc *t, void *thing) {
|
||||
// Do nothing. Call this with move-mode in order to say "Don't worry rust,
|
||||
// I'll take care of this."
|
||||
}
|
||||
|
||||
extern "C" CDECL intptr_t
|
||||
refcount(rust_task *task, type_desc *t, intptr_t *v) {
|
||||
|
||||
|
@ -283,7 +289,7 @@ task_yield(rust_task *task) {
|
|||
extern "C" CDECL intptr_t
|
||||
task_join(rust_task *task, rust_task_id tid) {
|
||||
// If the other task is already dying, we don't have to wait for it.
|
||||
rust_task *join_task = task->kernel->get_task_by_id(tid);
|
||||
smart_ptr<rust_task> join_task = task->kernel->get_task_by_id(tid);
|
||||
// FIXME: find task exit status and return that.
|
||||
if(!join_task) return 0;
|
||||
join_task->lock.lock();
|
||||
|
@ -728,7 +734,9 @@ get_task_pointer(rust_task *task, rust_task_id id) {
|
|||
|
||||
extern "C" CDECL void
|
||||
start_task(rust_task *task, rust_task_id id) {
|
||||
task->kernel->get_task_by_id(id)->start();
|
||||
rust_task * target = task->kernel->get_task_by_id(id);
|
||||
|
||||
target->start();
|
||||
}
|
||||
|
||||
extern "C" void *task_trampoline asm("task_trampoline");
|
||||
|
|
|
@ -145,13 +145,12 @@ template<class T>
|
|||
class smart_ptr {
|
||||
T *p;
|
||||
|
||||
smart_ptr(const smart_ptr &sp) : p(sp.p) {
|
||||
if(p) { p->ref(); }
|
||||
}
|
||||
|
||||
public:
|
||||
smart_ptr() : p(NULL) {};
|
||||
smart_ptr(T *p) : p(p) { if(p) { p->ref(); } }
|
||||
smart_ptr(const smart_ptr &sp) : p(sp.p) {
|
||||
if(p) { p->ref(); }
|
||||
}
|
||||
|
||||
~smart_ptr() {
|
||||
if(p) {
|
||||
|
|
|
@ -40,6 +40,7 @@ ivec_reserve
|
|||
ivec_reserve_shared
|
||||
ivec_to_ptr
|
||||
last_os_error
|
||||
leak
|
||||
nano_time
|
||||
new_chan
|
||||
new_port
|
||||
|
|
|
@ -2,7 +2,12 @@
|
|||
|
||||
use std;
|
||||
|
||||
fn main() { let t = spawn child(10); std::task::join(t); }
|
||||
import std::task;
|
||||
|
||||
fn main() {
|
||||
let t = task::_spawn(bind child(10));
|
||||
task::join_id(t);
|
||||
}
|
||||
|
||||
fn child(i: int) { log_err i; assert (i == 10); }
|
||||
|
||||
|
|
|
@ -1,23 +1,33 @@
|
|||
// Temporarily xfailing, because something is wrong.
|
||||
// xfail-stage2
|
||||
use std;
|
||||
|
||||
import std::comm;
|
||||
import std::comm::chan_t;
|
||||
import std::comm::send;
|
||||
import std::task;
|
||||
|
||||
fn main() { test05(); }
|
||||
|
||||
fn test05_start(pch: *u8) {
|
||||
let ch = comm::chan_from_unsafe_ptr(pch);
|
||||
|
||||
ch.send(10);
|
||||
ch.send(20);
|
||||
ch.send(30);
|
||||
fn test05_start(ch : chan_t[int]) {
|
||||
log_err ch;
|
||||
send(ch, 10);
|
||||
log_err "sent 10";
|
||||
send(ch, 20);
|
||||
log_err "sent 20";
|
||||
send(ch, 30);
|
||||
log_err "sent 30";
|
||||
}
|
||||
|
||||
fn test05() {
|
||||
let po = comm::mk_port[int]();
|
||||
let ch = po.mk_chan();
|
||||
spawn test05_start(ch.unsafe_ptr());
|
||||
let ch = po.mk_chan2();
|
||||
task::_spawn(bind test05_start(ch));
|
||||
let value = po.recv();
|
||||
log_err value;
|
||||
value = po.recv();
|
||||
log_err value;
|
||||
value = po.recv();
|
||||
log_err value;
|
||||
assert (value == 30);
|
||||
}
|
||||
|
|
|
@ -38,3 +38,9 @@ fn test_lib_spawn() {
|
|||
fn foo() { log_err "Hello, World!"; }
|
||||
task::_spawn(foo);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_lib_spawn2() {
|
||||
fn foo(x : int) { assert(x == 42); }
|
||||
task::_spawn(bind foo(42));
|
||||
}
|
Loading…
Add table
Reference in a new issue