]> git.lizzy.rs Git - rust.git/commitdiff
rewrite task tests
authorNiko Matsakis <niko@alum.mit.edu>
Thu, 5 Jan 2012 04:11:39 +0000 (20:11 -0800)
committerNiko Matsakis <niko@alum.mit.edu>
Sat, 7 Jan 2012 06:40:31 +0000 (22:40 -0800)
src/rt/rust.cpp
src/rt/rust_builtin.cpp
src/rt/rust_task.cpp
src/rt/rust_task.h
src/rt/test/rust_test_runtime.cpp
src/test/stdtest/task.rs

index a3b30c26e5b128cfaecebf76a2ada664f611f0d8..03acdaa91e0381ba6a6304a56f7cdf3ff28b017c 100644 (file)
@@ -98,7 +98,7 @@ rust_start(uintptr_t main_fn, int argc, char **argv, void* crate_map) {
         DLOG(sched, dom, "startup: arg[%d] = '%s'", i, args->argv[i]);
     }
 
-    root_task->start((spawn_fn)main_fn, (uintptr_t)args->args);
+    root_task->start((spawn_fn)main_fn, NULL, args->args);
     root_task->deref();
     root_task = NULL;
 
index b387078a75ab5e3829ff263e3b682f3cd87dc5fa..4f951a7faf0af67daf40eac0bf29ba8829f27074 100644 (file)
@@ -421,15 +421,15 @@ rust_get_task() {
 }
 
 struct fn_env_pair {
-    intptr_t f;
-    intptr_t env;
+    spawn_fn f;
+    rust_boxed_closure *env;
 };
 
 extern "C" CDECL void
 start_task(rust_task_id id, fn_env_pair *f) {
     rust_task *task = rust_scheduler::get_task();
     rust_task *target = task->kernel->get_task_by_id(id);
-    target->start((spawn_fn)f->f, f->env);
+    target->start(f->f, f->env, NULL);
     target->deref();
 }
 
