[−][src]Struct stateright::semantics::LinearizabilityTester
This tester captures a potentially concurrent history of operations and
validates that it adheres to a SequentialSpec
based on the
linearizability consistency model. This model requires that operations be
applied atomically and that sequenced (non-concurrent) operations are
applied in order.
If you're not sure whether to pick this or SequentialConsistencyTester
, favor
LinearizabilityTester
.
Linearizability
Unlike with sequential consistency, all sequenced (non-concurrent) operations must respect a happens-before relationship, even across threads, which ensures that histories respect "real time" ordering (defined more precisely below). Anomalies are prevented because threads all agree on the viable order of operations. For example, the later read by Thread 2 must read the value of Thread 1's write (rather than a differing earlier value) since those two operations are not concurrent:
-----------Time------------------------------>
Thread 1: [write invoked... and returns]
Thread 2: [read invoked... and returns]
While "real time" is a common way to phrase an implicit total ordering on non-concurrent events spanning threads, a more precise way to think about this is that prior to Thread 2 starting its read, Thread 1 is capable of communicating with Thread 2 indicating that the write finished. This perspective avoids introducing the notion of a shared global time, which is often a misleading perspective when it comes to distributed systems (or even modern physics in general).
The SequentialSpec
will imply additional ordering constraints based on semantics specific
to each operation. For example, a value cannot be popped off a stack before it is pushed. It is
then the responsibility of this tester to establish whether a valid total ordering of events
exists under these constraints.
See also: SequentialConsistencyTester
.
Implementations
impl<T: Ord, RefObj: SequentialSpec> LinearizabilityTester<T, RefObj>
[src]
pub fn new(init_ref_obj: RefObj) -> Self
[src]
Constructs a LinearizabilityTester
.
pub fn len(&self) -> usize
[src]
Indicates the aggregate number of operations completed or in flight across all threads.
impl<T, RefObj> LinearizabilityTester<T, RefObj> where
T: Copy + Debug + Ord,
RefObj: SequentialSpec,
RefObj::Op: Debug,
RefObj::Ret: Debug + PartialEq,
[src]
T: Copy + Debug + Ord,
RefObj: SequentialSpec,
RefObj::Op: Debug,
RefObj::Ret: Debug + PartialEq,
pub fn on_invoke(
&mut self,
thread_id: T,
op: RefObj::Op
) -> Result<&mut Self, String>
[src]
&mut self,
thread_id: T,
op: RefObj::Op
) -> Result<&mut Self, String>
Indicates that a thread invoked an operation. Returns Ok(...)
if the
history is valid, even if it is not lineariable.
pub fn on_return(
&mut self,
thread_id: T,
ret: RefObj::Ret
) -> Result<&mut Self, String>
[src]
&mut self,
thread_id: T,
ret: RefObj::Ret
) -> Result<&mut Self, String>
Indicates that a thread's earlier operation invocation returned. Returns
Ok(...)
if the history is valid, even if it is not linearizable.
pub fn on_invret(
&mut self,
thread_id: T,
op: RefObj::Op,
ret: RefObj::Ret
) -> Result<&mut Self, String>
[src]
&mut self,
thread_id: T,
op: RefObj::Op,
ret: RefObj::Ret
) -> Result<&mut Self, String>
A helper that indicates both an operation and corresponding return
value for a thread. Returns Ok(...)
if the history is valid, even if
it is not lineariable.
pub fn serialized_history(&self) -> Option<Vec<(RefObj::Op, RefObj::Ret)>> where
RefObj: Clone,
RefObj::Op: Clone,
RefObj::Ret: Clone,
[src]
RefObj: Clone,
RefObj::Op: Clone,
RefObj::Ret: Clone,
Attempts to serialize the recorded partially ordered operation history into a total order that is consistent with a reference object's operational semantics.
Trait Implementations
impl<ThreadId: Clone, RefObj: Clone + SequentialSpec> Clone for LinearizabilityTester<ThreadId, RefObj> where
RefObj::Op: Clone,
RefObj::Ret: Clone,
RefObj::Op: Clone,
[src]
RefObj::Op: Clone,
RefObj::Ret: Clone,
RefObj::Op: Clone,
pub fn clone(&self) -> LinearizabilityTester<ThreadId, RefObj>
[src]
pub fn clone_from(&mut self, source: &Self)
1.0.0[src]
impl<ThreadId: Debug, RefObj: Debug + SequentialSpec> Debug for LinearizabilityTester<ThreadId, RefObj> where
RefObj::Op: Debug,
RefObj::Ret: Debug,
RefObj::Op: Debug,
[src]
RefObj::Op: Debug,
RefObj::Ret: Debug,
RefObj::Op: Debug,
impl<T: Ord, RefObj> Default for LinearizabilityTester<T, RefObj> where
RefObj: Default + SequentialSpec,
[src]
RefObj: Default + SequentialSpec,
impl<ThreadId: Eq, RefObj: Eq + SequentialSpec> Eq for LinearizabilityTester<ThreadId, RefObj> where
RefObj::Op: Eq,
RefObj::Ret: Eq,
RefObj::Op: Eq,
[src]
RefObj::Op: Eq,
RefObj::Ret: Eq,
RefObj::Op: Eq,
impl<ThreadId: Hash, RefObj: Hash + SequentialSpec> Hash for LinearizabilityTester<ThreadId, RefObj> where
RefObj::Op: Hash,
RefObj::Ret: Hash,
RefObj::Op: Hash,
[src]
RefObj::Op: Hash,
RefObj::Ret: Hash,
RefObj::Op: Hash,
pub fn hash<__H: Hasher>(&self, state: &mut __H)
[src]
pub fn hash_slice<H>(data: &[Self], state: &mut H) where
H: Hasher,
1.3.0[src]
H: Hasher,
impl<ThreadId: PartialEq, RefObj: PartialEq + SequentialSpec> PartialEq<LinearizabilityTester<ThreadId, RefObj>> for LinearizabilityTester<ThreadId, RefObj> where
RefObj::Op: PartialEq,
RefObj::Ret: PartialEq,
RefObj::Op: PartialEq,
[src]
RefObj::Op: PartialEq,
RefObj::Ret: PartialEq,
RefObj::Op: PartialEq,
pub fn eq(&self, other: &LinearizabilityTester<ThreadId, RefObj>) -> bool
[src]
pub fn ne(&self, other: &LinearizabilityTester<ThreadId, RefObj>) -> bool
[src]
impl<T, RefObj> Serialize for LinearizabilityTester<T, RefObj> where
RefObj: Serialize + SequentialSpec,
RefObj::Op: Serialize,
RefObj::Ret: Serialize,
T: Ord + Serialize,
[src]
RefObj: Serialize + SequentialSpec,
RefObj::Op: Serialize,
RefObj::Ret: Serialize,
T: Ord + Serialize,
impl<ThreadId, RefObj: SequentialSpec> StructuralEq for LinearizabilityTester<ThreadId, RefObj>
[src]
impl<ThreadId, RefObj: SequentialSpec> StructuralPartialEq for LinearizabilityTester<ThreadId, RefObj>
[src]
Auto Trait Implementations
impl<ThreadId, RefObj> RefUnwindSafe for LinearizabilityTester<ThreadId, RefObj> where
RefObj: RefUnwindSafe,
ThreadId: RefUnwindSafe,
<RefObj as SequentialSpec>::Op: RefUnwindSafe,
<RefObj as SequentialSpec>::Ret: RefUnwindSafe,
[src]
RefObj: RefUnwindSafe,
ThreadId: RefUnwindSafe,
<RefObj as SequentialSpec>::Op: RefUnwindSafe,
<RefObj as SequentialSpec>::Ret: RefUnwindSafe,
impl<ThreadId, RefObj> Send for LinearizabilityTester<ThreadId, RefObj> where
RefObj: Send,
ThreadId: Send,
<RefObj as SequentialSpec>::Op: Send,
<RefObj as SequentialSpec>::Ret: Send,
[src]
RefObj: Send,
ThreadId: Send,
<RefObj as SequentialSpec>::Op: Send,
<RefObj as SequentialSpec>::Ret: Send,
impl<ThreadId, RefObj> Sync for LinearizabilityTester<ThreadId, RefObj> where
RefObj: Sync,
ThreadId: Sync,
<RefObj as SequentialSpec>::Op: Sync,
<RefObj as SequentialSpec>::Ret: Sync,
[src]
RefObj: Sync,
ThreadId: Sync,
<RefObj as SequentialSpec>::Op: Sync,
<RefObj as SequentialSpec>::Ret: Sync,
impl<ThreadId, RefObj> Unpin for LinearizabilityTester<ThreadId, RefObj> where
RefObj: Unpin,
[src]
RefObj: Unpin,
impl<ThreadId, RefObj> UnwindSafe for LinearizabilityTester<ThreadId, RefObj> where
RefObj: UnwindSafe,
ThreadId: RefUnwindSafe,
<RefObj as SequentialSpec>::Op: RefUnwindSafe,
<RefObj as SequentialSpec>::Ret: RefUnwindSafe,
[src]
RefObj: UnwindSafe,
ThreadId: RefUnwindSafe,
<RefObj as SequentialSpec>::Op: RefUnwindSafe,
<RefObj as SequentialSpec>::Ret: RefUnwindSafe,
Blanket Implementations
impl<T> Any for T where
T: 'static + ?Sized,
[src]
T: 'static + ?Sized,
impl<T> Borrow<T> for T where
T: ?Sized,
[src]
T: ?Sized,
impl<T> BorrowMut<T> for T where
T: ?Sized,
[src]
T: ?Sized,
pub fn borrow_mut(&mut self) -> &mut T
[src]
impl<Q, K> Equivalent<K> for Q where
K: Borrow<Q> + ?Sized,
Q: Eq + ?Sized,
[src]
K: Borrow<Q> + ?Sized,
Q: Eq + ?Sized,
pub fn equivalent(&self, key: &K) -> bool
[src]
impl<T> From<T> for T
[src]
impl<T, U> Into<U> for T where
U: From<T>,
[src]
U: From<T>,
impl<T> ToOwned for T where
T: Clone,
[src]
T: Clone,
type Owned = T
The resulting type after obtaining ownership.
pub fn to_owned(&self) -> T
[src]
pub fn clone_into(&self, target: &mut T)
[src]
impl<T, U> TryFrom<U> for T where
U: Into<T>,
[src]
U: Into<T>,
type Error = Infallible
The type returned in the event of a conversion error.
pub fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>
[src]
impl<T, U> TryInto<U> for T where
U: TryFrom<T>,
[src]
U: TryFrom<T>,
type Error = <U as TryFrom<T>>::Error
The type returned in the event of a conversion error.
pub fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>
[src]
impl<V, T> VZip<V> for T where
V: MultiLane<T>,
V: MultiLane<T>,