about summary refs log tree commit diff
diff options
context:
space:
mode:
authorJeffrey Yasskin <jyasskin@gmail.com>2010-08-08 19:24:35 -0700
committerJeffrey Yasskin <jyasskin@gmail.com>2010-08-09 11:43:16 +0200
commitb71340552fa0caa870877f87a1273e8d4c91efe6 (patch)
treea1a1883cded2c8541a817d41d91c2002a926207b
parentdf75a968c56935cca1c1482a8703eca82c607c62 (diff)
downloadrust-b71340552fa0caa870877f87a1273e8d4c91efe6.tar.gz
rust-b71340552fa0caa870877f87a1273e8d4c91efe6.zip
Add names to tasks and domains. These can either be an explicit literal string
after the "spawn" keyword, or implicitly the call expression used to start the
spawn.
-rw-r--r--doc/rust.texi16
-rw-r--r--src/boot/fe/ast.ml5
-rw-r--r--src/boot/fe/pexp.ml29
-rw-r--r--src/boot/me/alias.ml2
-rw-r--r--src/boot/me/effect.ml2
-rw-r--r--src/boot/me/layout.ml2
-rw-r--r--src/boot/me/trans.ml11
-rw-r--r--src/boot/me/type.ml2
-rw-r--r--src/boot/me/typestate.ml4
-rw-r--r--src/boot/me/walk.ml2
-rw-r--r--src/rt/rust.cpp2
-rw-r--r--src/rt/rust_dom.cpp66
-rw-r--r--src/rt/rust_dom.h5
-rw-r--r--src/rt/rust_task.cpp43
-rw-r--r--src/rt/rust_task.h5
-rw-r--r--src/rt/rust_upcall.cpp50
16 files changed, 151 insertions, 95 deletions
diff --git a/doc/rust.texi b/doc/rust.texi
index 3aa079d705f..63181f8846a 100644
--- a/doc/rust.texi
+++ b/doc/rust.texi
@@ -2822,12 +2822,15 @@ x.y = z + 2;
 @c * Ref.Stmt.Spawn::               Statements creating new tasks.
 @cindex Spawn statement
 
-A @code{spawn} statement consists of keyword @code{spawn}, followed by a
-normal @emph{call} statement (@pxref{Ref.Stmt.Call}).  A @code{spawn}
-statement causes the runtime to construct a new task executing the called
-function.  The called function is referred to as the @dfn{entry function} for
-the spawned task, and its arguments are copied from the spawning task to the
-spawned task before the spawned task begins execution.
+A @code{spawn} statement consists of keyword @code{spawn}, followed by
+an optional literal string naming the new task and then a normal
+@emph{call} statement (@pxref{Ref.Stmt.Call}).  A @code{spawn}
+statement causes the runtime to construct a new task executing the
+called function with the given name.  The called function is referred
+to as the @dfn{entry function} for the spawned task, and its arguments
+are copied from the spawning task to the spawned task before the
+spawned task begins execution.  If no explicit name is present, the
+task is implicitly named with the string of the call statement.
 
 Functions taking alias-slot arguments, or returning non-nil values, cannot be
 spawned. Iterators cannot be spawned.
