1#[cfg(feature = "sc-drf")]
2use crate::std::sync::atomic_sc::ordering::SeqCst;
3use crate::{
4 ghost::{Perm, perm::PermTarget},
5 logic::FMap,
6 prelude::*,
7 std::sync::{
8 atomic::ordering::{Acquire, Relaxed, Release},
9 view::{AcquireSyncView, HasTimestamp, ReleaseSyncView, SyncView, Timestamp},
10 },
11};
12use core::marker::PhantomData;
13
14#[opaque]
21pub struct Committer<C: PermTarget, T, Load, Store>(PhantomData<(C, T, Load, Store)>);
22
23impl<C: PermTarget, T, Load, Store> Committer<C, T, Load, Store> {
24 #[logic(opaque)]
28 pub fn ward(self) -> C {
29 dead
30 }
31
32 #[logic(opaque)]
40 pub fn timestamp(self) -> Timestamp {
41 dead
42 }
43
44 #[logic(opaque)]
46 pub fn val_load_logic(self) -> T {
47 dead
48 }
49
50 #[check(ghost)]
52 #[trusted]
53 #[logic_alias(self.val_load_logic())]
54 pub fn val_load(&self) -> T {
55 panic!("Should not be called outside ghost code")
56 }
57
58 #[logic(opaque)]
60 pub fn val_store_logic(self) -> T {
61 dead
62 }
63
64 #[check(ghost)]
66 #[trusted]
67 #[logic_alias(self.val_store_logic())]
68 pub fn val_store(&self) -> T {
69 panic!("Should not be called outside ghost code")
70 }
71
72 #[logic(opaque)]
74 pub fn shot_store(self) -> bool {
75 dead
76 }
77
78 #[logic(open, inline)]
79 pub fn hist_inv(self, other: Self) -> bool {
80 self.ward() == other.ward()
81 && self.val_load() == other.val_load()
82 && self.val_store() == other.val_store()
83 && self.timestamp() == other.timestamp()
84 }
85}
86
87impl<C, T, Store> Committer<C, T, Relaxed, Store>
88where
89 C: PermTarget<Value = FMap<Timestamp, (T, SyncView)>> + HasTimestamp,
90{
91 #[requires(!self.shot_store())]
95 #[requires(self.ward() == *own.ward())]
96 #[ensures(*sync_view <= ^sync_view)]
97 #[ensures(self.ward().get_timestamp(*sync_view) <= self.timestamp())]
98 #[ensures(self.timestamp() <= self.ward().get_timestamp(^sync_view))]
99 #[ensures(own.val().lookup(self.timestamp()) == Some((self.val_load(), result@)))]
100 #[check(ghost)]
101 #[trusted]
102 #[allow(unused_variables)]
103 pub fn shoot_load(&self, own: &Perm<C>, sync_view: &mut SyncView) -> AcquireSyncView {
104 panic!("Should not be called outside ghost code")
105 }
106}
107
108impl<C, T, Store> Committer<C, T, Acquire, Store>
109where
110 C: PermTarget<Value = FMap<Timestamp, (T, SyncView)>> + HasTimestamp,
111{
112 #[requires(!self.shot_store())]
116 #[requires(self.ward() == *own.ward())]
117 #[ensures(*sync_view <= ^sync_view)]
118 #[ensures(self.ward().get_timestamp(*sync_view) <= self.timestamp())]
119 #[ensures(self.timestamp() <= self.ward().get_timestamp(^sync_view))]
120 #[ensures(match own.val().lookup(self.timestamp()) {
121 Some((v, v_view)) => v == self.val_load() && v_view <= ^sync_view,
122 None => false
123 })]
124 #[check(ghost)]
125 #[trusted]
126 #[allow(unused_variables)]
127 pub fn shoot_load(&self, own: &Perm<C>, sync_view: &mut SyncView) {
128 panic!("Should not be called outside ghost code")
129 }
130}
131
132#[cfg(feature = "sc-drf")]
133impl<C, Store> Committer<C, C::Value, SeqCst, Store>
134where
135 C: PermTarget,
136 C::Value: Sized,
137{
138 #[requires(!self.shot_store())]
142 #[requires(self.ward() == *own.ward())]
143 #[ensures(self.val_load() == own.val())]
144 #[check(ghost)]
145 #[trusted]
146 #[allow(unused_variables)]
147 pub fn shoot_load(&self, own: &Perm<C>) {
148 panic!("Should not be called outside ghost code")
149 }
150}
151
152impl<C, T, Load> Committer<C, T, Load, Relaxed>
153where
154 C: PermTarget<Value = FMap<Timestamp, (T, SyncView)>> + HasTimestamp,
155{
156 #[requires(!(*self).shot_store())]
160 #[requires(self.ward() == *(*own).ward())]
161 #[ensures((*self).hist_inv(^self))]
162 #[ensures((^self).shot_store())]
163 #[ensures((*own).ward() == (^own).ward())]
164 #[ensures(*sync_view <= ^sync_view)]
165 #[ensures((*self).ward().get_timestamp(*sync_view) <= self.timestamp())]
166 #[ensures(self.timestamp() < (*self).ward().get_timestamp(^sync_view))]
167 #[ensures((*own).val().lookup(self.timestamp() + 1) == None)]
168 #[ensures((^own).val() == (*own).val().add(self.timestamp() + 1, ((*self).val_store(), rel_view@)))]
169 #[check(ghost)]
170 #[trusted]
171 #[allow(unused_variables)]
172 pub fn shoot_store(
173 &mut self,
174 own: &mut Perm<C>,
175 sync_view: &mut SyncView,
176 rel_view: ReleaseSyncView,
177 ) {
178 panic!("Should not be called outside ghost code")
179 }
180}
181
182impl<C, T, Load> Committer<C, T, Load, Release>
183where
184 C: PermTarget<Value = FMap<Timestamp, (T, SyncView)>> + HasTimestamp,
185{
186 #[requires(!(*self).shot_store())]
190 #[requires(self.ward() == *(*own).ward())]
191 #[ensures((*self).hist_inv(^self))]
192 #[ensures((^self).shot_store())]
193 #[ensures((*own).ward() == (^own).ward())]
194 #[ensures(*sync_view <= ^sync_view)]
195 #[ensures((*self).ward().get_timestamp(*sync_view) <= self.timestamp())]
196 #[ensures(self.timestamp() < (*self).ward().get_timestamp(^sync_view))]
197 #[ensures((*own).val().lookup(self.timestamp() + 1) == None)]
198 #[ensures((^own).val() == (*own).val().add(self.timestamp() + 1, ((*self).val_store(), ^sync_view)))]
199 #[check(ghost)]
200 #[trusted]
201 #[allow(unused_variables)]
202 pub fn shoot_store(&mut self, own: &mut Perm<C>, sync_view: &mut SyncView) {
203 panic!("Should not be called outside ghost code")
204 }
205}
206
207#[cfg(feature = "sc-drf")]
208impl<C, Load> Committer<C, C::Value, Load, SeqCst>
209where
210 C: PermTarget,
211 C::Value: Sized,
212{
213 #[requires(!(*self).shot_store())]
217 #[requires(self.ward() == *(*own).ward())]
218 #[ensures((*self).hist_inv(^self))]
219 #[ensures((^self).shot_store())]
220 #[ensures((*own).ward() == (^own).ward())]
221 #[ensures((^own).val() == (*self).val_store())]
222 #[check(ghost)]
223 #[trusted]
224 #[allow(unused_variables)]
225 pub fn shoot_store(&mut self, own: &mut Perm<C>) {
226 panic!("Should not be called outside ghost code")
227 }
228}