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

Rewrite wait/notify with wasm threads #7629

Merged
merged 2 commits into from
Dec 5, 2023

Conversation

alexcrichton
Copy link
Member

This commit rewrites and refactors the ParkingSpot implementation in Wasmtime. This is motivated by #7623 primarily which is something I haven't been able to reproduce but it doesn't look like a spurious issue. Additionally in reviewing the previous implementation I'm not sure if it was technically spec-compliant.

Previously each parking spot was modeled with a single condition variable. All threads blocking on the same address would block on the same condition variable. When waking up N threads the condition variable would either use notify_all or notify_one N times. The part I wasn't so sure about is that each thread, when waking up, would "consume" a wakeup notification on the way out, going back to sleep if a notification wasn't available. This was intended to handle spurious wakeups from the OS condition variable in use. This could mean, however, that a spurious wakeup of one thread could consume a notification from another thread. This was documented already as a possibility and "probably ok" but my gut is that this behavior led to #7623, although I haven't been able to construct a trace that would lead the test here to deadlock.

Out of caution, however, this commit rewrites the implementation to be similar to what V8 and SpiderMonkey are doing. Both of those implementations are using a linked list of waiters for threads that are blocked and then notifying N threads dequeues N threads to wake them up. This makes the semantics of knowing which thread is waken up easier to understand from an implementation point of view since each wakeup notification deterministically goes to a specified thread. The tricky part about this implementation is that a doubly-linked-list needs to be maintained within ParkingSpot to handle this.

While I was here I additionally refactored the interface of ParkingSpot to more closely match the raw interface of WebAssembly. This is intended to scope the problem being solved more narrowly to what wasm needs rather than trying to solve a more general problem at the same time.

Closes #7623

This commit rewrites and refactors the `ParkingSpot` implementation in
Wasmtime. This is motivated by bytecodealliance#7623 primarily which is something I haven't
been able to reproduce but it doesn't look like a spurious issue. Additionally
in reviewing the previous implementation I'm not sure if it was technically
spec-compliant.

Previously each parking spot was modeled with a single condition variable. All
threads blocking on the same address would block on the same condition
variable. When waking up N threads the condition variable would either use
`notify_all` or `notify_one` N times. The part I wasn't so sure about is that
each thread, when waking up, would "consume" a wakeup notification on the way
out, going back to sleep if a notification wasn't available. This was intended
to handle spurious wakeups from the OS condition variable in use. This could
mean, however, that a spurious wakeup of one thread could consume a
notification from another thread. This was documented already as a possibility
and "probably ok" but my gut is that this behavior led to bytecodealliance#7623, although I
haven't been able to construct a trace that would lead the test here to
deadlock.

Out of caution, however, this commit rewrites the implementation to be similar
to what V8 and SpiderMonkey are doing. Both of those implementations are using
a linked list of waiters for threads that are blocked and then notifying
N threads dequeues N threads to wake them up. This makes the semantics
of knowing which thread is waken up easier to understand from an
implementation point of view since each wakeup notification
deterministically goes to a specified thread. The tricky part about this
implementation is that a doubly-linked-list needs to be maintained
within `ParkingSpot` to handle this.

While I was here I additionally refactored the interface of
`ParkingSpot` to more closely match the raw interface of WebAssembly.
This is intended to scope the problem being solved more narrowly to what
wasm needs rather than trying to solve a more general problem at the
same time.

Closes bytecodealliance#7623
@alexcrichton alexcrichton requested a review from a team as a code owner December 4, 2023 17:58
@alexcrichton alexcrichton requested review from pchickey and removed request for a team December 4, 2023 17:58
@alexcrichton alexcrichton added this pull request to the merge queue Dec 5, 2023
Merged via the queue into bytecodealliance:main with commit 8e7f67a Dec 5, 2023
19 checks passed
@alexcrichton alexcrichton deleted the fix-wait-notify branch December 5, 2023 17:07
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.

Likely concurrency bug/deadlock in ParkingSpot
2 participants