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

Fix freezes caused by concurrently produced iterators #4416

Merged
merged 4 commits into from
Jun 22, 2021

Conversation

vrurg
Copy link
Member

@vrurg vrurg commented Jun 19, 2021

Freezes were happening with code similar to:

(.list, .list) given (^10).hyper;

The cause was tracked down to two iterators created for the same
$!work-stage-head object. In an identical situation Seq would throw
X::Seq::Consumed which seems logical. Similar approach was taken for
HyperSeq and RaceSeq.

Aside of this, I noticed that HyperSeq and RaceSeq share basicall
all their code except for hyper and race methods. I found it
reasonable to move all commonalities into a role.

Fixes #4413

@vrurg vrurg added the WIP Work In Progress, do not merge (yet) label Jun 19, 2021
@vrurg
Copy link
Member Author

vrurg commented Jun 19, 2021

I'm not marking this PR as draft because it is basically done and ready. The only thing I'm not sure about is the new role name. Is Sequence::Hyper OK, or is it better to move it under Rakudo::Internals and make something like Rakudo::Internals::HyperSequence for uniformity purpose?

Also, when the role is moved into a dedicated file it's gonna be almost the first case of adding a new one since Raku extensions were approved. So, it's tempting to make it the first .rakumod in the core.

@vrurg vrurg requested review from lizmat and jnthn June 19, 2021 02:45
vrurg added a commit to vrurg/roast that referenced this pull request Jun 19, 2021
`HyperSeq` and `RaceSeq` should throw if an iterator has been already
produced for them, similar to what `Seq` currently does.

In support of rakudo/rakudo#4416 and rakudo/rakudo#4413
vrurg added a commit to vrurg/roast that referenced this pull request Jun 19, 2021
`HyperSeq` and `RaceSeq` should throw if an iterator has been already
produced for them, similar to what `Seq` currently does.

In support of rakudo/rakudo#4416 and rakudo/rakudo#4413
@lizmat
Copy link
Contributor

lizmat commented Jun 19, 2021

As this is mostly @jnthn's brainchild, I'm deferring review to him. I would definitely not merge this for a 2021.06 release.

On other notes:

  • I'm ok with the name
  • It can live in Rakudo::Internals, at least for now.

@jnthn
Copy link
Member

jnthn commented Jun 19, 2021

Given Sequence is the base role for every kind of Seq, I figure something like ParallelSequence would be more fitting.

src/core.c/Exception.pm6 Outdated Show resolved Hide resolved
"by assigning the Seq into an array)"
("The iterator of this $!kind is already in use/consumed by another $!kind" ~
" (you might solve this by adding .cache on usages of the $!kind, or " ~
"by assigning the $!kind into an array)").naive-word-wrapper
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm what is naive-word-wrapper? I'd expect such things to be applied at the point of exception printing, not in the message production...

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But we currently don't do it anyway. There are a couple other exceptions doing this. This particular message was previously using newlines inside the message to wrap it. So, I'd keep it this way until the printing starts wrapping.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, to be fair this was a more general grumble rather than anything that should block this PR.

src/core.c/HyperSeq.pm6 Outdated Show resolved Hide resolved
vrurg added a commit to vrurg/rakudo that referenced this pull request Jun 20, 2021
Take into account @jnthn notes from rakudo#4416
(rakudo#4416):

- Rename `Sequence::Hyper` into `ParallelSequence`
- Extract `ParallelSequence` into own file ParallelSequence.rakumod
- Make `X::Seq::Consumed` expect `$.kind` to contain a sequence class
- Make `ParallelSequence` `iterator` method thread-safe by using a
  `cas`-set flag.
- Add `ParallelSequence` to the list of expected symbol in tests
@vrurg
Copy link
Member Author

vrurg commented Jun 20, 2021

@jnthn All notes were taken into account except for the naive-word-wrapper due to the concerns I wrote about.

I also considered making Seq thread-safe too but it's probably never meant to be. So, I dropped the idea.

@vrurg vrurg changed the title [WIP] Fix freezes caused by concurrently produced iterators Fix freezes caused by concurrently produced iterators Jun 20, 2021
@vrurg vrurg added hyper/race and removed WIP Work In Progress, do not merge (yet) labels Jun 20, 2021
my role ParallelSequence does Iterable does Sequence {
has HyperConfiguration $.configuration;
has Rakudo::Internals::HyperWorkStage $!work-stage-head;
has $!has-iterator;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this should be has atomicint $!has-iterator

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(What you have relies on interning of Int, which is probably reliable, but still...)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this should be has atomicint $!has-iterator

atomicint was my choice too, but it is not generally available at this point. I tried changing the order of build with no success. But there was another error which I located later. Perhaps it was the problem, not the order. So, I will try that later today.

Freezes were happening with code similar to:

    (.list, .list) given (^10).hyper;

The cause was tracked down to two iterators created for the same
`$!work-stage-head` object. In an identical situation `Seq` would throw
`X::Seq::Consumed` which seems logical. Similar approach was taken for
`HyperSeq` and `RaceSeq`.

Aside of this, I noticed that `HyperSeq` and `RaceSeq` share basicall
all their code except for `hyper` and `race` methods. I found it
reasonable to move all commonalities into a role.

Fixes rakudo#4413
Take into account @jnthn notes from rakudo#4416
(rakudo#4416):

- Rename `Sequence::Hyper` into `ParallelSequence`
- Extract `ParallelSequence` into own file ParallelSequence.rakumod
- Make `X::Seq::Consumed` expect `$.kind` to contain a sequence class
- Make `ParallelSequence` `iterator` method thread-safe by using a
  `cas`-set flag.
- Add `ParallelSequence` to the list of expected symbol in tests
vrurg added a commit to vrurg/roast that referenced this pull request Jun 22, 2021
`HyperSeq` and `RaceSeq` should throw if an iterator has been already
produced for them, similar to what `Seq` currently does.

In support of rakudo/rakudo#4416 and rakudo/rakudo#4413
This required atomicops.pm6 to be moved upper in the order of core
files.
@vrurg
Copy link
Member Author

vrurg commented Jun 22, 2021

I will merge when get JVM backend fixed. It would probably have to deal with Int.

JVM doesn't have `atomicint`.
@vrurg vrurg merged commit 772711a into rakudo:master Jun 22, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Weird interaction between array interpolation, given and hyper
3 participants