-
-
Notifications
You must be signed in to change notification settings - Fork 2.4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
rt: fix bug in work-stealing queue (#2387)
Fixes a couple bugs in the work-stealing queue introduced as part of #2315. First, the cursor needs to be able to represent more values than the size of the buffer. This is to be able to track if `tail` is ahead of `head` or if they are identical. This bug resulted in the "overflow" path being taken before the buffer was full. The second bug can happen when a queue is being stolen from concurrently with stealing into. In this case, it is possible for buffer slots to be overwritten before they are released by the stealer. This is harder to happen in practice due to the first bug preventing the queue from filling up 100%, but could still happen. It triggered an assertion in `steal_into`. This bug slipped through due to a bug in loom not correctly catching the case. The loom bug is fixed as part of tokio-rs/loom#119. Fixes: #2382
- Loading branch information
1 parent
de8326a
commit 58ba45a
Showing
8 changed files
with
387 additions
and
44 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
use std::cell::UnsafeCell; | ||
use std::fmt; | ||
use std::ops::Deref; | ||
|
||
/// `AtomicU16` providing an additional `load_unsync` function. | ||
pub(crate) struct AtomicU16 { | ||
inner: UnsafeCell<std::sync::atomic::AtomicU16>, | ||
} | ||
|
||
unsafe impl Send for AtomicU16 {} | ||
unsafe impl Sync for AtomicU16 {} | ||
|
||
impl AtomicU16 { | ||
pub(crate) fn new(val: u16) -> AtomicU16 { | ||
let inner = UnsafeCell::new(std::sync::atomic::AtomicU16::new(val)); | ||
AtomicU16 { inner } | ||
} | ||
|
||
/// Performs an unsynchronized load. | ||
/// | ||
/// # Safety | ||
/// | ||
/// All mutations must have happened before the unsynchronized load. | ||
/// Additionally, there must be no concurrent mutations. | ||
pub(crate) unsafe fn unsync_load(&self) -> u16 { | ||
*(*self.inner.get()).get_mut() | ||
} | ||
} | ||
|
||
impl Deref for AtomicU16 { | ||
type Target = std::sync::atomic::AtomicU16; | ||
|
||
fn deref(&self) -> &Self::Target { | ||
// safety: it is always safe to access `&self` fns on the inner value as | ||
// we never perform unsafe mutations. | ||
unsafe { &*self.inner.get() } | ||
} | ||
} | ||
|
||
impl fmt::Debug for AtomicU16 { | ||
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { | ||
self.deref().fmt(fmt) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.