Skip to content

Commit

Permalink
Avoid building up a huge stack of continuations
Browse files Browse the repository at this point in the history
If we have a continuation to resume, it already has the continuation
entry frame with error handling as part of the stack that is resumed.
If we thus invoke the continuation inside such a frame, and then it
also results in the continuation being taken, we make the stack more
deeply nested each time. Don't do that. Also refactor to avoid taking
a closure holding the continuation, which will make things a little
cheaper.
  • Loading branch information
jnthn committed Jul 20, 2018
1 parent 683ae67 commit bf514c1
Showing 1 changed file with 30 additions and 19 deletions.
49 changes: 30 additions & 19 deletions src/core/ThreadPoolScheduler.pm6
Expand Up @@ -26,6 +26,12 @@ my class ThreadPoolScheduler does Scheduler {
# Infrastructure for non-blocking `await` for code running on the
# scheduler.
my constant THREAD_POOL_PROMPT = Mu.new;
my class ContinuationWrapper {
has $.cont;
method new(Mu \cont) {
nqp::p6bindattrinvres(nqp::create(self), ContinuationWrapper, '$!cont', cont)
}
}
class ThreadPoolAwaiter does Awaiter {
has $!queue;

Expand Down Expand Up @@ -57,7 +63,7 @@ my class ThreadPoolScheduler does Scheduler {
$handle.subscribe-awaiter(-> \success, \result {
$success := success;
$result := result;
nqp::push($!queue, { nqp::continuationinvoke(c, nqp::null()) });
nqp::push($!queue, ContinuationWrapper.new(c));
Nil
});
});
Expand Down Expand Up @@ -229,26 +235,31 @@ my class ThreadPoolScheduler does Scheduler {

method !run-one(\task --> Nil) {
$!working = 1;
nqp::continuationreset(THREAD_POOL_PROMPT, {
if nqp::istype(task, List) {
my Mu $code := nqp::shift(nqp::getattr(task, List, '$!reified'));
$code(|task);
}
else {
task.();
}
CONTROL {
default {
my Mu $vm-ex := nqp::getattr(nqp::decont($_), Exception, '$!ex');
nqp::getcomp('perl6').handle-control($vm-ex);
if nqp::istype(task, ContinuationWrapper) {
nqp::continuationinvoke(task.cont, nqp::null());
}
else {
nqp::continuationreset(THREAD_POOL_PROMPT, {
if nqp::istype(task, List) {
my Mu $code := nqp::shift(nqp::getattr(task, List, '$!reified'));
$code(|task);
}
}
CATCH {
default {
$!scheduler.handle_uncaught($_)
else {
task.();
}
}
});
CONTROL {
default {
my Mu $vm-ex := nqp::getattr(nqp::decont($_), Exception, '$!ex');
nqp::getcomp('perl6').handle-control($vm-ex);
}
}
CATCH {
default {
$!scheduler.handle_uncaught($_)
}
}
});
}
$!working = 0;
#?if moar
++$!completed;
Expand Down

0 comments on commit bf514c1

Please sign in to comment.