@@ -2843,6 +2846,7 @@ fn helper(chan[u8] out) @{
 
 let port[u8] out;
 let task p = spawn helper(chan(out));
+let task p2 = spawn "my_helper" helper(chan(out));
 // let task run, do other things.
 auto result <- out;
 
diff --git a/src/boot/fe/ast.ml b/src/boot/fe/ast.ml
index efbd62ae202..8fc952a5150 100644
--- a/src/boot/fe/ast.ml
+++ b/src/boot/fe/ast.ml
@@ -199,7 +199,7 @@ and tup_input = (mutability * atom)
 and stmt' =
 
   (* lval-assigning stmts. *)
-    STMT_spawn of (lval * domain * lval * (atom array))
+    STMT_spawn of (lval * domain * string * lval * (atom array))
   | STMT_new_rec of (lval * (rec_input array) * lval option)
   | STMT_new_tup of (lval * (tup_input array))
   | STMT_new_vec of (lval * mutability * atom array)
@@ -936,10 +936,11 @@ and fmt_stmt_body (ff:Format.formatter) (s:stmt) : unit =
             fmt ff ";"
           end
 
-      | STMT_spawn (dst, domain, fn, args) ->
+      | STMT_spawn (dst, domain, name, fn, args) ->
           fmt_lval ff dst;
           fmt ff " = spawn ";
           fmt_domain ff domain;
+          fmt_str ff ("\"" ^ name ^ "\"");
           fmt_lval ff fn;
           fmt_atoms ff args;
           fmt ff ";";
diff --git a/src/boot/fe/pexp.ml b/src/boot/fe/pexp.ml
index 3e17e0e49e7..75983c7f837 100644
--- a/src/boot/fe/pexp.ml
+++ b/src/boot/fe/pexp.ml
@@ -18,7 +18,7 @@ open Parser;;
 
 type pexp' =
     PEXP_call of (pexp * pexp array)
-  | PEXP_spawn of (Ast.domain * pexp)
+  | PEXP_spawn of (Ast.domain * string * pexp)
   | PEXP_bind of (pexp * pexp option array)
   | PEXP_rec of ((Ast.ident * Ast.mutability * pexp) array * pexp option)
   | PEXP_tup of ((Ast.mutability * pexp) array)
@@ -558,9 +558,27 @@ and parse_bottom_pexp (ps:pstate) : pexp =
               THREAD -> bump ps; Ast.DOMAIN_thread
             | _ -> Ast.DOMAIN_local
         in
-        let pexp = ctxt "spawn [domain] pexp: init call" parse_pexp ps in
+          (* Spawns either have an explicit literal string for the spawned
+             task's name, or the task is named as the entry call
+             expression. *)
+        let explicit_name =
+          match peek ps with
+              LIT_STR s -> bump ps; Some s
+            | _ -> None
+        in
+        let pexp =
+          ctxt "spawn [domain] [name] pexp: init call" parse_pexp ps
+        in
         let bpos = lexpos ps in
-          span ps apos bpos (PEXP_spawn (domain, pexp))
+        let name =
+          match explicit_name with
+              Some s -> s
+                (* FIXME: string_of_span returns a string like
+                   "./driver.rs:10:16 - 11:52", not the actual text at those
+                   characters *)
+            | None -> Session.string_of_span { lo = apos; hi = bpos }
+        in
+          span ps apos bpos (PEXP_spawn (domain, name, pexp))
 
     | BIND ->
         let apos = lexpos ps in
@@ -1183,7 +1201,7 @@ and desugar_expr_init
           let bind_stmt = ss (Ast.STMT_bind (dst_lval, fn_lval, arg_atoms)) in
             ac [ fn_stmts; arg_stmts; [| bind_stmt |] ]
 
-      | PEXP_spawn (domain, sub) ->
+      | PEXP_spawn (domain, name, sub) ->
           begin
             match sub.node with
                 PEXP_call (fn, args) ->
@@ -1191,7 +1209,8 @@ and desugar_expr_init
                   let (arg_stmts, arg_atoms) = desugar_expr_atoms ps args in
                   let fn_lval = atom_lval ps fn_atom in
                   let spawn_stmt =
-                    ss (Ast.STMT_spawn (dst_lval, domain, fn_lval, arg_atoms))
+                    ss (Ast.STMT_spawn
+                          (dst_lval, domain, name, fn_lval, arg_atoms))
                   in
                     ac [ fn_stmts; arg_stmts; [| spawn_stmt |] ]
               | _ -> raise (err "non-call spawn" ps)
diff --git a/src/boot/me/alias.ml b/src/boot/me/alias.ml
index 94d34fb2df0..27575324171 100644
--- a/src/boot/me/alias.ml
+++ b/src/boot/me/alias.ml
@@ -59,7 +59,7 @@ let alias_analysis_visitor
              * survive 'into' a sub-block (those formed during iteration)
              * need to be handled in this module.  *)
             Ast.STMT_call (dst, callee, args)
-          | Ast.STMT_spawn (dst, _, callee, args)
+          | Ast.STMT_spawn (dst, _, _, callee, args)
             -> alias_call_args dst callee args
 
           | Ast.STMT_send (_, src) -> alias src
diff --git a/src/boot/me/effect.ml b/src/boot/me/effect.ml
index 79868defa41..73797409d31 100644
--- a/src/boot/me/effect.ml
+++ b/src/boot/me/effect.ml
@@ -62,7 +62,7 @@ let mutability_checking_visitor
       match s.node with
             Ast.STMT_copy (lv_dst, _)
           | Ast.STMT_call (lv_dst, _, _)
-          | Ast.STMT_spawn (lv_dst, _, _, _)
+          | Ast.STMT_spawn (lv_dst, _, _, _, _)
           | Ast.STMT_recv (lv_dst, _)
           | Ast.STMT_bind (lv_dst, _, _)
           | Ast.STMT_new_rec (lv_dst, _, _)
diff --git a/src/boot/me/layout.ml b/src/boot/me/layout.ml
index a9358795ed3..1df37f0f9e2 100644
--- a/src/boot/me/layout.ml
+++ b/src/boot/me/layout.ml
@@ -400,7 +400,7 @@ let layout_visitor
       let callees =
         match s.node with
             Ast.STMT_call (_, lv, _)
-          | Ast.STMT_spawn (_, _, lv, _) -> [| lv |]
+          | Ast.STMT_spawn (_, _, _, lv, _) -> [| lv |]
           | Ast.STMT_check (_, calls) -> Array.map (fun (lv, _) -> lv) calls
           | _ -> [| |]
       in
diff --git a/src/boot/me/trans.ml b/src/boot/me/trans.ml
index b708bb268ff..01a89c56588 100644
--- a/src/boot/me/trans.ml
+++ b/src/boot/me/trans.ml
@@ -2128,10 +2128,12 @@ let trans_visitor
       ((*initializing*)_:bool)
       (dst:Ast.lval)
       (domain:Ast.domain)
