From 51e1ce292d0a64630df1764bb3f71b885aff7116 Mon Sep 17 00:00:00 2001 From: Eric Holk Date: Wed, 18 May 2011 11:38:41 -0700 Subject: [PATCH 1/8] Added a couple of test cases for sending messages. One works as expected, the other succeeds unexpectedly. --- src/test/run-fail/trivial-message2.rs | 14 ++++++++++++++ src/test/run-pass/trivial-message.rs | 15 +++++++++++++++ 2 files changed, 29 insertions(+) create mode 100644 src/test/run-fail/trivial-message2.rs create mode 100644 src/test/run-pass/trivial-message.rs diff --git a/src/test/run-fail/trivial-message2.rs b/src/test/run-fail/trivial-message2.rs new file mode 100644 index 0000000000000..d5404c8f6f054 --- /dev/null +++ b/src/test/run-fail/trivial-message2.rs @@ -0,0 +1,14 @@ +/* + This program should hang on the r <- po line. + */ + +fn main() { + let port[int] po = port(); + let chan[int] ch = chan(po); + + auto r <- po; + + ch <| 42; + + log_err r; +} diff --git a/src/test/run-pass/trivial-message.rs b/src/test/run-pass/trivial-message.rs new file mode 100644 index 0000000000000..2e08da8be745d --- /dev/null +++ b/src/test/run-pass/trivial-message.rs @@ -0,0 +1,15 @@ +/* + This is about the simplest program that can successfully send a + message. + */ + +fn main() { + let port[int] po = port(); + let chan[int] ch = chan(po); + + ch <| 42; + + auto r <- po; + + log_err r; +} From 2b124a81409a00e9e00a4fdb02c16ff4e1f9b534 Mon Sep 17 00:00:00 2001 From: Eric Holk Date: Tue, 17 May 2011 17:24:55 -0700 Subject: [PATCH 2/8] Started working on translating spawn. It correctly generates the task name in the case that it is not provided. --- src/comp/middle/trans.rs | 42 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 41 insertions(+), 1 deletion(-) diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs index e1b0332a60738..cc8ec47829e34 100644 --- a/src/comp/middle/trans.rs +++ b/src/comp/middle/trans.rs @@ -5543,6 +5543,10 @@ fn trans_expr(&@block_ctxt cx, &@ast::expr e) -> result { ret trans_recv(cx, lhs, rhs, ann); } + case (ast::expr_spawn(?dom, ?name, ?func, ?args, ?ann)) { + ret trans_spawn(dom, name, func, args, ann); + } + case (_) { // The expression is an lvalue. Fall through. } @@ -5879,9 +5883,45 @@ fn trans_chan(&@block_ctxt cx, &@ast::expr e, &ast::ann ann) -> result { ret res(bcx, chan_val); } +fn trans_spawn(&ast::spawn_dom dom, &option::t[str] name, + &@ast::expr func, &vec[@ast::expr] args, + &ast::ann ann) -> result { + // Make the task name + auto tname = alt(name) { + case(none) { + auto argss = vec::map(common::expr_to_str, args); + #fmt("%s(%s)", + common::expr_to_str(func), + str::connect(argss, ", ")) + } + case(some[str](?n)) { + n + } + }; + + // dump a bunch of information + log_err "Spawn"; + //log_err dom; + log_err #fmt("task name: %s", tname); + + // Generate code + alt(dom) { + case(ast::dom_implicit) { + // TODO + log_err "Spawning implicit domain tasks is not implemented."; + fail; + } + + case(ast::dom_thread) { + // TODO + log_err "Spawining new thread tasks is not implemented."; + fail; + } + } +} + fn trans_send(&@block_ctxt cx, &@ast::expr lhs, &@ast::expr rhs, &ast::ann ann) -> result { - auto bcx = cx; auto chn = trans_expr(bcx, lhs); bcx = chn.bcx; From d6338a8c1563fe7d7a9a1ea3de0692eb0e2560ac Mon Sep 17 00:00:00 2001 From: Eric Holk Date: Thu, 19 May 2011 14:07:59 -0700 Subject: [PATCH 3/8] Added some comments to trans_spawn that sort of explains what needs to happen --- src/comp/middle/trans.rs | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs index cc8ec47829e34..bca588a6336ae 100644 --- a/src/comp/middle/trans.rs +++ b/src/comp/middle/trans.rs @@ -5901,10 +5901,24 @@ fn trans_spawn(&ast::spawn_dom dom, &option::t[str] name, // dump a bunch of information log_err "Spawn"; - //log_err dom; log_err #fmt("task name: %s", tname); // Generate code + // + // This is a several step process. The following things need to happen + // (not necessarily in order): + // + // 1. Evaluate all the arguments to the spawnee. + // + // 2. Alloca a tuple that holds these arguments (they must be in reverse + // order, so that they match the expected stack layout for the spawnee) + // + // 3. Fill the tutple with the arguments we evaluated. + // + // 4. Pass a pointer to the spawnee function and the argument tuple to + // upcall_start_task. + + alt(dom) { case(ast::dom_implicit) { // TODO From 219351e4b9dd98977b6784d73acb68dc1be24585 Mon Sep 17 00:00:00 2001 From: Eric Holk Date: Thu, 19 May 2011 18:36:40 -0700 Subject: [PATCH 4/8] A little closure towards translating spawn. We're about ready to do the upcall, except that rustc segfaults. --- src/comp/middle/trans.rs | 51 ++++++++++++++++++++++++++++++++++++---- 1 file changed, 47 insertions(+), 4 deletions(-) diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs index bca588a6336ae..054e6114a7171 100644 --- a/src/comp/middle/trans.rs +++ b/src/comp/middle/trans.rs @@ -5544,7 +5544,7 @@ fn trans_expr(&@block_ctxt cx, &@ast::expr e) -> result { } case (ast::expr_spawn(?dom, ?name, ?func, ?args, ?ann)) { - ret trans_spawn(dom, name, func, args, ann); + ret trans_spawn(cx, dom, name, func, args, ann); } case (_) { @@ -5883,9 +5883,12 @@ fn trans_chan(&@block_ctxt cx, &@ast::expr e, &ast::ann ann) -> result { ret res(bcx, chan_val); } -fn trans_spawn(&ast::spawn_dom dom, &option::t[str] name, +fn trans_spawn(&@block_ctxt cx, + &ast::spawn_dom dom, &option::t[str] name, &@ast::expr func, &vec[@ast::expr] args, &ast::ann ann) -> result { + auto bcx = cx; + // Make the task name auto tname = alt(name) { case(none) { @@ -5913,22 +5916,62 @@ fn trans_spawn(&ast::spawn_dom dom, &option::t[str] name, // 2. Alloca a tuple that holds these arguments (they must be in reverse // order, so that they match the expected stack layout for the spawnee) // - // 3. Fill the tutple with the arguments we evaluated. + // 3. Fill the tuple with the arguments we evaluated. // // 4. Pass a pointer to the spawnee function and the argument tuple to // upcall_start_task. + // Translate the arguments, remembering their types and where the values + // ended up. + let vec[ty::t] arg_tys = []; + let vec[ValueRef] arg_vals = []; + for(@ast::expr e in args) { + auto arg = trans_expr(bcx, e); + + bcx = arg.bcx; + + vec::push[ValueRef](arg_vals, arg.val); + vec::push[ty::t](arg_tys, + ty::expr_ty(cx.fcx.lcx.ccx.tcx, + e)); + } + + // Make the tuple. We have to reverse the types first though. + vec::reverse[ty::t](arg_tys); + vec::reverse[ValueRef](arg_vals); + auto args_ty = ty::mk_imm_tup(cx.fcx.lcx.ccx.tcx, arg_tys); + // Allocate and fill the tuple. + auto llargs = alloc_ty(bcx, args_ty); + + auto i = vec::len[ValueRef](arg_vals) - 1u; + for(ValueRef v in arg_vals) { + // log_err #fmt("ty(llargs) = %s", + // val_str(bcx.fcx.lcx.ccx.tn, llargs.val)); + auto target = bcx.build.GEP(llargs.val, [C_int(0), C_int(i as int)]); + + // log_err #fmt("ty(v) = %s", val_str(bcx.fcx.lcx.ccx.tn, v)); + // log_err #fmt("ty(target) = %s", + // val_str(bcx.fcx.lcx.ccx.tn, target)); + + bcx.build.Store(v, target); + + i -= 1u; + } + + // Now we're ready to do the upcall. + alt(dom) { case(ast::dom_implicit) { // TODO log_err "Spawning implicit domain tasks is not implemented."; - fail; + //fail; } case(ast::dom_thread) { // TODO log_err "Spawining new thread tasks is not implemented."; + // TODO: for now use the normal unimpl thing. fail; } } From 41b39799906fd4254d702078c98f7196145dfb12 Mon Sep 17 00:00:00 2001 From: Eric Holk Date: Fri, 20 May 2011 14:07:49 -0700 Subject: [PATCH 5/8] Nicer printer of LLVM array types. --- src/comp/lib/llvm.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/comp/lib/llvm.rs b/src/comp/lib/llvm.rs index 6774d224aafe3..35a1d990ab439 100644 --- a/src/comp/lib/llvm.rs +++ b/src/comp/lib/llvm.rs @@ -1539,7 +1539,10 @@ fn type_to_str_inner(type_names names, ret s; } - case (10) { ret "Array"; } + case (10) { + auto el_ty = llvm::LLVMGetElementType(ty); + ret "[" + type_to_str_inner(names, outer, el_ty) + "]"; + } case (11) { let uint i = 0u; From d01948cd076b0266607277aea8f729d36b925053 Mon Sep 17 00:00:00 2001 From: Eric Holk Date: Fri, 20 May 2011 14:29:26 -0700 Subject: [PATCH 6/8] Called the new_task upcall. There are refcount issues though. --- src/comp/back/upcall.rs | 2 +- src/comp/middle/trans.rs | 24 +++++++++++++++++++++++- src/rt/rust_upcall.cpp | 5 +++-- 3 files changed, 27 insertions(+), 4 deletions(-) diff --git a/src/comp/back/upcall.rs b/src/comp/back/upcall.rs index b1b533c84d6a8..df7b4a4a2d028 100644 --- a/src/comp/back/upcall.rs +++ b/src/comp/back/upcall.rs @@ -122,7 +122,7 @@ fn declare_upcalls(type_names tn, ModuleRef llmod) -> @upcalls { [T_ptr(T_crate(tn)), T_size_t(), T_size_t(), T_size_t(), T_ptr(T_ptr(T_tydesc(tn)))], T_ptr(T_tydesc(tn))), - new_task=d("new_task", [T_ptr(T_i8())], T_taskptr(tn)), + new_task=d("new_task", [T_ptr(T_str())], T_taskptr(tn)), start_task=d("start_task", [T_taskptr(tn), T_int(), T_int(), T_int(), T_size_t()], T_taskptr(tn)), diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs index 054e6114a7171..8552aa4e6fe47 100644 --- a/src/comp/middle/trans.rs +++ b/src/comp/middle/trans.rs @@ -5903,7 +5903,8 @@ fn trans_spawn(&@block_ctxt cx, }; // dump a bunch of information - log_err "Spawn"; + log_err "Translating Spawn " + + "(The compiled program is not actually running yet, don't worry!"; log_err #fmt("task name: %s", tname); // Generate code @@ -5920,6 +5921,8 @@ fn trans_spawn(&@block_ctxt cx, // // 4. Pass a pointer to the spawnee function and the argument tuple to // upcall_start_task. + // + // 5. Oh yeah, we have to create the task before we start it... // Translate the arguments, remembering their types and where the values // ended up. @@ -5961,6 +5964,23 @@ fn trans_spawn(&@block_ctxt cx, // Now we're ready to do the upcall. + // But first, we'll create a task. + let ValueRef lltname = C_str(bcx.fcx.lcx.ccx, tname); + log_err #fmt("ty(new_task) = %s", + val_str(bcx.fcx.lcx.ccx.tn, + bcx.fcx.lcx.ccx.upcalls.new_task)); + log_err #fmt("ty(lltaskptr) = %s", + val_str(bcx.fcx.lcx.ccx.tn, + bcx.fcx.lltaskptr)); + log_err #fmt("ty(lltname) = %s", + val_str(bcx.fcx.lcx.ccx.tn, + lltname)); + + log_err "Building upcall_new_task"; + auto new_task = bcx.build.Call(bcx.fcx.lcx.ccx.upcalls.new_task, + [bcx.fcx.lltaskptr, lltname]); + log_err "Done"; + alt(dom) { case(ast::dom_implicit) { // TODO @@ -5975,6 +5995,8 @@ fn trans_spawn(&@block_ctxt cx, fail; } } + + ret res(bcx, new_task); } fn trans_send(&@block_ctxt cx, &@ast::expr lhs, &@ast::expr rhs, diff --git a/src/rt/rust_upcall.cpp b/src/rt/rust_upcall.cpp index 6bdfaef96e133..f95a6e3ebeeb2 100644 --- a/src/rt/rust_upcall.cpp +++ b/src/rt/rust_upcall.cpp @@ -538,10 +538,11 @@ upcall_get_type_desc(rust_task *task, } extern "C" CDECL rust_task * -upcall_new_task(rust_task *spawner, const char *name) { +upcall_new_task(rust_task *spawner, rust_vec *name) { + // name is a rust string structure. LOG_UPCALL_ENTRY(spawner); rust_dom *dom = spawner->dom; - rust_task *task = dom->create_task(spawner, name); + rust_task *task = dom->create_task(spawner, (const char *)name->data); return task; } From 0de27ce8bd6e17496c7557f189b97d5ce824566d Mon Sep 17 00:00:00 2001 From: Eric Holk Date: Fri, 20 May 2011 16:45:51 -0700 Subject: [PATCH 7/8] Translated start_task, but it fails on spp == align_down(spp) --- src/comp/back/upcall.rs | 14 ++++++++++++-- src/comp/middle/trans.rs | 42 ++++++++++++++++++++++++++++++++++++++++ src/rt/rust_upcall.cpp | 9 ++++----- 3 files changed, 58 insertions(+), 7 deletions(-) diff --git a/src/comp/back/upcall.rs b/src/comp/back/upcall.rs index df7b4a4a2d028..7f695518ed4cc 100644 --- a/src/comp/back/upcall.rs +++ b/src/comp/back/upcall.rs @@ -123,8 +123,8 @@ fn declare_upcalls(type_names tn, ModuleRef llmod) -> @upcalls { T_size_t(), T_ptr(T_ptr(T_tydesc(tn)))], T_ptr(T_tydesc(tn))), new_task=d("new_task", [T_ptr(T_str())], T_taskptr(tn)), - start_task=d("start_task", [T_taskptr(tn), T_int(), T_int(), - T_int(), T_size_t()], + start_task=d("start_task", [T_taskptr(tn), + T_int(), T_int(), T_size_t()], T_taskptr(tn)), new_thread=d("new_thread", [T_ptr(T_i8())], T_taskptr(tn)), start_thread=d("start_thread", [T_taskptr(tn), T_int(), T_int(), @@ -133,3 +133,13 @@ fn declare_upcalls(type_names tn, ModuleRef llmod) -> @upcalls { ); } +// +// Local Variables: +// mode: C++ +// fill-column: 78; +// indent-tabs-mode: nil +// c-basic-offset: 4 +// buffer-file-coding-system: utf-8-unix +// compile-command: "make -k -C .. 2>&1 | sed -e 's/\\/x\\//x:\\//g'"; +// End: +// diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs index 8552aa4e6fe47..12087e1a76379 100644 --- a/src/comp/middle/trans.rs +++ b/src/comp/middle/trans.rs @@ -5981,6 +5981,47 @@ fn trans_spawn(&@block_ctxt cx, [bcx.fcx.lltaskptr, lltname]); log_err "Done"; + // Okay, start the task. + // First we find the function + auto fnptr = trans_lval(bcx, func).res; + bcx = fnptr.bcx; + + auto num_args = vec::len[@ast::expr](args); + + auto llfnptr = bcx.build.GEP(fnptr.val, + [C_int(0), C_int(0)]); + log_err "Casting llfnptr"; + auto llfnptr_i = bcx.build.PointerCast(llfnptr, + T_int()); + log_err "Cassting llargs"; + auto llargs_i = bcx.build.PointerCast(llargs.val, + T_int()); + + log_err "Building call to start_task"; + log_err #fmt("ty(start_task) = %s", + val_str(bcx.fcx.lcx.ccx.tn, + bcx.fcx.lcx.ccx.upcalls.start_task)); + log_err #fmt("ty(lltaskptr) = %s", + val_str(bcx.fcx.lcx.ccx.tn, + bcx.fcx.lltaskptr)); + log_err #fmt("ty(new_task) = %s", + val_str(bcx.fcx.lcx.ccx.tn, + new_task)); + log_err #fmt("ty(llfnptr) = %s", + val_str(bcx.fcx.lcx.ccx.tn, + llfnptr_i)); + log_err #fmt("ty(llargs) = %s", + val_str(bcx.fcx.lcx.ccx.tn, + llargs_i)); + log_err #fmt("ty(num_args) = %s", + val_str(bcx.fcx.lcx.ccx.tn, + C_int(num_args as int))); + bcx.build.Call(bcx.fcx.lcx.ccx.upcalls.start_task, + [bcx.fcx.lltaskptr, new_task, + llfnptr_i, llargs_i, C_int(num_args as int)]); + log_err "Done"; + + /* alt(dom) { case(ast::dom_implicit) { // TODO @@ -5995,6 +6036,7 @@ fn trans_spawn(&@block_ctxt cx, fail; } } + */ ret res(bcx, new_task); } diff --git a/src/rt/rust_upcall.cpp b/src/rt/rust_upcall.cpp index f95a6e3ebeeb2..48d6a67ce44dc 100644 --- a/src/rt/rust_upcall.cpp +++ b/src/rt/rust_upcall.cpp @@ -549,20 +549,19 @@ upcall_new_task(rust_task *spawner, rust_vec *name) { extern "C" CDECL rust_task * upcall_start_task(rust_task *spawner, rust_task *task, - uintptr_t exit_task_glue, uintptr_t spawnee_fn, + uintptr_t args, size_t callsz) { LOG_UPCALL_ENTRY(spawner); rust_dom *dom = spawner->dom; DLOG(dom, task, "upcall start_task(task %s @0x%" PRIxPTR - " exit_task_glue 0x%" PRIxPTR ", spawnee 0x%" PRIxPTR - ", callsz %" PRIdPTR ")", task->name, task, exit_task_glue, + ", callsz %" PRIdPTR ")", task->name, task, spawnee_fn, callsz); - task->start(exit_task_glue, spawnee_fn, - spawner->rust_sp, callsz); + task->start((uintptr_t)rust_new_exit_task_glue, spawnee_fn, + args, callsz); return task; } From 3dd2877975efd0dd9ed8debe202c8e9d48810f48 Mon Sep 17 00:00:00 2001 From: Eric Holk Date: Fri, 20 May 2011 16:47:48 -0700 Subject: [PATCH 8/8] Using the right mode... --- src/comp/back/upcall.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/comp/back/upcall.rs b/src/comp/back/upcall.rs index 7f695518ed4cc..b892399a3b8e5 100644 --- a/src/comp/back/upcall.rs +++ b/src/comp/back/upcall.rs @@ -135,7 +135,7 @@ fn declare_upcalls(type_names tn, ModuleRef llmod) -> @upcalls { // // Local Variables: -// mode: C++ +// mode: rust // fill-column: 78; // indent-tabs-mode: nil // c-basic-offset: 4