Skip to content

Commit

Permalink
delete task->last
Browse files Browse the repository at this point in the history
this field was unnecessary, and could result in a task staying alive in the gc unnecessarily
  • Loading branch information
vtjnash committed Sep 24, 2015
1 parent 6453eca commit b005dee
Show file tree
Hide file tree
Showing 8 changed files with 41 additions and 60 deletions.
1 change: 0 additions & 1 deletion base/boot.jl
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,6 @@

# type Task
# parent::Task
# last::Task
# storage::Any
# consumers
# started::Bool
Expand Down
7 changes: 0 additions & 7 deletions base/docs/helpdb.jl
Original file line number Diff line number Diff line change
Expand Up @@ -10883,13 +10883,6 @@ Returns `true` if the value of the sign of `x` is negative, otherwise `false`.
"""
signbit

doc"""
istaskstarted(task) -> Bool
Tell whether a task has started executing.
"""
istaskstarted

doc"""
clamp(x, lo, hi)
Expand Down
1 change: 0 additions & 1 deletion base/exports.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1026,7 +1026,6 @@ export
Condition,
consume,
current_task,
istaskstarted,
istaskdone,
lock,
notify,
Expand Down
2 changes: 1 addition & 1 deletion base/serialize.jl
Original file line number Diff line number Diff line change
Expand Up @@ -346,7 +346,7 @@ end

function serialize(s::SerializationState, t::Task)
serialize_cycle(s, t) && return
if istaskstarted(t) && !istaskdone(t)
if !istaskdone(t)
error("cannot serialize a running Task")
end
writetag(s.io, TASK_TAG)
Expand Down
60 changes: 27 additions & 33 deletions base/task.jl
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,6 @@ end

current_task() = ccall(:jl_get_current_task, Any, ())::Task
istaskdone(t::Task) = ((t.state == :done) | (t.state == :failed))
istaskstarted(t::Task) = isdefined(t, :last)

yieldto(t::Task, x::ANY = nothing) = ccall(:jl_switchto, Any, (Any, Any), t, x)