+      (name:string)
       (fn_lval:Ast.lval)
       (args:Ast.atom array)
       : unit =
     let (task_cell, _) = trans_lval_init dst in
+    let runtime_name = trans_static_string name in
     let (fptr_operand, fn_ty) = trans_callee fn_lval in
     (*let fn_ty_params = [| |] in*)
     let _ =
@@ -2165,7 +2167,7 @@ let trans_visitor
         match domain with
             Ast.DOMAIN_thread ->
               begin
-                trans_upcall "upcall_new_thread" new_task [| |];
+                trans_upcall "upcall_new_thread" new_task [| runtime_name |];
                 copy_fn_args false true (CLONE_all new_task) call;
                 trans_upcall "upcall_start_thread" task_cell
                   [|
@@ -2177,7 +2179,7 @@ let trans_visitor
             end
          | _ ->
              begin
-                 trans_upcall "upcall_new_task" new_task [| |];
+                 trans_upcall "upcall_new_task" new_task [| runtime_name |];
                  copy_fn_args false true (CLONE_chan new_task) call;
                  trans_upcall "upcall_start_task" task_cell
                    [|
@@ -4496,8 +4498,9 @@ let trans_visitor
       | Ast.STMT_send (chan,src) ->
           trans_send chan src
 
-      | Ast.STMT_spawn (dst, domain, plv, args) ->
-          trans_spawn (maybe_init stmt.id "spawn" dst) dst domain plv args
+      | Ast.STMT_spawn (dst, domain, name, plv, args) ->
+          trans_spawn (maybe_init stmt.id "spawn" dst) dst
+            domain name plv args
 
       | Ast.STMT_recv (dst, chan) ->
           trans_recv (maybe_init stmt.id "recv" dst) dst chan
diff --git a/src/boot/me/type.ml b/src/boot/me/type.ml
index 23210ea1ff8..b2d5a6221d0 100644
--- a/src/boot/me/type.ml
+++ b/src/boot/me/type.ml
@@ -692,7 +692,7 @@ let check_stmt (cx:Semant.ctxt) : (fn_ctx -> Ast.stmt -> unit) =
     and check_stmt (stmt:Ast.stmt) : unit =
       check_ret stmt;
       match stmt.Common.node with
-          Ast.STMT_spawn (dst, _, callee, args) ->
+          Ast.STMT_spawn (dst, _, _, callee, args) ->
             infer_lval Ast.TY_task dst;
             demand Ast.TY_nil (check_fn callee args)
 
diff --git a/src/boot/me/typestate.ml b/src/boot/me/typestate.ml
index baf4a54398c..207029909de 100644
--- a/src/boot/me/typestate.ml
+++ b/src/boot/me/typestate.ml
@@ -664,7 +664,7 @@ let condition_assigning_visitor
             let precond = Array.append dst_init src_init in
               raise_pre_post_cond s.id precond;
 
-        | Ast.STMT_spawn (dst, _, lv, args)
+        | Ast.STMT_spawn (dst, _, _, lv, args)
         | Ast.STMT_call (dst, lv, args) ->
             raise_dst_init_precond_if_writing_through s.id dst;
             visit_callable_pre s.id (lval_slots cx dst) lv args
@@ -1350,7 +1350,7 @@ let lifecycle_visitor
         match s.node with
             Ast.STMT_copy (lv_dst, _)
           | Ast.STMT_call (lv_dst, _, _)
-          | Ast.STMT_spawn (lv_dst, _, _, _)
+          | Ast.STMT_spawn (lv_dst, _, _, _, _)
           | Ast.STMT_recv (lv_dst, _)
           | Ast.STMT_bind (lv_dst, _, _)
           | Ast.STMT_new_rec (lv_dst, _, _)
diff --git a/src/boot/me/walk.ml b/src/boot/me/walk.ml
index 0e65406aec3..cadfd66b967 100644
--- a/src/boot/me/walk.ml
+++ b/src/boot/me/walk.ml
@@ -451,7 +451,7 @@ and walk_stmt
           walk_lval v f;
           Array.iter (walk_opt_atom v) az
 
-      | Ast.STMT_spawn (dst,_,p,az) ->
+      | Ast.STMT_spawn (dst,_,_,p,az) ->
           walk_lval v dst;
           walk_lval v p;
           Array.iter (walk_atom v) az
diff --git a/src/rt/rust.cpp b/src/rt/rust.cpp
index 9cc2fe4188a..82a19cbcd84 100644
--- a/src/rt/rust.cpp
+++ b/src/rt/rust.cpp
@@ -182,7 +182,7 @@ rust_start(uintptr_t main_fn, rust_crate const *crate, int argc, char **argv)
     int ret;
     {
         rust_srv srv;
-        rust_dom dom(&srv, crate);
+        rust_dom dom(&srv, crate, "main");
         command_line_args args(dom, argc, argv);
 
         dom.log(rust_log::DOM, "startup: %d args", args.argc);
diff --git a/src/rt/rust_dom.cpp b/src/rt/rust_dom.cpp
index 99aaddb2b15..004a10275e4 100644
--- a/src/rt/rust_dom.cpp
+++ b/src/rt/rust_dom.cpp
@@ -5,11 +5,13 @@
 template class ptr_vec<rust_task>;
 
 
-rust_dom::rust_dom(rust_srv *srv, rust_crate const *root_crate) :
+rust_dom::rust_dom(rust_srv *srv, rust_crate const *root_crate,
+                   const char *name) :
     interrupt_flag(0),
     root_crate(root_crate),
     _log(srv, this),
     srv(srv),
+    name(name),
     running_tasks(this),
     blocked_tasks(this),
     dead_tasks(this),
@@ -25,7 +27,7 @@ rust_dom::rust_dom(rust_srv *srv, rust_crate const *root_crate) :
     pthread_attr_setstacksize(&attr, 1024 * 1024);
     pthread_attr_setdetachstate(&attr, true);
 #endif
-    root_task = new (this) rust_task(this, NULL);
+    root_task = new (this) rust_task(this, NULL, name);
 }
 
 static void
@@ -42,23 +44,25 @@ rust_dom::delete_proxies() {
     rust_task *task;
     rust_proxy<rust_task> *task_proxy;
     while (_task_proxies.pop(&task, &task_proxy)) {
-        log(rust_log::TASK, "deleting proxy %" PRIxPTR
-                            " in dom %" PRIxPTR, task_proxy, task_proxy->dom);
+        log(rust_log::TASK,
+            "deleting proxy %" PRIxPTR " in dom %s @0x%" PRIxPTR,
+            task_proxy, task_proxy->dom->name, task_proxy->dom);
         delete task_proxy;
     }
 
     rust_port *port;
     rust_proxy<rust_port> *port_proxy;
     while (_port_proxies.pop(&port, &port_proxy)) {
-        log(rust_log::TASK, "deleting proxy %" PRIxPTR
-                            " in dom %" PRIxPTR, port_proxy, port_proxy->dom);
+        log(rust_log::TASK,
+            "deleting proxy %" PRIxPTR " in dom %s @0x%" PRIxPTR,
+            port_proxy, port_proxy->dom->name, port_proxy->dom);
         delete port_proxy;
     }
 }
 
 rust_dom::~rust_dom() {
     log(rust_log::MEM | rust_log::DOM,
-             "~rust_dom 0x%" PRIxPTR, (uintptr_t)this);
+        "~rust_dom %s @0x%" PRIxPTR, name, (uintptr_t)this);
 
     log(rust_log::TASK, "deleting all proxies");
     delete_proxies();
@@ -124,7 +128,8 @@ rust_dom::logptr(char const *msg, T* ptrval) {
 
 void
 rust_dom::fail() {
-    log(rust_log::DOM, "domain 0x%" PRIxPTR " root task failed", this);
+    log(rust_log::DOM, "domain %s @0x%" PRIxPTR " root task failed",
+        name, this);
     I(this, rval == 0);
     rval = 1;
 }
@@ -133,8 +138,9 @@ void *
 rust_dom::malloc(size_t sz) {
     void *p = srv->malloc(sz);
     I(this, p);
-    log(rust_log::MEM, "0x%" PRIxPTR " rust_dom::malloc(%d) -> 0x%" PRIxPTR,
-        (uintptr_t) this, sz, p);
+    log(rust_log::MEM,
+        "%s @0x%" PRIxPTR " rust_dom::malloc(%d) -> 0x%" PRIxPTR,
+        name, (uintptr_t) this, sz, p);
     return p;
 }
 
@@ -190,8 +196,8 @@ void
 rust_dom::add_task_to_state_vec(ptr_vec<rust_task> *v, rust_task *task)
 {
     log(rust_log::MEM|rust_log::TASK,
-        "adding task 0x%" PRIxPTR " in state '%s' to vec 0x%" PRIxPTR,
-        (uintptr_t)task, state_vec_name(v), (uintptr_t)v);
+        "adding task %s @0x%" PRIxPTR " in state '%s' to vec 0x%" PRIxPTR,
+        task->name, (uintptr_t)task, state_vec_name(v), (uintptr_t)v);
     v->push(task);
 }
 
@@ -200,8 +206,8 @@ void
 rust_dom::remove_task_from_state_vec(ptr_vec<rust_task> *v, rust_task *task)
 {
     log(rust_log::MEM|rust_log::TASK,
-        "removing task 0x%" PRIxPTR " in state '%s' from vec 0x%" PRIxPTR,
-        (uintptr_t)task, state_vec_name(v), (uintptr_t)v);
+        "removing task %s @0x%" PRIxPTR " in state '%s' from vec 0x%" PRIxPTR,
+        task->name, (uintptr_t)task, state_vec_name(v), (uintptr_t)v);
     I(this, (*v)[task->idx] == task);
     v->swap_delete(task);
 }
@@ -229,7 +235,8 @@ rust_dom::reap_dead_tasks() {
 
             dead_tasks.swap_delete(task);
             log(rust_log::TASK,
-                "deleting unreferenced dead task 0x%" PRIxPTR, task);
+                "deleting unreferenced dead task %s @0x%" PRIxPTR,
+                task->name, task);
             delete task;
             continue;
         }
