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 of the latest load, before any store.

This is used for an update operation.

logic(opaque)

Source

pub fn val_load(self) -> T

Value read from the atomic operation.

logic(opaque)

Source

pub fn val_store(self) -> T

Value written by the atomic operation.

logic(opaque)

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<'static> = FMap<Timestamp, (T, SyncView)>> + HasTimestamp + 'static,

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().get(self.timestamp()) == Some((self.val_load(), result@))

terminates

ghost

Source§

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

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().get(self.timestamp()) {
    Some((v, v_view)) => v == self.val_load() && v_view <= ^sync_view,
    None => false
}

terminates

ghost

Source§

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

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()

terminates

ghost

Source§

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

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().get(self.timestamp() + 1) == None

ensures

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

terminates

ghost

Source§

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

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().get(self.timestamp() + 1) == None

ensures

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

terminates

ghost

Source§

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

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()

terminates

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>
where C: Objective, T: Objective, Load: Objective, Store: Objective,

§

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

§

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

§

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

§

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

§

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

§

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

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.