Merge commit 'jyasskin/work'
Conflicts: src/rt/rust_dom.cpp src/rt/rust_upcall.cpp
This commit is contained in:
commit
dbe8760af3
17 changed files with 156 additions and 104 deletions
|
@ -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;
|
||||
|
||||
|
|
|
@ -472,7 +472,6 @@ TEST_XFAILS_LLVM := $(TASK_XFAILS) \
|
|||
i32-sub.rs \
|
||||
i8-incr.rs \
|
||||
import.rs \
|
||||
inner-module.rs \
|
||||
integral-indexing.rs \
|
||||
int-lib.rs \
|
||||
iter-range.rs \
|
||||
|
|
|
@ -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, _, _)
|
||||
|
|
|
@ -402,7 +402,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
|
||||
|
|
|
@ -2141,10 +2141,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 _ =
|
||||
|
@ -2178,7 +2180,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
|
||||
[|
|
||||
|
@ -2190,7 +2192,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
|
||||
[|
|
||||
|
@ -4529,8 +4531,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
|
||||
|
|
|
@ -184,7 +184,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);
|
||||
|
|
|
@ -7,11 +7,13 @@ template class ptr_vec<rust_task>;
|
|||
// Keeps track of all live domains, for debugging purposes.
|
||||
array_list<rust_dom*> _live_domains;
|
||||
|
||||
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),
|
||||
|
@ -27,7 +29,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);
|
||||
|
||||
if (_live_domains.replace(NULL, this) == false) {
|
||||
_live_domains.append(this);
|
||||
|
@ -49,25 +51,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 0x%" PRIxPTR
|
||||
" in dom 0x%" PRIxPTR,
|
||||
task_proxy, task_proxy->dom);
|
||||
log(rust_log::TASK,
|
||||
"deleting proxy 0x%" 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 0x%" PRIxPTR
|
||||
" in dom 0x%" PRIxPTR,
|
||||
port_proxy, port_proxy->dom);
|
||||
log(rust_log::TASK,
|
||||
"deleting proxy 0x%" 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();
|
||||
|
@ -135,7 +137,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;
|
||||
}
|
||||
|
@ -144,8 +147,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;
|
||||
}
|
||||
|
||||
|
@ -201,8 +205,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);
|
||||
}
|
||||
|
||||
|
@ -211,8 +215,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);
|
||||
}
|
||||
|
@ -239,7 +243,8 @@ rust_dom::reap_dead_tasks() {
|
|||
I(this, task->tasks_waiting_to_join.is_empty());
|
||||
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;
|
||||
}
|
||||
|
@ -282,7 +287,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;
|
||||
|
@ -344,7 +349,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]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -352,16 +358,18 @@ 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 ", ref_count: %d",
|
||||
dead_tasks[i], dead_tasks[i]->ref_count);
|
||||
log(rust_log::TASK, "\t task: %s 0x%" PRIxPTR ", ref_count: %d",
|
||||
dead_tasks[i], dead_tasks[i]->name,
|
||||
dead_tasks[i]->ref_count);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -378,7 +386,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) {
|
||||
|
@ -405,22 +414,24 @@ rust_dom::start_main_loop()
|
|||
I(this, scheduled_task->running());
|
||||
|
||||
log(rust_log::TASK,
|
||||
"activating task 0x%" PRIxPTR
|
||||
", sp=0x%" PRIxPTR
|
||||
", ref_count=%d"
|
||||
", state: %s",
|
||||
(uintptr_t)scheduled_task,
|
||||
scheduled_task->rust_sp,
|
||||
scheduled_task->ref_count,
|
||||
scheduled_task->state_str());
|
||||
"activating task %s 0x%" PRIxPTR
|
||||
", sp=0x%" PRIxPTR
|
||||
", ref_count=%d"
|
||||
", state: %s",
|
||||
scheduled_task->name,
|
||||
(uintptr_t)scheduled_task,
|
||||
scheduled_task->rust_sp,
|
||||
scheduled_task->ref_count,
|
||||
scheduled_task->state_str());
|
||||
|
||||
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);
|
||||
|
|
|
@ -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;
|
||||
|
@ -44,7 +45,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());
|
||||
}
|
||||
|
||||
|
@ -331,7 +332,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();
|
||||
|
||||
|
@ -345,7 +346,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)
|
||||
|
@ -353,9 +354,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();
|
||||
}
|
||||
}
|
||||
|
@ -364,7 +365,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());
|
||||
}
|
||||
|
||||
|
@ -372,8 +373,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;
|
||||
}
|
||||
|
||||
|
@ -474,8 +476,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;
|
||||
|
@ -494,8 +497,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);
|
||||
|
@ -513,8 +517,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);
|
||||
|
@ -531,7 +535,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,18 +6,20 @@
|
|||
#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 \
|
||||
" ref_count: %d", \
|
||||
__FUNCTION__, \
|
||||
(task), __builtin_return_address(0), \
|
||||
(task)->name, (task), \
|
||||
__builtin_return_address(0), \
|
||||
(task->ref_count)); \
|
||||
(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
|
||||
|
||||
|
@ -70,8 +72,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);
|
||||
}
|
||||
|
||||
|
@ -91,8 +93,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);
|
||||
}
|
||||
|
@ -175,11 +178,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());
|
||||
|
@ -252,8 +255,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()) {
|
||||
|
@ -530,14 +533,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;
|
||||
}
|
||||
|
||||
|
@ -548,26 +551,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…
Add table
Add a link
Reference in a new issue