diff --git a/src/vm/jvm/QAST/Compiler.nqp b/src/vm/jvm/QAST/Compiler.nqp index 6eef385a7f..9d0f3c98d5 100644 --- a/src/vm/jvm/QAST/Compiler.nqp +++ b/src/vm/jvm/QAST/Compiler.nqp @@ -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); diff --git a/src/vm/jvm/runtime/org/perl6/nqp/runtime/Ops.java b/src/vm/jvm/runtime/org/perl6/nqp/runtime/Ops.java index a58dac11e6..fb5276cbae 100644 --- a/src/vm/jvm/runtime/org/perl6/nqp/runtime/Ops.java +++ b/src/vm/jvm/runtime/org/perl6/nqp/runtime/Ops.java @@ -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; } diff --git a/t/concurrency/01-thread.t b/t/concurrency/01-thread.t index 9979cbb560..775a488e37 100644 --- a/t/concurrency/01-thread.t +++ b/t/concurrency/01-thread.t @@ -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); @@ -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, @@ -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'); @@ -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); @@ -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); @@ -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. @@ -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. diff --git a/t/concurrency/02-lock.t b/t/concurrency/02-lock.t index aab687f948..2b083e1905 100644 --- a/t/concurrency/02-lock.t +++ b/t/concurrency/02-lock.t @@ -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); @@ -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); @@ -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); @@ -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; @@ -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); @@ -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); diff --git a/t/concurrency/03-semaphore.t b/t/concurrency/03-semaphore.t index bd7c73012b..acde22f3c0 100644 --- a/t/concurrency/03-semaphore.t +++ b/t/concurrency/03-semaphore.t @@ -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); diff --git a/t/concurrency/04-osr-crash.t b/t/concurrency/04-osr-crash.t index 027a5021c5..477e4029d8 100644 --- a/t/concurrency/04-osr-crash.t +++ b/t/concurrency/04-osr-crash.t @@ -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");