index f63e8d8d4c0178fc20edd5fd4360cfac01fc884c..cade11e372d9271b7ba3e21ec79fd7e1d28322a6 100644 (file)
@@ -292,18 +292,9 @@ rust_task::~rust_task()
 
 struct spawn_args {
     rust_task *task;
-    uintptr_t envptr;
     spawn_fn f;
-};
-
-struct rust_closure {
-    const type_desc *td;
-    // ... see trans_closure.rs for full description ...
-};
-
-struct rust_boxed_closure {
-    intptr_t ref_count;
-    rust_closure closure;
+    rust_boxed_closure *envptr;
+    void *argptr;
 };
 
 struct cleanup_args {
@@ -319,14 +310,6 @@ cleanup_task(cleanup_args *args) {
 
     cc::do_cc(task);
 
-    rust_boxed_closure* boxed_env = (rust_boxed_closure*)a->envptr;
-    if(boxed_env) {
-        // free the environment.
-        rust_closure *env = &boxed_env->closure;
-        env->td->drop_glue(NULL, NULL, &env->td, env);
-        env->td->free_glue(NULL, NULL, &env->td, env);
-    }
-
     task->die();
 
     if (task->killed && !failed) {
@@ -345,6 +328,8 @@ cleanup_task(cleanup_args *args) {
     }
 }
 
+extern "C" void upcall_shared_free(void* ptr);
+
 // This runs on the Rust stack
 extern "C" CDECL
 void task_start_wrapper(spawn_args *a)
@@ -355,16 +340,23 @@ void task_start_wrapper(spawn_args *a)
     try {
         // The first argument is the return pointer; as the task fn 
         // must have void return type, we can safely pass 0.
-        a->f(0, a->envptr);
+        a->f(0, a->envptr, a->argptr);
     } catch (rust_task *ex) {
         A(task->sched, ex == task,
           "Expected this task to be thrown for unwinding");
         failed = true;
     }
 
-    cleanup_args ca = {a, failed};
+    rust_boxed_closure* boxed_env = (rust_boxed_closure*)a->envptr;
+    if(boxed_env) {
+        // free the environment.
+        const type_desc *td = boxed_env->closure.td;
+        td->drop_glue(NULL, NULL, td->first_param, &boxed_env->closure);
+        upcall_shared_free(boxed_env);
+    }
 
     // The cleanup work needs lots of stack
+    cleanup_args ca = {a, failed};
     task->sched->c_context.call_shim_on_c_stack(&ca, (void*)cleanup_task);
 
     task->ctx.next->swap(task->ctx);
@@ -372,10 +364,12 @@ void task_start_wrapper(spawn_args *a)
 
 void
 rust_task::start(spawn_fn spawnee_fn,
-                 uintptr_t env)
+                 rust_boxed_closure *envptr,
+                 void *argptr)
 {
     LOG(this, task, "starting task from fn 0x%" PRIxPTR
-        " with env 0x%" PRIxPTR, spawnee_fn, env);
+        " with env 0x%" PRIxPTR " and arg 0x%" PRIxPTR,
+        spawnee_fn, envptr, argptr);
 
     I(sched, stk->data != NULL);
 
@@ -386,7 +380,8 @@ rust_task::start(spawn_fn spawnee_fn,
     spawn_args *a = (spawn_args *)sp;
 
     a->task = this;
-    a->envptr = env;
+    a->envptr = envptr;
+    a->argptr = argptr;
     a->f = spawnee_fn;
 
     ctx.call((void *)task_start_wrapper, a, sp);
index 2c8e9809c7abd68ec256c786e31f27392fffae53..6be28f41574c356c18dee2cf2ffaaef99ff048f8 100644 (file)
@@ -21,7 +21,17 @@ struct chan_handle {
     rust_port_id port;
 };
 
-typedef void (*CDECL spawn_fn)(uintptr_t, uintptr_t);
+struct rust_closure {
+    const type_desc *td;
+    // ... see trans_closure.rs for full description ...
+};
+
+struct rust_boxed_closure {
+    intptr_t ref_count;
+    rust_closure closure;
+};
+
+typedef void (*CDECL spawn_fn)(void*, rust_boxed_closure*, void *);
 
 struct rust_box;
 
@@ -135,7 +145,8 @@ rust_task : public kernel_owned<rust_task>, rust_cond
     ~rust_task();
 
     void start(spawn_fn spawnee_fn,
-               uintptr_t args);
+               rust_boxed_closure *env,
+               void *args);
     void start();
     bool running();
     bool blocked();
index 644a23f28b1b92b2913a7d1b2e272d42360f81b5..7bfa06fdc99477c79e6473fac1c96ada45a740f9 100644 (file)
@@ -39,7 +39,7 @@ rust_domain_test::run() {
     return true;
 }
 
-void task_entry(uintptr_t retptr, uintptr_t env) {
+void task_entry(void *, rust_boxed_closure *, void *) {
     printf("task entry\n");
 }
 
@@ -47,7 +47,7 @@ void
 rust_task_test::worker::run() {
     rust_task_id root_id = kernel->create_task(NULL, "main");
     rust_task *root_task = kernel->get_task_by_id(root_id);
-    root_task->start(&task_entry, (uintptr_t)NULL);
+    root_task->start(&task_entry, NULL, NULL);
     root_task->sched->start_main_loop();
 }
 
index 3a08606f47ec890dabf2b0c472636c6625e7ab90..500189a0bc6f6818c239345036b6838b1afe0a86 100644 (file)
 #[test]
 #[ignore(cfg(target_os = "win32"))]
 fn test_unsupervise() {
-    fn f(&&_i: ()) { task::unsupervise(); fail; }
-    task::spawn((), f);
+    fn f() { task::unsupervise(); fail; }
+    task::spawn {|| f};
 }
 
 #[test]
 fn test_lib_spawn() {
-    fn foo(&&_i: ()) { #error("Hello, World!"); }
-    task::spawn((), foo);
+    fn foo() { #error("Hello, World!"); }
+    task::spawn {|| foo};
 }
 
 #[test]
 fn test_lib_spawn2() {
-    fn foo(&&x: int) { assert (x == 42); }
-    task::spawn(42, foo);
+    fn foo(x: int) { assert (x == 42); }
+    task::spawn {|| foo(42);};
 }
 
 #[test]
 fn test_join_chan() {
-    fn winner(&&_i: ()) { }
+    fn winner() { }
 
-    let p = comm::port();
-    task::spawn_notify((), winner, comm::chan(p));
-    let s = comm::recv(p);
-    #error("received task status message");
-    log(error, s);
-    alt s {
-      task::exit(_, task::tr_success.) {/* yay! */ }
+    let t = task::spawn_joinable {|| winner();};
+    alt task::join(t) {
+      task::tr_success. {/* yay! */ }
       _ { fail "invalid task status received" }
     }
 }
@@ -46,32 +42,18 @@ fn winner(&&_i: ()) { }
 #[test]
 #[ignore(cfg(target_os = "win32"))]
 fn test_join_chan_fail() {
-    fn failer(&&_i: ()) { task::unsupervise(); fail }
+    fn failer() { task::unsupervise(); fail }
 
-    let p = comm::port();
-    task::spawn_notify((), failer, comm::chan(p));
-    let s = comm::recv(p);
-    #error("received task status message");
-    log(error, s);
-    alt s {
-      task::exit(_, task::tr_failure.) {/* yay! */ }
+    let t = task::spawn_joinable {|| failer();};
+    alt task::join(t) {
+      task::tr_failure. {/* yay! */ }
       _ { fail "invalid task status received" }
     }
 }
 
 #[test]
-fn test_join_convenient() {
-    fn winner(&&_i: ()) { }
-    let handle = task::spawn_joinable((), winner);
-    assert (task::tr_success == task::join(handle));
-}
-
-#[test]
-#[ignore]
 fn spawn_polymorphic() {
-    // FIXME #1038: Can't spawn palymorphic functions
-    /*fn foo<T: send>(x: T) { log(error, x); }
-
-    task::spawn(true, foo);
-    task::spawn(42, foo);*/
+    fn foo<send T>(x: T) { log(error, x); }
+    task::spawn {|| foo(true);}
+    task::spawn {|| foo(42);}
 }