@@ -272,7 +279,7 @@ rust_dom::get_task_proxy(rust_task *task) {
     if (_task_proxies.get(task, &proxy)) {
         return proxy;
     }
-    log(rust_log::COMM, "no proxy for 0x%" PRIxPTR, task);
+    log(rust_log::COMM, "no proxy for %s @0x%" PRIxPTR, task->name, task);
     proxy = new (this) rust_proxy<rust_task> (this, task, false);
     _task_proxies.put(task, proxy);
     return proxy;
@@ -327,7 +334,8 @@ rust_dom::log_state() {
         log(rust_log::TASK, "running tasks:");
         for (size_t i = 0; i < running_tasks.length(); i++) {
             log(rust_log::TASK,
-                "\t task: 0x%" PRIxPTR, running_tasks[i]);
+                "\t task: %s @0x%" PRIxPTR,
+                running_tasks[i]->name, running_tasks[i]);
         }
     }
 
@@ -335,15 +343,17 @@ rust_dom::log_state() {
         log(rust_log::TASK, "blocked tasks:");
         for (size_t i = 0; i < blocked_tasks.length(); i++) {
             log(rust_log::TASK,
-                "\t task: 0x%" PRIxPTR ", blocked on: 0x%" PRIxPTR,
-                blocked_tasks[i], blocked_tasks[i]->cond);
+                "\t task: %s @0x%" PRIxPTR ", blocked on: 0x%" PRIxPTR,
+                blocked_tasks[i]->name, blocked_tasks[i],
+                blocked_tasks[i]->cond);
         }
     }
 
     if (!dead_tasks.is_empty()) {
         log(rust_log::TASK, "dead tasks:");
         for (size_t i = 0; i < dead_tasks.length(); i++) {
-            log(rust_log::TASK, "\t task: 0x%" PRIxPTR, dead_tasks[i]);
+            log(rust_log::TASK, "\t task: %s @0x%" PRIxPTR,
+                dead_tasks[i]->name, dead_tasks[i]);
         }
     }
 }
