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

Atomics: Handle timeouts in waits in the (single-threaded) interpreter #6408

Merged
merged 7 commits into from
Mar 19, 2024

Conversation

kripken
Copy link
Member

@kripken kripken commented Mar 18, 2024

The interpreter does not run multiple threads, and it was returning 0 from
atomic.wait, which means it was woken up. But it is more correct for it to
return 2, which means it timed out - which is actually the case, as no other
thread exists that can wake it up. However, even that is not good for fuzzing
as the timeout may be infinite or large, so just emit a host limit error on any
timeout for now, until we actually implement threads.

This was noticed by the fuzzer, as now we compare atomics testcases with V8.

@kripken kripken requested a review from tlively March 18, 2024 21:30
@tlively
Copy link
Member

tlively commented Mar 18, 2024

...which is actually the case...

Unless the timeout is negative, in which case the actual correct behavior is to hang indefinitely. Do we want to model that somehow?

@kripken
Copy link
Member Author

kripken commented Mar 18, 2024

Hmm, good question. Maybe we should error on that atm. I pushed that now.

@kripken
Copy link
Member Author

kripken commented Mar 18, 2024

Hmm, a downside to erroring like that is that we'd need to ignore all testcases with such inputs in the fuzzer, or else we error there. It might be simpler for now to just always return 2?

Comment on lines 3373 to 3379
// TODO: Add threads support.
// For now, as there are no other threads, if there is no timeout then
// error (this would hang forever), and if there is a timeout then
// just report that we timed out.
if (timeout.getSingleValue().getInteger() < 0) {
return Flow(NONCONSTANT_FLOW);
}
Copy link
Member

Choose a reason for hiding this comment

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

This should go after the not equal check if we decide to keep it.

Copy link
Member Author

Choose a reason for hiding this comment

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

Thanks, fixed.

@tlively
Copy link
Member

tlively commented Mar 19, 2024

Hmm, a downside to erroring like that is that we'd need to ignore all testcases with such inputs in the fuzzer, or else we error there. It might be simpler for now to just always return 2?

Given that there's no way usefully check the behavior of waiting without actual threads, this seems fine to me as long as we have a comment about it.

@kripken
Copy link
Member Author

kripken commented Mar 19, 2024

I added a comment and switched this to emitting a "host limit" trap. That is necessary for the fuzzer to know to ignore such testcases. I also made us emit that limit for any timeout that is nonzero, as not only an infinite timeout can hang but even a small finite one, inside a loop.

@kripken kripken changed the title Atomics: Return that we timeout in waits in the (single-threaded) interpreter Atomics: Handle timeouts in waits in the (single-threaded) interpreter Mar 19, 2024
@tlively
Copy link
Member

tlively commented Mar 19, 2024

Aren't infinite loops already handled by separate machinery, though?

@kripken
Copy link
Member Author

kripken commented Mar 19, 2024

These wouldn't be infinite, but just very slow. Imagine even a 1ms timeout executed a million times.

@kripken
Copy link
Member Author

kripken commented Mar 19, 2024

That is, even a 1ms timeout would make this by far our slowest instruction 🐢

@tlively
Copy link
Member

tlively commented Mar 19, 2024

Oh sure, but I don't think we should actually implement them with a wait. No execution environment our interpreter runs in actually cares about wall clock time, right? I would expect that we would return a 2 immediately for any non-negative timeout and and return a host limit exception that the fuzzer can ignore for any negative timeout.

@kripken
Copy link
Member Author

kripken commented Mar 19, 2024

Sorry, I should have said: The problem isn't in our interpreter but when we run V8 in the fuzzer. V8 does obey the timeouts. So it seems best to mark any timeout as a host limit for us (which then gets skipped in the fuzzer).

@tlively
Copy link
Member

tlively commented Mar 19, 2024

Oh, I see the issue. Yes, this makes sense, then.

@kripken kripken merged commit 4ce9fb4 into WebAssembly:main Mar 19, 2024
14 checks passed
@kripken kripken deleted the atomic.wait branch March 19, 2024 19:34
@gkdn gkdn mentioned this pull request Aug 31, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants