From b71340552fa0caa870877f87a1273e8d4c91efe6 Mon Sep 17 00:00:00 2001 From: Jeffrey Yasskin Date: Sun, 8 Aug 2010 19:24:35 -0700 Subject: [PATCH] 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. --- doc/rust.texi | 16 ++++++---- src/boot/fe/ast.ml | 5 +-- src/boot/fe/pexp.ml | 29 +++++++++++++++--- src/boot/me/alias.ml | 2 +- src/boot/me/effect.ml | 2 +- src/boot/me/layout.ml | 2 +- src/boot/me/trans.ml | 11 ++++--- src/boot/me/type.ml | 2 +- src/boot/me/typestate.ml | 4 +-- src/boot/me/walk.ml | 2 +- src/rt/rust.cpp | 2 +- src/rt/rust_dom.cpp | 66 ++++++++++++++++++++++++---------------- src/rt/rust_dom.h | 5 ++- src/rt/rust_task.cpp | 43 ++++++++++++++------------ src/rt/rust_task.h | 5 ++- src/rt/rust_upcall.cpp | 52 ++++++++++++++++--------------- 16 files changed, 152 insertions(+), 96 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_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 *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 *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 *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 *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 (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 running_tasks; ptr_vec blocked_tasks; ptr_vec 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(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 *src, ptr_vec *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_crate_cache *cache; // Fields known only to the runtime. + const char *const name; ptr_vec *state; rust_cond *cond; rust_task *supervisor; // Parent-link for failure propagation. @@ -41,8 +42,10 @@ rust_task : public maybe_proxy, 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 *target) { LOG_UPCALL_ENTRY(task); - task->log(rust_log::UPCALL | rust_log::COMM, - "target: 0x%" PRIxPTR ", task: 0x%" PRIxPTR, - target, target->delegate()); - rust_task *target_task = target->delegate(); + task->log(rust_log::UPCALL | rust_log::COMM, + "target: 0x%" PRIxPTR ", task: %s @0x%" PRIxPTR, + target, target_task->name, target_task); + 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 *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 * -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 *proxy = new (old_dom) rust_proxy(old_dom, new_dom->root_task, true);