Struct vstd::invariant::AtomicInvariant
source · pub struct AtomicInvariant<K, V, Pred> { /* private fields */ }
Expand description
An AtomicInvariant
is a ghost object that provides “interior mutability”
for ghost objects, specifically, for tracked
ghost objects.
A reference &AtomicInvariant
may be shared between clients.
A client holding such a reference may open the invariant
to obtain ghost ownership of v1: V
, and then close the invariant by returning
ghost ownership of a (potentially) different object v2: V
.
An AtomicInvariant
implements Sync
and may be shared between threads.
However, this means that an AtomicInvariant
can be only opened for
the duration of a single sequentially consistent atomic operation.
Such operations are provided by our PAtomic
library.
For an invariant object without this atomicity restriction,
see LocalInvariant
, which gives up thread safety in exchange.
An AtomicInvariant
consists of:
- A predicate specified via the
InvariantPredicate
type bound, that determines what valuesV
may be saved inside the invariant. - A constant
K
, specified at construction type. The predicate function takes this constant as a parameter, so the constant allows users to dynamically configure the predicate function in a way that can’t be done at the type level. - A namespace. This is a bit of a technicality, and you can often just declare
it as an arbitrary integer with no issues. See the
open_local_invariant!
documentation for more details.
The constant and namespace are specified at construction time (AtomicInvariant::new
).
These values are fixed for the lifetime of the AtomicInvariant
object.
To open the invariant and access the stored object V
,
use the macro open_atomic_invariant!
.
The AtomicInvariant
API is an instance of the “invariant” method in Verus’s general philosophy on interior mutability.
Note: Rather than using AtomicInvariant
directly, we generally recommend
using the atomic_ghost
APIs.
Implementations§
source§impl<K, V, Pred: InvariantPredicate<K, V>> AtomicInvariant<K, V, Pred>
impl<K, V, Pred: InvariantPredicate<K, V>> AtomicInvariant<K, V, Pred>
sourcepub spec fn constant(&self) -> K
pub spec fn constant(&self) -> K
The constant specified upon the initialization of this AtomicInvariant
.
sourcepub open spec fn inv(&self, v: V) -> bool
pub open spec fn inv(&self, v: V) -> bool
{ Pred::inv(self.constant(), v) }
Returns true
if it is possible to store the value v
into the AtomicInvariant
.
This is equivalent to Pred::inv(self.constant(), v)
.
sourcepub proof fn new(k: K, tracked v: V, ns: int) -> tracked i : AtomicInvariant<K, V, Pred>
pub proof fn new(k: K, tracked v: V, ns: int) -> tracked i : AtomicInvariant<K, V, Pred>
Pred::inv(k, v),
ensuresi.constant() == k,
i.namespace() == ns,
Initialize a new AtomicInvariant
with constant k
. initial stored (tracked) value v
,
and in the namespace ns
.
sourcepub proof fn into_inner(self) -> tracked v : V
pub proof fn into_inner(self) -> tracked v : V
self.inv(v),
Destroys the AtomicInvariant
, returning the tracked value contained within.