Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add stack size parameter to nqp::newthread #522

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/vm/jvm/QAST/Compiler.nqp
Original file line number Diff line number Diff line change
Expand Up @@ -2845,7 +2845,7 @@ QAST::OperationsJAST.map_classlib_core_op('jvmgetproperties', $TYPE_OPS, 'jvmget
QAST::OperationsJAST.map_classlib_core_op('getrusage', $TYPE_OPS, 'getrusage', [$RT_OBJ], $RT_OBJ, :tc);

# thread related opcodes
QAST::OperationsJAST.map_classlib_core_op('newthread', $TYPE_OPS, 'newthread', [$RT_OBJ, $RT_INT], $RT_OBJ, :tc);
QAST::OperationsJAST.map_classlib_core_op('newthread', $TYPE_OPS, 'newthread', [$RT_OBJ, $RT_INT, $RT_INT], $RT_OBJ, :tc);
QAST::OperationsJAST.map_classlib_core_op('threadrun', $TYPE_OPS, 'threadrun', [$RT_OBJ], $RT_OBJ, :tc);
QAST::OperationsJAST.map_classlib_core_op('threadjoin', $TYPE_OPS, 'threadjoin', [$RT_OBJ], $RT_OBJ, :tc);
QAST::OperationsJAST.map_classlib_core_op('threadid', $TYPE_OPS, 'threadid', [$RT_OBJ], $RT_INT, :tc);
Expand Down
4 changes: 2 additions & 2 deletions src/vm/jvm/runtime/org/perl6/nqp/runtime/Ops.java
Original file line number Diff line number Diff line change
Expand Up @@ -5706,9 +5706,9 @@ public void run() {
invokeArgless(tc, code);
}
}
public static SixModelObject newthread(SixModelObject code, long appLifetime, ThreadContext tc) {
public static SixModelObject newthread(SixModelObject code, long appLifetime, long stackSize, ThreadContext tc) {
SixModelObject thread = tc.gc.Thread.st.REPR.allocate(tc, tc.gc.Thread.st);
((VMThreadInstance)thread).thread = new Thread(new CodeRunnable(tc.gc, thread, code));
((VMThreadInstance)thread).thread = new Thread(new CodeRunnable(tc.gc, thread, code, stackSize));
((VMThreadInstance)thread).thread.setDaemon(appLifetime != 0);
return thread;
}
Expand Down
18 changes: 9 additions & 9 deletions t/concurrency/01-thread.t
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ plan(24);
# 2 tests
{
my $ran := 0;
my $t := nqp::newthread({ $ran := 1 }, 0);
my $t := nqp::newthread({ $ran := 1 }, 0, 0);
ok(nqp::defined($t), 'Can create a new non-app-lifetime thread');
nqp::threadrun($t);
nqp::threadjoin($t);
Expand All @@ -13,7 +13,7 @@ plan(24);
# 2 tests
{
my $start := nqp::time_n();
my $t := nqp::newthread({ nqp::sleep(10.0) }, 1);
my $t := nqp::newthread({ nqp::sleep(10.0) }, 1, 0);
ok(nqp::defined($t), 'Can create a new app-lifetime thread');
nqp::threadrun($t);
ok(nqp::time_n() - $start < 10.0,
Expand All @@ -26,7 +26,7 @@ plan(24);
my $t := nqp::newthread({
1 until $done;
ok(1, 'Can write to STDOUT in child thread');
}, 0);
}, 0, 0);
ok(1, 'Can write to STDOUT in parent thread before threadrun');
nqp::threadrun($t);
ok(1, 'Can write to STDOUT in parent thread after threadrun');
Expand All @@ -45,7 +45,7 @@ plan(24);
my $cid := 0;
my $t := nqp::newthread({
$cid := nqp::threadid(nqp::currentthread());
}, 0);
}, 0, 0);
ok(nqp::defined($t), 'Can create another new thread after previous joins');

$tid := nqp::threadid($t);
Expand All @@ -69,8 +69,8 @@ plan(24);
{
my $a := 0;
my $b := 0;
my $t1 := nqp::newthread({ $a := 21 }, 0);
my $t2 := nqp::newthread({ $b := 42 }, 0);
my $t1 := nqp::newthread({ $a := 21 }, 0, 0);
my $t2 := nqp::newthread({ $b := 42 }, 0, 0);

nqp::threadrun($t1);
nqp::threadrun($t2);
Expand All @@ -96,7 +96,7 @@ plan(24);
nqp::push(@a, '1');
nqp::threadyield() until nqp::elems(@a) == 3 && @a[2] eq 'b';
nqp::push(@a, '2');
}, 0);
}, 0, 0);

