Working on more spawn test cases.

This commit is contained in:
Eric Holk 2011-08-11 10:46:57 -07:00
parent a332043561
commit 2f23405a60
8 changed files with 55 additions and 20 deletions

View file

@ -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;
}

View file

@ -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

View file

@ -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");

View file

@ -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) {

View file

@ -40,6 +40,7 @@ ivec_reserve
ivec_reserve_shared
ivec_to_ptr
last_os_error
leak
nano_time
new_chan
new_port

View file

@ -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); }

View file

@ -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);
}

View file

@ -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));
}