Expand Down Expand Up @@ -115,60 +114,55 @@ suppress_excp_printing(t::Task) = isa(t.storage, ObjectIdDict) ? get(get_task_tl
function task_done_hook(t::Task)
err = (t.state == :failed)
result = t.result
nexttask = t.last
handled = true
if err
t.backtrace = catch_backtrace()
end

q = t.consumers
t.consumers = nothing

if isa(t.donenotify, Condition)
handled |= !isempty(t.donenotify.waitq)
notify(t.donenotify, result, error=err)
end

#### un-optimized version
#isa(q,Condition) && notify(q, result, error=err)
if isa(q,Task)
nexttask = q
nexttask.state = :runnable
if err
nexttask.exception = result
end
yieldto(nexttask, result) # this terminates the task
elseif isa(q,Condition) && !isempty(q.waitq)
notify(q, result, error=err)
else
handled = false
end

t.consumers = nothing

if isa(t.donenotify,Condition)
handled |= !isempty(t.donenotify.waitq)
notify(t.donenotify, result, error=err)
end

if nexttask.state == :runnable
if err
nexttask.exception = result
if err && !handled
if isa(result,InterruptException) && isdefined(Base,:active_repl_backend) &&
active_repl_backend.backend_task.state == :waiting && isempty(Workqueue) &&
active_repl_backend.in_eval
throwto(active_repl_backend.backend_task, result)
end
yieldto(nexttask, result)
else
if err && !handled
if isa(result,InterruptException) && isdefined(Base,:active_repl_backend) &&
active_repl_backend.backend_task.state == :waiting && isempty(Workqueue) &&
active_repl_backend.in_eval
throwto(active_repl_backend.backend_task, result)
end
if !suppress_excp_printing(t)
let bt = t.backtrace
# run a new task to print the error for us
@schedule with_output_color(:red, STDERR) do io
print(io, "ERROR (unhandled task failure): ")
showerror(io, result, bt)
println(io)
end
if !suppress_excp_printing(t)
let bt = t.backtrace
# run a new task to print the error for us
@schedule with_output_color(:red, STDERR) do io
print(io, "ERROR (unhandled task failure): ")
showerror(io, result, bt)
println(io)
end
end
end
# if a finished task accidentally gets into the queue, wait()
# could return. in that case just take the next task off the queue.
while true
wait()
end
end
# if a finished task accidentally gets into the queue, wait()
# could return. in that case just take the next task off the queue.
while true
wait()
end
end

Expand Down
1 change: 0 additions & 1 deletion src/gc.c
Original file line number Diff line number Diff line change
Expand Up @@ -1577,7 +1577,6 @@ static void gc_mark_task_stack(jl_task_t *ta, int d)
NOINLINE static void gc_mark_task(jl_task_t *ta, int d)
{
if (ta->parent) gc_push_root(ta->parent, d);
if (ta->last) gc_push_root(ta->last, d);
gc_push_root(ta->tls, d);
gc_push_root(ta->consumers, d);
gc_push_root(ta->donenotify, d);
Expand Down
1 change: 0 additions & 1 deletion src/julia.h
Original file line number Diff line number Diff line change
Expand Up @@ -1374,7 +1374,6 @@ typedef struct _jl_handler_t {
typedef struct _jl_task_t {
JL_DATA_TYPE
struct _jl_task_t *parent;
struct _jl_task_t *last;
jl_value_t *tls;
jl_sym_t *state;
jl_value_t *consumers;
Expand Down
28 changes: 13 additions & 15 deletions src/task.c
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,7 @@ static void NORETURN finish_task(jl_task_t *t, jl_value_t *resultval)
// early free of stkbuf
void *stkbuf = t->stkbuf;
if (stkbuf != NULL) {
t->stkbuf = NULL;
t->stkbuf = (void*)(intptr_t)-1;
free(stkbuf - sizeof(size_t));
}
#endif
Expand Down Expand Up @@ -344,8 +344,6 @@ static void ctx_switch(jl_task_t *t)
jl_current_module = last->current_module;
}

t->last = jl_current_task;
jl_gc_wb(t, t->last);
jl_current_task = t;

#if defined(_OS_WINDOWS_) && !defined(COPY_STACKS)
Expand Down Expand Up @@ -424,9 +422,12 @@ JL_THREAD jl_value_t * volatile jl_task_arg_in_transit;
extern int jl_in_gc;
DLLEXPORT jl_value_t *jl_switchto(jl_task_t *t, jl_value_t *arg)
{
if (t == jl_current_task) {
throw_if_exception_set(t);
return arg;
}
if (t->state == done_sym || t->state == failed_sym ||
// task started but stkbuf NULL'd => finish_task ran
(t->last != NULL && t->stkbuf == NULL && t != jl_current_task)) {
(t->stkbuf == (void*)(intptr_t)-1)) {
if (t->exception != jl_nothing)
jl_throw(t->exception);
return t->result;
Expand Down Expand Up @@ -824,7 +825,6 @@ DLLEXPORT jl_task_t *jl_new_task(jl_function_t *start, size_t ssize)
t->ssize = ssize;
t->current_module = NULL;
t->parent = jl_current_task;
t->last = NULL;
t->tls = jl_nothing;
t->consumers = jl_nothing;
t->state = runnable_sym;
Expand Down Expand Up @@ -856,8 +856,8 @@ DLLEXPORT jl_task_t *jl_new_task(jl_function_t *start, size_t ssize)
static void jl_unprotect_stack(jl_task_t *t)
{
void *stk = t->stkbuf;
if (stk) {
t->stkbuf = NULL;
if (stk && stk != (void*)(intptr_t)-1) {
t->stkbuf = (void*)(intptr_t)-1;
#ifdef COPY_STACKS
free(stk - sizeof(size_t));
#else
Expand All @@ -882,9 +882,8 @@ void jl_init_tasks(void)
jl_task_type = jl_new_datatype(jl_symbol("Task"),
jl_any_type,
jl_emptysvec,
jl_svec(10,
jl_svec(9,
jl_symbol("parent"),
jl_symbol("last"),
jl_symbol("storage"),
jl_symbol("state"),
jl_symbol("consumers"),
Expand All @@ -893,13 +892,13 @@ void jl_init_tasks(void)
jl_symbol("exception"),
jl_symbol("backtrace"),
jl_symbol("code")),
jl_svec(10,
jl_any_type, jl_any_type,
jl_svec(9,
jl_any_type,
jl_any_type, jl_sym_type,
jl_any_type, jl_any_type,
jl_any_type, jl_any_type,
jl_any_type, jl_function_type),
0, 1, 0);
0, 1, 8);
jl_svecset(jl_task_type->types, 0, (jl_value_t*)jl_task_type);

done_sym = jl_symbol("done");
Expand Down Expand Up @@ -975,8 +974,7 @@ void jl_init_root_task(void *stack, size_t ssize)
jl_current_task->started = 1;
jl_current_task->parent = jl_current_task;
jl_current_task->current_module = jl_current_module;
jl_current_task->last = jl_current_task;
jl_current_task->tls = NULL;
jl_current_task->tls = jl_nothing;
jl_current_task->consumers = jl_nothing;
jl_current_task->state = runnable_sym;
jl_current_task->start = NULL;
Expand Down

0 comments on commit b005dee

Please sign in to comment.