# Make sure child thread is at least *runnable* (if not actually running)
# before running parent thread's code.
Expand Down Expand Up @@ -133,13 +133,13 @@ plan(24);
nqp::push(@a, 'b');
nqp::threadyield() until nqp::elems(@a) == 4 && @a[3] eq '2';
nqp::push(@a, 'c');
}, 0);
}, 0, 0);
my $t2 := nqp::newthread({
nqp::threadyield() until nqp::elems(@a) == 1 && @a[0] eq 'a';
nqp::push(@a, '1');
nqp::threadyield() until nqp::elems(@a) == 3 && @a[2] eq 'b';
nqp::push(@a, '2');
}, 0);
}, 0, 0);

# Make sure $t2 is at least *runnable* (if not actually running)
# before $t1 becomes runnable.
Expand Down
20 changes: 10 additions & 10 deletions t/concurrency/02-lock.t
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ my class CondVar is repr('ConditionVariable') { }
nqp::lock($l);
ok(1, 'Lock that survived CATCH works in another thread too');
nqp::unlock($l);
}, 0);
}, 0, 0);
nqp::threadrun($t);
nqp::threadjoin($t);

Expand All @@ -70,7 +70,7 @@ my class CondVar is repr('ConditionVariable') { }
$output := $output ~ 'a';
}
nqp::unlock($l);
}, 0);
}, 0, 0);

my $t2 := nqp::newthread({
nqp::lock($l);
Expand All @@ -79,7 +79,7 @@ my class CondVar is repr('ConditionVariable') { }
$output := $output ~ 'b';
}
nqp::unlock($l);
}, 0);
}, 0, 0);

nqp::threadrun($t1);
nqp::threadrun($t2);
Expand Down Expand Up @@ -111,7 +111,7 @@ my class CondVar is repr('ConditionVariable') { }
nqp::condsignalall($c);
$now1 := nqp::time_n();
nqp::unlock($l);
}, 0);
}, 0, 0);
nqp::threadrun($t1);

my $elems := 0;
Expand All @@ -130,7 +130,7 @@ my class CondVar is repr('ConditionVariable') { }
}
nqp::push(@log, 'lager');
nqp::unlock($l);
}, 0);
}, 0, 0);
nqp::threadrun($t2);

nqp::threadjoin($t1);
Expand Down Expand Up @@ -161,35 +161,35 @@ my class CondVar is repr('ConditionVariable') { }
nqp::condsignalone($c1);
nqp::condsignalall($c2);
nqp::unlock($l);
}, 0);
}, 0, 0);

my $t2 := nqp::newthread({
nqp::lock($l);
nqp::condwait($c1);
$count_one++;
nqp::unlock($l);
}, 0);
}, 0, 0);

my $t3 := nqp::newthread({
nqp::lock($l);
nqp::condwait($c1);
$count_one++;
nqp::unlock($l);
}, 0);
}, 0, 0);

my $t4 := nqp::newthread({
nqp::lock($l);
nqp::condwait($c2);
$count_all++;
nqp::unlock($l);
}, 0);
}, 0, 0);

my $t5 := nqp::newthread({
nqp::lock($l);
nqp::condwait($c2);
$count_all++;
nqp::unlock($l);
}, 0);
}, 0, 0);

# Start all waiting threads
nqp::threadrun($t2);
Expand Down
12 changes: 6 additions & 6 deletions t/concurrency/03-semaphore.t
Original file line number Diff line number Diff line change
Expand Up @@ -38,28 +38,28 @@ my class Semaphore is repr('Semaphore') { }
my $s := nqp::box_i(3, Semaphore);
my $t1 := nqp::newthread({
nqp::semacquire($s);
}, 0);
}, 0, 0);
my $t2 := nqp::newthread({
nqp::semacquire($s);
}, 0);
}, 0, 0);
my $t3 := nqp::newthread({
nqp::semacquire($s);
}, 0);
}, 0, 0);
my $t4 := nqp::newthread({
ok(!nqp::semtryacquire($s), 'Trying fourth acquire before release fails');
}, 0);
}, 0, 0);
my $t5 := nqp::newthread({
my $before := nqp::time_n();
nqp::semacquire($s);
my $after := nqp::time_n();
ok($after - $before > 1.0, 'Fourth acquire blocks on empty semaphore');
ok($released, 'Fourth acquire succeeds after release in other thread');
}, 0);
}, 0, 0);
my $t6 := nqp::newthread({
nqp::sleep(3.0);
$released := 1;
nqp::semrelease($s);
}, 0);
}, 0, 0);

# First, exhaust semaphore capacity
nqp::threadrun($t1);
Expand Down
2 changes: 1 addition & 1 deletion t/concurrency/04-osr-crash.t
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ my $t := nqp::newthread({
ok(1, "in thread");
dec()
}
}, 1);
}, 1, 0);
nqp::threadrun($t);
nqp::threadjoin($t);
ok(1, "Thread with top level loop survived");