@@ -360,7 +370,8 @@ rust_dom::start_main_loop()
     // Make sure someone is watching, to pull us out of infinite loops.
     rust_timer timer(this);
 
-    log(rust_log::DOM, "running main-loop on domain 0x%" PRIxPTR, this);
+    log(rust_log::DOM, "running main-loop on domain %s @0x%" PRIxPTR,
+        name, this);
     logptr("exit-task glue", root_crate->get_exit_task_glue());
 
     while (n_live_tasks() > 0) {
@@ -386,16 +397,18 @@ rust_dom::start_main_loop()
         I(this, scheduled_task->running());
 
         log(rust_log::TASK,
-                 "activating task 0x%" PRIxPTR ", sp=0x%" PRIxPTR,
-                 (uintptr_t)scheduled_task, scheduled_task->rust_sp);
+                 "activating task %s @0x%" PRIxPTR ", sp=0x%" PRIxPTR,
+            scheduled_task->name, (uintptr_t)scheduled_task,
+            scheduled_task->rust_sp);
 
         interrupt_flag = 0;
 
         activate(scheduled_task);
 
         log(rust_log::TASK,
-                 "returned from task 0x%" PRIxPTR
+                 "returned from task %s @0x%" PRIxPTR
                  " in state '%s', sp=0x%" PRIxPTR,
+                 scheduled_task->name,
                  (uintptr_t)scheduled_task,
                  state_vec_name(scheduled_task->state),
                  scheduled_task->rust_sp);
@@ -417,8 +430,9 @@ rust_dom::start_main_loop()
         if (_log.is_tracing(rust_log::DOM)) {
             for (size_t i = 0; i < dead_tasks.length(); i++) {
                 log(rust_log::DOM,
-                    "task: 0x%" PRIxPTR ", index: %d, ref_count: %d",
-                    dead_tasks[i], i, dead_tasks[i]->ref_count);
+                    "task: %s @0x%" PRIxPTR ", index: %d, ref_count: %d",
+                    dead_tasks[i]->name, dead_tasks[i], i,
+                    dead_tasks[i]->ref_count);
             }
         }
 
diff --git a/src/rt/rust_dom.h b/src/rt/rust_dom.h
index 528790d56cc..abf10cefe00 100644
--- a/src/rt/rust_dom.h
+++ b/src/rt/rust_dom.h
@@ -25,6 +25,7 @@ struct rust_dom
     rust_crate const *root_crate;
     rust_log _log;
     rust_srv *srv;
