diff options
author | Valentin Popov <valentin@popov.link> | 2024-07-19 15:37:58 +0300 |
---|---|---|
committer | Valentin Popov <valentin@popov.link> | 2024-07-19 15:37:58 +0300 |
commit | a990de90fe41456a23e58bd087d2f107d321f3a1 (patch) | |
tree | 15afc392522a9e85dc3332235e311b7d39352ea9 /vendor/crossbeam-epoch/src/epoch.rs | |
parent | 3d48cd3f81164bbfc1a755dc1d4a9a02f98c8ddd (diff) | |
download | fparkan-a990de90fe41456a23e58bd087d2f107d321f3a1.tar.xz fparkan-a990de90fe41456a23e58bd087d2f107d321f3a1.zip |
Deleted vendor folder
Diffstat (limited to 'vendor/crossbeam-epoch/src/epoch.rs')
-rw-r--r-- | vendor/crossbeam-epoch/src/epoch.rs | 132 |
1 files changed, 0 insertions, 132 deletions
diff --git a/vendor/crossbeam-epoch/src/epoch.rs b/vendor/crossbeam-epoch/src/epoch.rs deleted file mode 100644 index 18d7418..0000000 --- a/vendor/crossbeam-epoch/src/epoch.rs +++ /dev/null @@ -1,132 +0,0 @@ -//! The global epoch -//! -//! The last bit in this number is unused and is always zero. Every so often the global epoch is -//! incremented, i.e. we say it "advances". A pinned participant may advance the global epoch only -//! if all currently pinned participants have been pinned in the current epoch. -//! -//! If an object became garbage in some epoch, then we can be sure that after two advancements no -//! participant will hold a reference to it. That is the crux of safe memory reclamation. - -use crate::primitive::sync::atomic::{AtomicUsize, Ordering}; - -/// An epoch that can be marked as pinned or unpinned. -/// -/// Internally, the epoch is represented as an integer that wraps around at some unspecified point -/// and a flag that represents whether it is pinned or unpinned. -#[derive(Copy, Clone, Default, Debug, Eq, PartialEq)] -pub(crate) struct Epoch { - /// The least significant bit is set if pinned. The rest of the bits hold the epoch. - data: usize, -} - -impl Epoch { - /// Returns the starting epoch in unpinned state. - #[inline] - pub(crate) fn starting() -> Self { - Self::default() - } - - /// Returns the number of epochs `self` is ahead of `rhs`. - /// - /// Internally, epochs are represented as numbers in the range `(isize::MIN / 2) .. (isize::MAX - /// / 2)`, so the returned distance will be in the same interval. - pub(crate) fn wrapping_sub(self, rhs: Self) -> isize { - // The result is the same with `(self.data & !1).wrapping_sub(rhs.data & !1) as isize >> 1`, - // because the possible difference of LSB in `(self.data & !1).wrapping_sub(rhs.data & !1)` - // will be ignored in the shift operation. - self.data.wrapping_sub(rhs.data & !1) as isize >> 1 - } - - /// Returns `true` if the epoch is marked as pinned. - #[inline] - pub(crate) fn is_pinned(self) -> bool { - (self.data & 1) == 1 - } - - /// Returns the same epoch, but marked as pinned. - #[inline] - pub(crate) fn pinned(self) -> Epoch { - Epoch { - data: self.data | 1, - } - } - - /// Returns the same epoch, but marked as unpinned. - #[inline] - pub(crate) fn unpinned(self) -> Epoch { - Epoch { - data: self.data & !1, - } - } - - /// Returns the successor epoch. - /// - /// The returned epoch will be marked as pinned only if the previous one was as well. - #[inline] - pub(crate) fn successor(self) -> Epoch { - Epoch { - data: self.data.wrapping_add(2), - } - } -} - -/// An atomic value that holds an `Epoch`. -#[derive(Default, Debug)] -pub(crate) struct AtomicEpoch { - /// Since `Epoch` is just a wrapper around `usize`, an `AtomicEpoch` is similarly represented - /// using an `AtomicUsize`. - data: AtomicUsize, -} - -impl AtomicEpoch { - /// Creates a new atomic epoch. - #[inline] - pub(crate) fn new(epoch: Epoch) -> Self { - let data = AtomicUsize::new(epoch.data); - AtomicEpoch { data } - } - - /// Loads a value from the atomic epoch. - #[inline] - pub(crate) fn load(&self, ord: Ordering) -> Epoch { - Epoch { - data: self.data.load(ord), - } - } - - /// Stores a value into the atomic epoch. - #[inline] - pub(crate) fn store(&self, epoch: Epoch, ord: Ordering) { - self.data.store(epoch.data, ord); - } - - /// Stores a value into the atomic epoch if the current value is the same as `current`. - /// - /// The return value is a result indicating whether the new value was written and containing - /// the previous value. On success this value is guaranteed to be equal to `current`. - /// - /// This method takes two `Ordering` arguments to describe the memory - /// ordering of this operation. `success` describes the required ordering for the - /// read-modify-write operation that takes place if the comparison with `current` succeeds. - /// `failure` describes the required ordering for the load operation that takes place when - /// the comparison fails. Using `Acquire` as success ordering makes the store part - /// of this operation `Relaxed`, and using `Release` makes the successful load - /// `Relaxed`. The failure ordering can only be `SeqCst`, `Acquire` or `Relaxed` - /// and must be equivalent to or weaker than the success ordering. - #[inline] - pub(crate) fn compare_exchange( - &self, - current: Epoch, - new: Epoch, - success: Ordering, - failure: Ordering, - ) -> Result<Epoch, Epoch> { - match self - .data - .compare_exchange(current.data, new.data, success, failure) - { - Ok(data) => Ok(Epoch { data }), - Err(data) => Err(Epoch { data }), - } - } -} |