Skip to main content

Committer

Struct Committer 

Source
pub struct Committer<C: PermTarget, T, Load, Store>(/* private fields */);
Expand description

Wrapper around a single atomic operation, where multiple ghost steps can be performed.

Note: For load-only accesses, this committer has no observable effect on ghost ressources. Thus, it is optional to shoot it, and nothing prevent the user from shooting it several times.

Implementations§

Source§

impl<C: PermTarget, T, Load, Store> Committer<C, T, Load, Store>

Source

pub fn ward(self) -> C

Identity of the committer

This is used so that we can only use the committer with the right [AtomicOwn].

logic(opaque) ⚠

Source

pub fn timestamp(self) -> Timestamp

Timestamp used for the atomic operation. For a load operation, this is the timestamp of the value read. For a store operation, this is the predecessor of the timestamp of the value written.

The use of the predecessor for store operations allows us to use the same logical function for the timestamp for both the load and the store in a read-modify-write operation. Indeed, in the case of a read-modify-write operation, the timestamp of the store is the successor of the timestamp of the load.

logic(opaque) ⚠

Source

pub fn val_load_logic(self) -> T

Value read from the atomic operation.

logic(opaque) ⚠

Source

pub fn val_load(&self) -> T

Value read from the atomic operation.

ghost

ensures

#[logic_alias(self.val_load_logic())]

Source

pub fn val_store_logic(self) -> T

Value written by the atomic operation.

logic(opaque) ⚠

Source

pub fn val_store(&self) -> T

Value written by the atomic operation.

ghost

ensures

#[logic_alias(self.val_store_logic())]

Source

pub fn shot_store(self) -> bool

Status of the committer

logic(opaque) ⚠

Source

pub fn hist_inv(self, other: Self) -> bool

logic(open, inline)

self.ward() == other.ward()
    && self.val_load() == other.val_load()
    && self.val_store() == other.val_store()
    && self.timestamp() == other.timestamp()
Source§

impl<C, T, Store> Committer<C, T, Relaxed, Store>
where C: PermTarget<Value = FMap<Timestamp, (T, SyncView)>> + HasTimestamp,

Source

pub fn shoot_load( &self, own: &Perm<C>, sync_view: &mut SyncView, ) -> AcquireSyncView

‘Shoot’ the committer

This does the read on the atomic in ghost code.

requires

!self.shot_store()

requires

self.ward() == *own.ward()

ensures

*sync_view <= ^sync_view

ensures

self.ward().get_timestamp(*sync_view) <= self.timestamp()

ensures

self.timestamp() <= self.ward().get_timestamp(^sync_view)

ensures

own.val().lookup(self.timestamp()) == Some((self.val_load(), result@))

ghost

Source§

impl<C, T, Store> Committer<C, T, Acquire, Store>
where C: PermTarget<Value = FMap<Timestamp, (T, SyncView)>> + HasTimestamp,

Source

pub fn shoot_load(&self, own: &Perm<C>, sync_view: &mut SyncView)

‘Shoot’ the committer

This does the read on the atomic in ghost code.

requires

!self.shot_store()

requires

self.ward() == *own.ward()

ensures

*sync_view <= ^sync_view

ensures

self.ward().get_timestamp(*sync_view) <= self.timestamp()

ensures

self.timestamp() <= self.ward().get_timestamp(^sync_view)

ensures

match own.val().lookup(self.timestamp()) {
    Some((v, v_view)) => v == self.val_load() && v_view <= ^sync_view,
    None => false
}

ghost

Source§

impl<C, Store> Committer<C, C::Value, SeqCst, Store>
where C: PermTarget, C::Value: Sized,

Source

pub fn shoot_load(&self, own: &Perm<C>)

‘Shoot’ the committer

This does the read on the atomic in ghost code.

requires

!self.shot_store()

requires

self.ward() == *own.ward()

ensures

self.val_load() == own.val()

ghost

Source§

impl<C, T, Load> Committer<C, T, Load, Relaxed>
where C: PermTarget<Value = FMap<Timestamp, (T, SyncView)>> + HasTimestamp,

Source

pub fn shoot_store( &mut self, own: &mut Perm<C>, sync_view: &mut SyncView, rel_view: ReleaseSyncView, )

‘Shoot’ the committer (Relaxed)

This does the write on the atomic in ghost code, and can only be called once.

requires

!(*self).shot_store()

requires

self.ward() == *(*own).ward()

ensures

(*self).hist_inv(^self)

ensures

(^self).shot_store()

ensures

(*own).ward() == (^own).ward()

ensures

*sync_view <= ^sync_view

ensures

(*self).ward().get_timestamp(*sync_view) <= self.timestamp()

ensures

self.timestamp() < (*self).ward().get_timestamp(^sync_view)

ensures

(*own).val().lookup(self.timestamp() + 1) == None

ensures

(^own).val() == (*own).val().add(self.timestamp() + 1, ((*self).val_store(), rel_view@))

ghost

Source§

impl<C, T, Load> Committer<C, T, Load, Release>
where C: PermTarget<Value = FMap<Timestamp, (T, SyncView)>> + HasTimestamp,

Source

pub fn shoot_store(&mut self, own: &mut Perm<C>, sync_view: &mut SyncView)

‘Shoot’ the committer

This does the write on the atomic in ghost code, and can only be called once.

requires

!(*self).shot_store()

requires

self.ward() == *(*own).ward()

ensures

(*self).hist_inv(^self)

ensures

(^self).shot_store()

ensures

(*own).ward() == (^own).ward()

ensures

*sync_view <= ^sync_view

ensures

(*self).ward().get_timestamp(*sync_view) <= self.timestamp()

ensures

self.timestamp() < (*self).ward().get_timestamp(^sync_view)

ensures

(*own).val().lookup(self.timestamp() + 1) == None

ensures

(^own).val() == (*own).val().add(self.timestamp() + 1, ((*self).val_store(), ^sync_view))

ghost

Source§

impl<C, Load> Committer<C, C::Value, Load, SeqCst>
where C: PermTarget, C::Value: Sized,

Source

pub fn shoot_store(&mut self, own: &mut Perm<C>)

‘Shoot’ the committer

This does the write on the atomic in ghost code, and can only be called once.

requires

!(*self).shot_store()

requires

self.ward() == *(*own).ward()

ensures

(*self).hist_inv(^self)

ensures

(^self).shot_store()

ensures

(*own).ward() == (^own).ward()

ensures

(^own).val() == (*self).val_store()

ghost

Auto Trait Implementations§

§

impl<C, T, Load, Store> Freeze for Committer<C, T, Load, Store>

§

impl<C, T, Load, Store> Objective for Committer<C, T, Load, Store>

§

impl<C, T, Load, Store> RefUnwindSafe for Committer<C, T, Load, Store>

§

impl<C, T, Load, Store> Send for Committer<C, T, Load, Store>

§

impl<C, T, Load, Store> Sync for Committer<C, T, Load, Store>

§

impl<C, T, Load, Store> Unpin for Committer<C, T, Load, Store>

§

impl<C, T, Load, Store> UnsafeUnpin for Committer<C, T, Load, Store>

§

impl<C, T, Load, Store> UnwindSafe for Committer<C, T, Load, Store>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.