+    const char *const name;
     ptr_vec<rust_task> running_tasks;
     ptr_vec<rust_task> blocked_tasks;
     ptr_vec<rust_task> dead_tasks;
@@ -47,7 +48,9 @@ struct rust_dom
     pthread_attr_t attr;
 #endif
 
-    rust_dom(rust_srv *srv, rust_crate const *root_crate);
+    // Only a pointer to 'name' is kept, so it must live as long as this
+    // domain.
+    rust_dom(rust_srv *srv, rust_crate const *root_crate, const char *name);
     ~rust_dom();
 
     void activate(rust_task *task);
diff --git a/src/rt/rust_task.cpp b/src/rt/rust_task.cpp
index 9f4fa611a95..279850cb0f8 100644
--- a/src/rt/rust_task.cpp
+++ b/src/rt/rust_task.cpp
@@ -52,7 +52,7 @@ align_down(uintptr_t sp)
 }
 
 
-rust_task::rust_task(rust_dom *dom, rust_task *spawner) :
+rust_task::rust_task(rust_dom *dom, rust_task *spawner, const char *name) :
     maybe_proxy<rust_task>(this),
     stk(new_stk(dom, 0)),
     runtime_sp(0),
@@ -60,6 +60,7 @@ rust_task::rust_task(rust_dom *dom, rust_task *spawner) :
     gc_alloc_chain(0),
     dom(dom),
     cache(NULL),
+    name(name),
     state(&dom->running_tasks),
     cond(NULL),
     supervisor(spawner),
