ostd/specs/mm/frame/linked_list/
linked_list_owners.rs1use vstd::atomic::*;
2use vstd::prelude::*;
3use vstd::seq_lib::*;
4use vstd::simple_pptr::*;
5use vstd_extra::cast_ptr::Repr;
6use vstd_extra::ownership::*;
7
8use super::*;
9use crate::mm::frame::{AnyFrameMeta, CursorMut, Link, LinkedList, MetaSlot, UniqueFrameOwner};
10use crate::mm::Paddr;
11use crate::specs::arch::kspace::FRAME_METADATA_RANGE;
12use crate::specs::arch::mm::MAX_NR_PAGES;
13use crate::specs::mm::frame::mapping::META_SLOT_SIZE;
14
15verus! {
16
17pub ghost struct LinkModel {
18 pub paddr: Paddr,
19}
20
21impl Inv for LinkModel {
22 open spec fn inv(self) -> bool {
23 true
24 }
25}
26
27pub tracked struct LinkOwner {
28 pub paddr: Paddr,
29 pub in_list: u64,
30}
31
32impl Inv for LinkOwner {
33 open spec fn inv(self) -> bool {
34 true
35 }
36}
37
38impl View for LinkOwner {
39 type V = LinkModel;
40
41 open spec fn view(&self) -> Self::V {
42 LinkModel { paddr: self.paddr }
43 }
44}
45
46impl InvView for LinkOwner {
47 proof fn view_preserves_inv(self) {
48 }
49}
50
51impl<M: AnyFrameMeta + Repr<MetaSlot>> OwnerOf for Link<M> {
53 type Owner = LinkOwner;
54
55 open spec fn wf(self, owner: Self::Owner) -> bool {
56 true
57 }
62}
63
64impl<M: AnyFrameMeta + Repr<MetaSlot>> ModelOf for Link<M> {
65
66}
67
68pub ghost struct LinkedListModel {
69 pub list: Seq<LinkModel>,
70}
71
72impl LinkedListModel {
73 pub open spec fn front(self) -> Option<LinkModel> {
74 if self.list.len() > 0 {
75 Some(self.list[0])
76 } else {
77 None
78 }
79 }
80
81 pub open spec fn back(self) -> Option<LinkModel> {
82 if self.list.len() > 0 {
83 Some(self.list[self.list.len() - 1])
84 } else {
85 None
86 }
87 }
88}
89
90impl Inv for LinkedListModel {
91 open spec fn inv(self) -> bool {
92 true
93 }
94}
95
96#[rustc_has_incoherent_inherent_impls]
97pub tracked struct LinkedListOwner<M: AnyFrameMeta + Repr<MetaSlot>> {
98 pub list: Seq<LinkOwner>,
99 pub perms: Map<int, vstd_extra::cast_ptr::PointsTo<MetaSlot, Link<M>>>,
100 pub list_id: u64,
101}
102
103impl<M: AnyFrameMeta + Repr<MetaSlot>> Inv for LinkedListOwner<M> {
104 open spec fn inv(self) -> bool {
105 forall|i: int| 0 <= i < self.list.len() ==> self.inv_at(i)
106 }
107}
108
109impl<M: AnyFrameMeta + Repr<MetaSlot>> LinkedListOwner<M> {
110 pub open spec fn inv_at(self, i: int) -> bool {
111 &&& self.perms.contains_key(i)
112 &&& self.perms[i].addr() == self.list[i].paddr
113 &&& self.perms[i].points_to.addr() == self.list[i].paddr
114 &&& self.perms[i].wf()
115 &&& self.perms[i].addr() % META_SLOT_SIZE() == 0
116 &&& FRAME_METADATA_RANGE().start <= self.perms[i].addr() < FRAME_METADATA_RANGE().start
117 + MAX_NR_PAGES() * META_SLOT_SIZE()
118 &&& self.perms[i].is_init()
119 &&& self.perms[i].value().wf(self.list[i])
120 &&& i == 0 <==> self.perms[i].mem_contents().value().prev is None
121 &&& i == self.list.len() - 1 <==> self.perms[i].value().next is None
122 &&& 0 < i ==> self.perms[i].value().prev is Some && self.perms[i].value().prev.unwrap()
123 == self.perms[i - 1].pptr()
124 &&& i < self.list.len() - 1 ==> self.perms[i].value().next is Some
125 && self.perms[i].value().next.unwrap() == self.perms[i + 1].pptr()
126 &&& self.list[i].inv()
127 &&& self.list[i].in_list == self.list_id
128 }
129
130 pub open spec fn view_helper(owners: Seq<LinkOwner>) -> Seq<LinkModel>
131 decreases owners.len(),
132 {
133 if owners.len() == 0 {
134 Seq::<LinkModel>::empty()
135 } else {
136 seq![owners[0].view()].add(Self::view_helper(owners.remove(0)))
137 }
138 }
139
140 pub proof fn view_preserves_len(owners: Seq<LinkOwner>)
141 ensures
142 Self::view_helper(owners).len() == owners.len(),
143 decreases owners.len(),
144 {
145 if owners.len() == 0 {
146 } else {
147 Self::view_preserves_len(owners.remove(0))
148 }
149 }
150}
151
152impl<M: AnyFrameMeta + Repr<MetaSlot>> View for LinkedListOwner<M> {
153 type V = LinkedListModel;
154
155 open spec fn view(&self) -> Self::V {
156 LinkedListModel { list: Self::view_helper(self.list) }
157 }
158}
159
160impl<M: AnyFrameMeta + Repr<MetaSlot>> InvView for LinkedListOwner<M> {
161 proof fn view_preserves_inv(self) {
162 }
163}
164
165impl<M: AnyFrameMeta + Repr<MetaSlot>> LinkedListOwner<M> {
166 }
183
184impl<M: AnyFrameMeta + Repr<MetaSlot>> OwnerOf for LinkedList<M> {
185 type Owner = LinkedListOwner<M>;
186
187 open spec fn wf(self, owner: Self::Owner) -> bool {
188 &&& self.front is None <==> owner.list.len() == 0
189 &&& self.back is None <==> owner.list.len() == 0
190 &&& owner.list.len() > 0 ==> self.front is Some && self.front.unwrap().addr()
191 == owner.list[0].paddr && owner.perms[0].pptr() == self.front.unwrap()
192 && self.back is Some && self.back.unwrap().addr() == owner.list[owner.list.len()
193 - 1].paddr && owner.perms[owner.list.len() - 1].pptr() == self.back.unwrap()
194 &&& self.size == owner.list.len()
195 &&& self.list_id == owner.list_id
196 }
197}
198
199impl<M: AnyFrameMeta + Repr<MetaSlot>> ModelOf for LinkedList<M> {
200
201}
202
203#[rustc_has_incoherent_inherent_impls]
204pub ghost struct CursorModel {
205 pub ghost fore: Seq<LinkModel>,
206 pub ghost rear: Seq<LinkModel>,
207 pub ghost list_model: LinkedListModel,
208}
209
210impl Inv for CursorModel {
211 open spec fn inv(self) -> bool {
212 self.list_model.inv()
213 }
214}
215
216#[rustc_has_incoherent_inherent_impls]
217pub tracked struct CursorOwner<M: AnyFrameMeta + Repr<MetaSlot>> {
218 pub list_own: LinkedListOwner<M>,
219 pub list_perm: PointsTo<LinkedList<M>>,
220 pub index: int,
221}
222
223impl<M: AnyFrameMeta + Repr<MetaSlot>> Inv for CursorOwner<M> {
224 open spec fn inv(self) -> bool {
225 &&& 0 <= self.index <= self.length()
226 &&& self.list_own.inv()
227 }
228}
229
230impl<M: AnyFrameMeta + Repr<MetaSlot>> View for CursorOwner<M> {
231 type V = CursorModel;
232
233 open spec fn view(&self) -> Self::V {
234 let list = self.list_own.view();
235 CursorModel {
236 fore: list.list.take(self.index),
237 rear: list.list.skip(self.index),
238 list_model: list,
239 }
240 }
241}
242
243impl<M: AnyFrameMeta + Repr<MetaSlot>> InvView for CursorOwner<M> {
244 proof fn view_preserves_inv(self) {
245 }
246}
247
248impl<M: AnyFrameMeta + Repr<MetaSlot>> OwnerOf for CursorMut<M> {
249 type Owner = CursorOwner<M>;
250
251 open spec fn wf(self, owner: Self::Owner) -> bool {
252 &&& 0 <= owner.index < owner.length() ==> self.current.is_some()
253 && self.current.unwrap().addr() == owner.list_own.list[owner.index].paddr
254 && owner.list_own.perms[owner.index].pptr() == self.current.unwrap()
255 &&& owner.index == owner.list_own.list.len() ==> self.current.is_none()
256 &&& owner.list_perm.pptr() == self.list
257 &&& owner.list_perm.is_init()
258 &&& owner.list_perm.mem_contents().value().wf(owner.list_own)
259 }
260}
261
262impl<M: AnyFrameMeta + Repr<MetaSlot>> ModelOf for CursorMut<M> {
263
264}
265
266impl CursorModel {
267 pub open spec fn current(self) -> Option<LinkModel> {
268 if self.rear.len() > 0 {
269 Some(self.rear[0])
270 } else {
271 None
272 }
273 }
274}
275
276impl<M: AnyFrameMeta + Repr<MetaSlot>> CursorOwner<M> {
277 pub open spec fn length(self) -> int {
278 self.list_own.list.len() as int
279 }
280
281 pub open spec fn current(self) -> Option<LinkOwner> {
282 if 0 <= self.index < self.length() {
283 Some(self.list_own.list[self.index])
284 } else {
285 None
286 }
287 }
288
289 #[verifier::external_body]
290 pub fn list_insert(
291 Tracked(cursor): Tracked<&mut Self>,
292 Tracked(link): Tracked<&mut LinkOwner>,
293 Tracked(perm): Tracked<&vstd_extra::cast_ptr::PointsTo<MetaSlot, Link<M>>>,
294 )
295 ensures
296 cursor.list_own.list == old(cursor).list_own.list.insert(old(cursor).index, *old(link)),
297 cursor.list_own.list_id == old(cursor).list_own.list_id,
298 forall|idx: int| 0 <= idx < cursor.length() ==> cursor.list_own.perms.contains_key(idx),
299 forall|idx: int|
300 0 <= idx < cursor.index ==> cursor.list_own.perms[idx] == old(
301 cursor,
302 ).list_own.perms[idx],
303 forall|idx: int|
304 old(cursor).index < idx <= old(cursor).length() ==> cursor.list_own.perms[idx]
305 == old(cursor).list_own.perms[idx - 1],
306 cursor.list_own.perms[old(cursor).index] == perm,
307 cursor.index == old(cursor).index + 1,
308 cursor.list_perm == old(cursor).list_perm,
309 *link == *old(link),
310 {
311 unimplemented!()
312 }
313
314 pub open spec fn front_owner_spec(
315 list_own: LinkedListOwner<M>,
316 list_perm: PointsTo<LinkedList<M>>,
317 ) -> Self {
318 CursorOwner::<M> { list_own: list_own, list_perm: list_perm, index: 0 }
319 }
320
321 #[verifier::returns(proof)]
322 #[verifier::external_body]
323 pub proof fn front_owner(
324 list_own: LinkedListOwner<M>,
325 list_perm: PointsTo<LinkedList<M>>,
326 ) -> (res: Self)
327 ensures
328 res == Self::front_owner_spec(list_own, list_perm),
329 {
330 CursorOwner::<M> { list_own: list_own, list_perm: list_perm, index: 0 }
331 }
332
333 pub open spec fn back_owner_spec(
334 list_own: LinkedListOwner<M>,
335 list_perm: PointsTo<LinkedList<M>>,
336 ) -> Self {
337 CursorOwner::<M> {
338 list_own: list_own,
339 list_perm: list_perm,
340 index: if list_own.list.len() > 0 {
341 list_own.list.len() as int - 1
342 } else {
343 0
344 },
345 }
346 }
347
348 #[verifier::returns(proof)]
349 #[verifier::external_body]
350 pub proof fn back_owner(
351 list_own: LinkedListOwner<M>,
352 list_perm: PointsTo<LinkedList<M>>,
353 ) -> (res: Self)
354 ensures
355 res == Self::back_owner_spec(list_own, list_perm),
356 {
357 CursorOwner::<M> {
358 list_own: list_own,
359 list_perm: list_perm,
360 index: if list_own.list.len() > 0 {
361 list_own.list.len() as int - 1
362 } else {
363 0
364 },
365 }
366 }
367
368 pub open spec fn ghost_owner_spec(
369 list_own: LinkedListOwner<M>,
370 list_perm: PointsTo<LinkedList<M>>,
371 ) -> Self {
372 CursorOwner::<M> {
373 list_own: list_own,
374 list_perm: list_perm,
375 index: list_own.list.len() as int,
376 }
377 }
378
379 #[verifier::returns(proof)]
380 #[verifier::external_body]
381 pub proof fn ghost_owner(
382 list_own: LinkedListOwner<M>,
383 list_perm: PointsTo<LinkedList<M>>,
384 ) -> (res: Self)
385 ensures
386 res == Self::ghost_owner_spec(list_own, list_perm),
387 {
388 CursorOwner::<M> {
389 list_own: list_own,
390 list_perm: list_perm,
391 index: list_own.list.len() as int,
392 }
393 }
394}
395
396impl<M: AnyFrameMeta + Repr<MetaSlot>> UniqueFrameOwner<Link<M>> {
397 pub open spec fn frame_link_inv(&self) -> bool {
398 &&& self.meta_perm.value().prev is None
399 &&& self.meta_perm.value().next is None
400 &&& self.meta_own.paddr == self.meta_perm.addr()
401 }
402}
403
404}