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.
This commit is contained in:
parent
df75a968c5
commit
b71340552f
@ -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;
|
||||
|
||||
|
@ -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 ";";
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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, _, _)
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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, _, _)
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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));
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
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<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);
|
||||
|
Loading…
Reference in New Issue
Block a user