@@ -77,8 +78,8 @@ rust_task::rust_task(rust_dom *dom, rust_task *spawner) :
 rust_task::~rust_task()
 {
     dom->log(rust_log::MEM|rust_log::TASK,
-             "~rust_task 0x%" PRIxPTR ", refcnt=%d",
-             (uintptr_t)this, ref_count);
+             "~rust_task %s @0x%" PRIxPTR ", refcnt=%d",
+             name, (uintptr_t)this, ref_count);
 
     /*
       for (uintptr_t fp = get_fp(); fp; fp = get_previous_fp(fp)) {
@@ -311,7 +312,7 @@ void
 rust_task::yield(size_t nargs)
 {
     log(rust_log::TASK,
-        "task 0x%" PRIxPTR " yielding", this);
+        "task %s @0x%" PRIxPTR " yielding", name, this);
     run_after_return(nargs, dom->root_crate->get_yield_glue());
 }
 
@@ -326,7 +327,7 @@ rust_task::kill() {
     // Note the distinction here: kill() is when you're in an upcall
     // from task A and want to force-fail task B, you do B->kill().
     // If you want to fail yourself you do self->fail(upcall_nargs).
-    log(rust_log::TASK, "killing task 0x%" PRIxPTR, this);
+    log(rust_log::TASK, "killing task %s @0x%" PRIxPTR, name, this);
     // Unblock the task so it can unwind.
     unblock();
 
@@ -339,7 +340,7 @@ rust_task::kill() {
 void
 rust_task::fail(size_t nargs) {
     // See note in ::kill() regarding who should call this.
-    dom->log(rust_log::TASK, "task 0x%" PRIxPTR " failing", this);
+    dom->log(rust_log::TASK, "task %s @0x%" PRIxPTR " failing", name, this);
     // Unblock the task so it can unwind.
     unblock();
     if (this == dom->root_task)
@@ -347,9 +348,9 @@ rust_task::fail(size_t nargs) {
     run_after_return(nargs, dom->root_crate->get_unwind_glue());
     if (supervisor) {
         dom->log(rust_log::TASK,
-                 "task 0x%" PRIxPTR
-                 " propagating failure to supervisor 0x%" PRIxPTR,
-                 this, supervisor);
+                 "task %s @0x%" PRIxPTR
+                 " propagating failure to supervisor %s @0x%" PRIxPTR,
+                 name, this, supervisor->name, supervisor);
         supervisor->kill();
     }
 }
@@ -358,7 +359,7 @@ void
 rust_task::gc(size_t nargs)
 {
     dom->log(rust_log::TASK|rust_log::MEM,
-             "task 0x%" PRIxPTR " garbage collecting", this);
+             "task %s @0x%" PRIxPTR " garbage collecting", name, this);
     run_after_return(nargs, dom->root_crate->get_gc_glue());
 }
 
@@ -366,8 +367,9 @@ void
 rust_task::unsupervise()
 {
     dom->log(rust_log::TASK,
-             "task 0x%" PRIxPTR " disconnecting from supervisor 0x%" PRIxPTR,
-             this, supervisor);
+             "task %s @0x%" PRIxPTR
+             " disconnecting from supervisor %s @0x%" PRIxPTR,
+             name, this, supervisor->name, supervisor);
     supervisor = NULL;
 }
 
@@ -468,8 +470,9 @@ rust_task::malloc(size_t sz, type_desc *td)
     if (td) {
         gc_alloc *gcm = (gc_alloc*) mem;
         dom->log(rust_log::TASK|rust_log::MEM|rust_log::GC,
-                 "task 0x%" PRIxPTR " allocated %d GC bytes = 0x%" PRIxPTR,
-                 (uintptr_t)this, sz, gcm);
+                 "task %s @0x%" PRIxPTR
+                 " allocated %d GC bytes = 0x%" PRIxPTR,
+                 name, (uintptr_t)this, sz, gcm);
         memset((void*) gcm, 0, sizeof(gc_alloc));
         link_gc(gcm);
         gcm->ctrl_word = (uintptr_t)td;
@@ -488,8 +491,9 @@ rust_task::realloc(void *data, size_t sz, bool is_gc)
         sz += sizeof(gc_alloc);
         gcm = (gc_alloc*) dom->realloc((void*)gcm, sz);
         dom->log(rust_log::TASK|rust_log::MEM|rust_log::GC,
-                 "task 0x%" PRIxPTR " reallocated %d GC bytes = 0x%" PRIxPTR,
-                 (uintptr_t)this, sz, gcm);
+                 "task %s @0x%" PRIxPTR
+                 " reallocated %d GC bytes = 0x%" PRIxPTR,
+                 name, (uintptr_t)this, sz, gcm);
         if (!gcm)
             return gcm;
         link_gc(gcm);
@@ -507,8 +511,8 @@ rust_task::free(void *p, bool is_gc)
         gc_alloc *gcm = (gc_alloc*)(((char *)p) - sizeof(gc_alloc));
         unlink_gc(gcm);
         dom->log(rust_log::TASK|rust_log::MEM|rust_log::GC,
-                 "task 0x%" PRIxPTR " freeing GC memory = 0x%" PRIxPTR,
-                 (uintptr_t)this, gcm);
+                 "task %s @0x%" PRIxPTR " freeing GC memory = 0x%" PRIxPTR,
+                 name, (uintptr_t)this, gcm);
         dom->free(gcm);
     } else {
         dom->free(p);
@@ -521,7 +525,8 @@ rust_task::transition(ptr_vec<rust_task> *src, ptr_vec<rust_task> *dst)
 {
     I(dom, state == src);
     dom->log(rust_log::TASK,
-             "task 0x%" PRIxPTR " state change '%s' -> '%s'",
+             "task %s @0x%" PRIxPTR " state change '%s' -> '%s'",
+             name,
              (uintptr_t)this,
              dom->state_vec_name(src),
              dom->state_vec_name(dst));
diff --git a/src/rt/rust_task.h b/src/rt/rust_task.h
index b657592a5ef..27495e2c1ad 100644
--- a/src/rt/rust_task.h
+++ b/src/rt/rust_task.h
@@ -21,6 +21,7 @@ rust_task : public maybe_proxy<rust_task>,
     rust_crate_cache *cache;
 
     // Fields known only to the runtime.
+    const char *const name;
     ptr_vec<rust_task> *state;
     rust_cond *cond;
     rust_task *supervisor;     // Parent-link for failure propagation.
@@ -41,8 +42,10 @@ rust_task : public maybe_proxy<rust_task>,
 
     rust_alarm alarm;
 
+    // Only a pointer to 'name' is kept, so it must live as long as this task.
     rust_task(rust_dom *dom,
-              rust_task *spawner);
+              rust_task *spawner,
+              const char *name);
     ~rust_task();
 
     void start(uintptr_t exit_task_glue,
diff --git a/src/rt/rust_upcall.cpp b/src/rt/rust_upcall.cpp
index 574cb703a1f..b0757e29e42 100644
--- a/src/rt/rust_upcall.cpp
+++ b/src/rt/rust_upcall.cpp
@@ -6,16 +6,18 @@
 #define LOG_UPCALL_ENTRY(task)                              \
     (task)->dom->get_log().reset_indent(0);                 \
     (task)->log(rust_log::UPCALL,                           \
-                "> UPCALL %s - task: 0x%" PRIxPTR           \
+                "> UPCALL %s - task: %s @0x%" PRIxPTR       \
                 " retpc: x%" PRIxPTR,                       \
                 __FUNCTION__,                               \
-                (task), __builtin_return_address(0));       \
+                (task)->name, (task),                       \
+                __builtin_return_address(0));               \
     (task)->dom->get_log().indent();
 #else
 #define LOG_UPCALL_ENTRY(task)                              \
     (task)->dom->get_log().reset_indent(0);                 \
     (task)->log(rust_log::UPCALL,                           \
-                "> UPCALL task: x%" PRIxPTR (task));        \
+                "> UPCALL task: %s @x%" PRIxPTR,            \
+                (task)->name, (task));                      \
     (task)->dom->get_log().indent();
 #endif
 
@@ -55,8 +57,8 @@ upcall_new_port(rust_task *task, size_t unit_sz) {
     LOG_UPCALL_ENTRY(task);
     rust_dom *dom = task->dom;
     task->log(rust_log::UPCALL | rust_log::MEM | rust_log::COMM,
-              "upcall_new_port(task=0x%" PRIxPTR ", unit_sz=%d)",
-              (uintptr_t) task, unit_sz);
+              "upcall_new_port(task=0x%" PRIxPTR " (%s), unit_sz=%d)",
+              (uintptr_t) task, task->name, unit_sz);
     return new (dom) rust_port(task, unit_sz);
 }
 
@@ -76,8 +78,9 @@ upcall_new_chan(rust_task *task, rust_port *port) {
     LOG_UPCALL_ENTRY(task);
     rust_dom *dom = task->dom;
     task->log(rust_log::UPCALL | rust_log::MEM | rust_log::COMM,
-              "upcall_new_chan(task=0x%" PRIxPTR ", port=0x%" PRIxPTR ")",
-              (uintptr_t) task, port);
+              "upcall_new_chan("
+              "task=0x%" PRIxPTR " (%s), port=0x%" PRIxPTR ")",
+              (uintptr_t) task, task->name, port);
     I(dom, port);
     return new (dom) rust_chan(task, port);
 }
@@ -136,11 +139,11 @@ extern "C" CDECL void upcall_yield(rust_task *task) {
 extern "C" CDECL void
 upcall_join(rust_task *task, maybe_proxy<rust_task> *target) {
     LOG_UPCALL_ENTRY(task);
+    rust_task *target_task = target->delegate();
     task->log(rust_log::UPCALL | rust_log::COMM,
-              "target: 0x%" PRIxPTR ", task: 0x%" PRIxPTR,
-              target, target->delegate());
+              "target: 0x%" PRIxPTR ", task: %s @0x%" PRIxPTR,
+              target, target_task->name, target_task);
 
-    rust_task *target_task = target->delegate();
     if (target->is_proxy()) {
         notify_message::
         send(notify_message::JOIN, "join", task, target->as_proxy());
@@ -222,8 +225,8 @@ upcall_kill(rust_task *task, maybe_proxy<rust_task> *target) {
     rust_task *target_task = target->delegate();
 
     task->log(rust_log::UPCALL | rust_log::TASK,
-              "kill task 0x%" PRIxPTR ", ref count %d",
-              target_task,
+              "kill task %s @0x%" PRIxPTR ", ref count %d",
+              target_task->name, target_task,
               target_task->ref_count);
 
     if (target->is_proxy()) {
@@ -498,14 +501,14 @@ static void *rust_thread_start(void *ptr)
 }
 
 extern "C" CDECL rust_task *
-upcall_new_task(rust_task *spawner) {
+upcall_new_task(rust_task *spawner, const char *name) {
     LOG_UPCALL_ENTRY(spawner);
 
     rust_dom *dom = spawner->dom;
-    rust_task *task = new (dom) rust_task(dom, spawner);
+    rust_task *task = new (dom) rust_task(dom, spawner, name);
     dom->log(rust_log::UPCALL | rust_log::MEM | rust_log::TASK,
-             "upcall new_task(spawner 0x%" PRIxPTR ") = 0x%" PRIxPTR,
-             spawner, task);
+             "upcall new_task(spawner %s @0x%" PRIxPTR ", %s) = 0x%" PRIxPTR,
+             spawner->name, spawner, name, task);
     return task;
 }
 
@@ -516,26 +519,27 @@ upcall_start_task(rust_task *spawner, rust_task *task,
 
     rust_dom *dom = spawner->dom;
     dom->log(rust_log::UPCALL | rust_log::MEM | rust_log::TASK,
-             "upcall start_task(task 0x%" PRIxPTR
+             "upcall start_task(task %s @0x%" PRIxPTR
              " exit_task_glue 0x%" PRIxPTR
              ", spawnee 0x%" PRIxPTR
-             ", callsz %" PRIdPTR ")", task, exit_task_glue, spawnee_fn,
-             callsz);
+             ", callsz %" PRIdPTR ")", task->name, task, exit_task_glue,
+             spawnee_fn, callsz);
     task->start(exit_task_glue, spawnee_fn, spawner->rust_sp, callsz);
     return task;
 }
 
 extern "C" CDECL maybe_proxy<rust_task> *
-upcall_new_thread(rust_task *task) {
+upcall_new_thread(rust_task *task, const char *name) {
     LOG_UPCALL_ENTRY(task);
 
     rust_dom *old_dom = task->dom;
     rust_dom *new_dom = new rust_dom(old_dom->srv->clone(),
-                                     old_dom->root_crate);
+                                     old_dom->root_crate,
+                                     name);
 
     task->log(rust_log::UPCALL | rust_log::MEM,
-              "upcall new_thread() = dom 0x%" PRIxPTR " task 0x%" PRIxPTR,
-              new_dom, new_dom->root_task);
+              "upcall new_thread(%s) = dom 0x%" PRIxPTR " task 0x%" PRIxPTR,
+              name, new_dom, new_dom->root_task);
     rust_proxy<rust_task> *proxy =
         new (old_dom) rust_proxy<rust_task>(old_dom,
                                             new_dom->root_task, true);