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

Concurrent threads report same Thread ID post-await #6390

Closed
p6rt opened this issue Jul 11, 2017 · 4 comments
Closed

Concurrent threads report same Thread ID post-await #6390

p6rt opened this issue Jul 11, 2017 · 4 comments
Labels

Comments

@p6rt
Copy link

p6rt commented Jul 11, 2017

Migrated from rt.perl.org#131740 (status was 'resolved')

Searchable as RT131740$

@p6rt
Copy link
Author

p6rt commented Jul 11, 2017

From emmiller@gmail.com

I'm using the new scheduler behavior described here​:

rakudo/rakudo#1004

After an "await" on a managed (non-main) thread it appears that execution
may continue on a different thread than it began on; however, $*THREAD
continues to report the same ID, so that multiple concurrent threads are
reporting the same thread ID.

Here's a script that demonstrates the issue 50% of the time. This starts
three promises, which start work after receiving a message from the
channel. With RAKUDO_MAX_THREADS=2, Promise #​1 and #​2 will receive the
first 2 messages and start work. Promise #​2 has less work and finishes
early. Promise #​3 then receives a message from the channel and is scheduled
on the thread freed by Promise #​2. Both Promise #​1 and #​3 are then working
concurrently, as demonstrated by CPU usage; however, about half the time
they report an identical $*THREAD.id.

Expected behavior​: Each thread should report its current, post-await
$*THREAD.id

Actual behavior​: Each thread continues to report its pre-await $*THREAD.id

Possibly related, per IRC conversation​:
rakudo/rakudo@bedf2a7

./perl6 --version
This is Rakudo version 2017.06-197-g83e157012 built on MoarVM version
2017.06-56-g161ec639
implementing Perl 6.c.

use v6.d.PREVIEW;

my $channel = Channel.new;

my $promise1 = start {
  say "1. Waiting ({$*THREAD.id})";
  await $channel;
  say "1. Got it ({$*THREAD.id})";
  say "1. Result ({$*THREAD.id})​: " ~ [+] (1..^1e6).map​: 1/*;
  say "1. Result ({$*THREAD.id})​: " ~ [+] (1..^1e6).map​: 1/*;
}

my $promise2 = start {
  say "2. Waiting ({$*THREAD.id})";
  await $channel;
  say "2. Got it ({$*THREAD.id})";
  say "2. Result ({$*THREAD.id})​: " ~ [+] (1..^1e5).map​: 1/*;
  say "2. Result ({$*THREAD.id})​: " ~ [+] (1..^1e5).map​: 1/*;
}

my $promise3 = start {
  say "3. Waiting ({$*THREAD.id})";
  await $channel;
  say "3. Got it ({$*THREAD.id})";
  say "3. Result ({$*THREAD.id})​: " ~ [+] (1..^1e6).map​: 1/*;
  say "3. Result ({$*THREAD.id})​: " ~ [+] (1..^1e6).map​: 1/*;
}

sleep 3;
$channel.send("Hello");
$channel.send("Hello");
$channel.send("Hello");

await $promise1, $promise2, $promise3;

@p6rt
Copy link
Author

p6rt commented Jul 12, 2017

From @jnthn

On Tue, 11 Jul 2017 15​:30​:40 -0700, emmiller@​gmail.com wrote​:

I'm using the new scheduler behavior described here​:

rakudo/rakudo#1004

After an "await" on a managed (non-main) thread it appears that
execution
may continue on a different thread than it began on; however, $*THREAD
continues to report the same ID, so that multiple concurrent threads
are
reporting the same thread ID.

Here's a script that demonstrates the issue 50% of the time. This
starts
three promises, which start work after receiving a message from the
channel. With RAKUDO_MAX_THREADS=2, Promise #​1 and #​2 will receive the
first 2 messages and start work. Promise #​2 has less work and finishes
early. Promise #​3 then receives a message from the channel and is
scheduled
on the thread freed by Promise #​2. Both Promise #​1 and #​3 are then
working
concurrently, as demonstrated by CPU usage; however, about half the
time
they report an identical $*THREAD.id.

Expected behavior​: Each thread should report its current, post-await
$*THREAD.id

Actual behavior​: Each thread continues to report its pre-await
$*THREAD.id

Nice find. Dynamic variable lookups in MoarVM are cached, to improve lookup speed. However, the cache was not being invalidated when a continuation was taken (continuations being the mechanism underlying non-blocking `await`), and so an earlier resolution of `$*THREAD` was being re-used after the `await`. Fixed by invalidating the cache (which could conveniently and cheaply be done while walking the call stack to locate the continuation tag). Test added to the Rakudo test suite (t/02-rakudo/09-thread-id-after-await.t), since that allowed for a concise and more reliable test.

/jnthn

@p6rt
Copy link
Author

p6rt commented Jul 12, 2017

The RT System itself - Status changed from 'new' to 'open'

@p6rt
Copy link
Author

p6rt commented Jul 12, 2017

@jnthn - Status changed from 'open' to 'resolved'

@p6rt p6rt closed this as completed Jul 12, 2017
@p6rt p6rt added the Bug label Jan 5, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant