1use vstd::prelude::*;
7
8use vstd::atomic::PermissionU64;
9use vstd::seq_lib::*;
10use vstd::simple_pptr::*;
11
12use vstd_extra::cast_ptr::*;
13use vstd_extra::ownership::*;
14use vstd_extra::ptr_extra::*;
15
16use crate::mm::frame::meta::mapping::frame_to_meta;
17use crate::mm::frame::meta::REF_COUNT_UNUSED;
18use crate::mm::frame::UniqueFrame;
19use crate::mm::{Paddr, PagingLevel, Vaddr};
20use crate::specs::arch::mm::{MAX_NR_PAGES, MAX_PADDR, PAGE_SIZE};
21use crate::specs::mm::frame::linked_list::linked_list_owners::*;
22use crate::specs::mm::frame::meta_owners::{MetaSlotOwner, Metadata};
23use crate::specs::mm::frame::meta_region_owners::MetaRegionOwners;
24use crate::specs::mm::frame::unique::UniqueFrameOwner;
25
26use core::borrow::BorrowMut;
27use core::{
28 ops::{Deref, DerefMut},
29 ptr::NonNull,
30 sync::atomic::{AtomicU64, Ordering},
31};
32
33use crate::specs::*;
34
35use crate::mm::frame::meta::mapping::{frame_to_index, meta_addr, meta_to_frame};
36use crate::mm::frame::meta::{get_slot, has_safe_slot, AnyFrameMeta, MetaSlot};
37
38verus! {
39
40pub struct Link<M: AnyFrameMeta + Repr<MetaSlotSmall>> {
42 pub next: Option<ReprPtr<MetaSlot, MetadataAsLink<M>>>,
43 pub prev: Option<ReprPtr<MetaSlot, MetadataAsLink<M>>>,
44 pub meta: M,
45}
46
47pub struct LinkedList<M: AnyFrameMeta + Repr<MetaSlotSmall>> {
97 pub front: Option<ReprPtr<MetaSlot, MetadataAsLink<M>>>,
98 pub back: Option<ReprPtr<MetaSlot, MetadataAsLink<M>>>,
99 pub size: usize,
101 pub list_id: u64,
104}
105
106pub struct CursorMut<M: AnyFrameMeta + Repr<MetaSlotSmall>> {
111 pub list: PPtr<LinkedList<M>>,
112 pub current: Option<ReprPtr<MetaSlot, MetadataAsLink<M>>>,
113}
114
115impl<M: AnyFrameMeta + Repr<MetaSlotSmall>> LinkedList<M> {
116 pub const fn new() -> Self {
118 Self { front: None, back: None, size: 0, list_id: 0 }
119 }
120}
121
122impl<M: AnyFrameMeta + Repr<MetaSlotSmall>> Default for LinkedList<M> {
123 fn default() -> Self {
124 Self::new()
125 }
126}
127
128#[verus_verify]
133impl<M: AnyFrameMeta + Repr<MetaSlotSmall>> LinkedList<M> {
134 #[verus_spec(s =>
136 with
137 Tracked(owner): Tracked<LinkedListOwner<M>>,
138 requires
139 self.wf(owner),
140 owner.inv(),
141 ensures
142 s == self.model(owner).list.len(),
143 )]
144 pub fn size(&self) -> usize
145 {
146 proof {
147 LinkedListOwner::<M>::view_preserves_len(owner.list);
148 }
149 self.size
150 }
151
152 #[verus_spec(b =>
154 with
155 Tracked(owner): Tracked<LinkedListOwner<M>>,
156 requires
157 self.wf(owner),
158 owner.inv(),
159 ensures
160 b ==> self.size == 0 && self.front is None && self.back is None,
161 !b ==> self.size > 0 && self.front is Some && self.back is Some,
162 )]
163 pub fn is_empty(&self) -> bool
164 {
165 let is_empty = self.size == 0;
166 is_empty
167 }
168
169 #[verus_spec(
181 with
182 Tracked(regions): Tracked<&mut MetaRegionOwners>,
183 Tracked(owner): Tracked<&mut LinkedListOwner<M>>,
184 Tracked(perm): Tracked<vstd::simple_pptr::PointsTo<LinkedList<M>>>,
185 Tracked(frame_own): Tracked<&mut UniqueFrameOwner<Link<M>>>,
186 requires
187 perm.pptr() == ptr,
188 perm.is_init(),
189 perm.mem_contents().value().wf(*old(owner)),
190 old(owner).inv(),
191 old(owner).list_id != 0,
192 old(frame_own).inv(),
193 old(frame_own).global_inv(*old(regions)),
194 frame.wf(*old(frame_own)),
195 old(frame_own).frame_link_inv(),
196 old(owner).list.len() < usize::MAX,
197 old(regions).inv(),
198 old(regions).slots.contains_key(old(frame_own).slot_index),
199 old(regions).slot_owners[old(frame_own).slot_index].inner_perms.in_list.is_for(
200 old(regions).slots[old(frame_own).slot_index].value().in_list,
201 ),
202 ensures
203 owner.inv(),
204 owner.list == old(owner).list.insert(0, frame_own.meta_own),
205 owner.list_id == old(owner).list_id,
206 frame_own.meta_own.paddr == old(frame_own).meta_own.paddr,
207 frame_own.meta_own.in_list == old(owner).list_id,
208 )]
209 pub fn push_front(ptr: PPtr<Self>, frame: UniqueFrame<Link<M>>) {
210 let ll = ptr.borrow(Tracked(&perm));
211 let current = ll.front;
212 let tracked mut cursor_own = CursorOwner::front_owner(*owner, perm);
213 let mut cursor = CursorMut { list: ptr, current };
214
215 #[verus_spec(with Tracked(regions), Tracked(&mut cursor_own), Tracked(frame_own))]
216 cursor.insert_before(frame);
217
218 proof {
219 *owner = cursor_own.list_own;
220 }
221 }
222
223 #[verus_spec(r =>
235 with
236 Tracked(regions): Tracked<&mut MetaRegionOwners>,
237 Tracked(perm): Tracked<vstd::simple_pptr::PointsTo<LinkedList<M>>>,
238 Tracked(owner): Tracked<LinkedListOwner<M>>,
239 Tracked(frame_own): Tracked<UniqueFrameOwner<Link<M>>>,
240 requires
241 old(regions).inv(),
242 perm.pptr() == ptr,
243 perm.is_init(),
244 perm.value().wf(owner),
245 owner.inv(),
246 old(regions).slots.contains_key(frame_to_index(owner.list[0].paddr)),
247 ensures
248 owner.list.len() == 0 ==> r.is_none(),
249 r.is_some() ==> r.unwrap().0.model(r.unwrap().1@).meta == owner.list[0]@,
250 r.is_some() ==> r.unwrap().1@.frame_link_inv(),
251 )]
252 pub fn pop_front(ptr: PPtr<Self>) -> Option<(UniqueFrame<Link<M>>, Tracked<UniqueFrameOwner<Link<M>>>)> {
253 assert(owner.list.len() > 0 ==> owner.inv_at(0));
254
255 proof_with!(Tracked(owner), Tracked(perm) => Tracked(cursor_own));
256 let cursor = Self::cursor_front_mut(ptr);
257 let mut cursor = cursor;
258 let tracked mut cursor_own = cursor_own;
259
260 #[verus_spec(with Tracked(regions), Tracked(&mut cursor_own))]
261 cursor.take_current()
262 }
263
264 #[verus_spec(
276 with
277 Tracked(regions): Tracked<&mut MetaRegionOwners>,
278 Tracked(owner): Tracked<&mut LinkedListOwner<M>>,
279 Tracked(perm): Tracked<vstd::simple_pptr::PointsTo<LinkedList<M>>>,
280 Tracked(frame_own): Tracked<&mut UniqueFrameOwner<Link<M>>>,
281 requires
282 perm.pptr() == ptr,
283 perm.is_init(),
284 perm.mem_contents().value().wf(*old(owner)),
285 old(owner).inv(),
286 old(owner).list_id != 0,
287 old(frame_own).inv(),
288 old(frame_own).global_inv(*old(regions)),
289 frame.wf(*old(frame_own)),
290 old(frame_own).frame_link_inv(),
291 old(owner).list.len() < usize::MAX,
292 old(regions).inv(),
293 old(regions).slots.contains_key(old(frame_own).slot_index),
294 old(regions).slot_owners[old(frame_own).slot_index].inner_perms.in_list.is_for(
295 old(regions).slots[old(frame_own).slot_index].value().in_list,
296 ),
297 ensures
298 owner.inv(),
299 old(owner).list.len() > 0 ==> owner.list == old(owner).list.insert(
300 old(owner).list.len() as int - 1, frame_own.meta_own),
301 old(owner).list.len() == 0 ==> owner.list == old(owner).list.insert(
302 0, frame_own.meta_own),
303 owner.list_id == old(owner).list_id,
304 frame_own.meta_own.paddr == old(frame_own).meta_own.paddr,
305 frame_own.meta_own.in_list == old(owner).list_id,
306 )]
307 pub fn push_back(ptr: PPtr<Self>, frame: UniqueFrame<Link<M>>) {
308 let ll = ptr.borrow(Tracked(&perm));
309 let current = ll.back;
310 let tracked mut cursor_own = CursorOwner::back_owner(*owner, perm);
311 let mut cursor = CursorMut { list: ptr, current };
312
313 #[verus_spec(with Tracked(regions), Tracked(&mut cursor_own), Tracked(frame_own))]
314 cursor.insert_before(frame);
315
316 proof {
317 *owner = cursor_own.list_own;
318 }
319 }
320
321 #[verus_spec(r =>
334 with
335 Tracked(regions): Tracked<&mut MetaRegionOwners>,
336 Tracked(perm): Tracked<vstd::simple_pptr::PointsTo<LinkedList<M>>>,
337 Tracked(owner): Tracked<LinkedListOwner<M>>,
338 Tracked(frame_own): Tracked<UniqueFrameOwner<Link<M>>>,
339 requires
340 old(regions).inv(),
341 perm.pptr() == ptr,
342 perm.is_init(),
343 perm.mem_contents().value().wf(owner),
344 owner.inv(),
345 old(regions).slots.contains_key(frame_to_index(owner.list[owner.list.len() - 1].paddr)),
346 ensures
347 owner.list.len() == 0 ==> r.is_none(),
348 r.is_some() ==> r.unwrap().0.model(r.unwrap().1@).meta == owner.list[owner.list.len() - 1]@,
349 r.is_some() ==> r.unwrap().1@.frame_link_inv(),
350 )]
351 pub fn pop_back(ptr: PPtr<Self>) -> Option<(UniqueFrame<Link<M>>, Tracked<UniqueFrameOwner<Link<M>>>)> {
352 assert(owner.list.len() > 0 ==> owner.inv_at(owner.list.len() - 1));
353
354 #[verus_spec(with Tracked(owner), Tracked(perm))]
355 let (cursor, cursor_own) = Self::cursor_back_mut(ptr);
356 let mut cursor = cursor;
357 let mut cursor_own = cursor_own;
358
359 #[verus_spec(with Tracked(regions), Tracked(cursor_own.borrow_mut()))]
360 cursor.take_current()
361 }
362
363 #[verus_spec(r =>
377 with
378 Tracked(regions): Tracked<&mut MetaRegionOwners>,
379 Tracked(slot_own): Tracked<&MetaSlotOwner>,
380 Tracked(owner): Tracked<&mut LinkedListOwner<M>>,
381 requires
382 slot_own.inv(),
383 old(regions).inv(),
384 old(regions).slots.contains_key(frame_to_index(frame)),
385 old(regions).slots[frame_to_index(frame)].is_init(),
386 old(regions).slot_owners.contains_key(frame_to_index(frame)),
387 old(regions).slot_owners[frame_to_index(frame)].inner_perms.in_list.is_for(
388 old(regions).slots[frame_to_index(frame)].mem_contents().value().in_list,
389 ),
390 ensures
391 old(owner).list_id != 0 ==> *owner == *old(owner),
392 )]
393 pub fn contains(ptr: PPtr<Self>, frame: Paddr) -> bool {
394 let Ok(slot_ptr) = get_slot(frame) else {
395 return false;
396 };
397
398 let tracked mut slot_perm = regions.slots.tracked_remove(frame_to_index(frame));
399 let tracked mut slot_own = regions.slot_owners.tracked_remove(frame_to_index(frame));
400
401 let slot = slot_ptr.take(Tracked(&mut slot_perm));
402
403 let tracked mut inner_perms = slot_own.take_inner_perms();
404
405 let in_list = slot.in_list.load(Tracked(&mut inner_perms.in_list));
406 slot_ptr.put(Tracked(&mut slot_perm), slot);
407
408 proof {
409 slot_own.sync_inner(&inner_perms);
410 regions.slot_owners.tracked_insert(frame_to_index(frame), slot_own);
411 regions.slots.tracked_insert(frame_to_index(frame), slot_perm);
412 }
413
414 in_list == #[verus_spec(with Tracked(owner))]
415 Self::lazy_get_id(ptr)
416 }
417
418 #[verus_spec(r =>
436 with
437 Tracked(regions): Tracked<&mut MetaRegionOwners>,
438 Tracked(owner): Tracked<LinkedListOwner<M>>,
439 Tracked(perm): Tracked<vstd::simple_pptr::PointsTo<LinkedList<M>>>,
440 -> cursor_owner: Tracked<Option<CursorOwner<M>>>,
441 requires
442 old(regions).inv(),
443 ensures
444!has_safe_slot(frame) ==> r is None,
446 )]
447 #[verifier::external_body]
448 pub fn cursor_mut_at(ptr: PPtr<Self>, frame: Paddr) -> Option<CursorMut<M>>
449 {
450 let tracked mut slot_own = regions.slot_owners.tracked_remove(frame_to_index(frame));
451 let tracked mut inner_perms = slot_own.take_inner_perms();
452
453 if let Ok(slot_ptr) = get_slot(frame) {
454 let slot = slot_ptr.borrow(Tracked(®ions.slots[frame_to_index(frame)]));
455
456 let in_list = slot.in_list.load(Tracked(&mut inner_perms.in_list));
457
458 let contains = in_list == #[verus_spec(with Tracked(&owner))]
459 Self::lazy_get_id(ptr);
460
461 #[verus_spec(with Tracked(®ions.slots[frame_to_index(frame)]))]
462 let meta_ptr = slot.as_meta_ptr::<Link<M>>();
463
464 if contains {
465 proof {
466 slot_own.sync_inner(&inner_perms);
467 regions.slot_owners.tracked_insert(frame_to_index(frame), slot_own);
468 }
469
470 let ghost link = owner.list.filter(|link: LinkOwner| link.paddr == frame).first();
471 let ghost index = owner.list.index_of(link);
472 let tracked cursor_owner = CursorOwner::cursor_mut_at_owner(owner, perm, index);
473
474 proof_with!(|= Tracked(Some(cursor_owner)));
475 Some(CursorMut { list: ptr, current: Some(MetadataAsLink::cast_from_metadata(meta_ptr)) })
476 } else {
477 proof {
478 slot_own.sync_inner(&inner_perms);
479 regions.slot_owners.tracked_insert(frame_to_index(frame), slot_own);
480 }
481
482 proof_with!(|= Tracked(None));
483 None
484 }
485 } else {
486 assert(!has_safe_slot(frame));
487 proof_with!(|= Tracked(None));
488 None
489 }
490 }
491
492 #[verus_spec(r =>
507 with
508 Tracked(owner): Tracked<LinkedListOwner<M>>,
509 Tracked(perm): Tracked<vstd::simple_pptr::PointsTo<LinkedList<M>>>,
510 -> r_perm: Tracked<CursorOwner<M>>,
511 requires
512 perm.pptr() == ptr,
513 perm.is_init(),
514 perm.mem_contents().value().wf(owner),
515 owner.inv(),
516 ensures
517 r.wf(r_perm@),
518 r_perm@.inv(),
519 r_perm@ == CursorOwner::front_owner_spec(owner, perm),
520 )]
521 pub fn cursor_front_mut(ptr: PPtr<Self>) -> CursorMut<M> {
522 let ll = ptr.borrow(Tracked(&perm));
523 let current = ll.front;
524
525 proof_with!(|= Tracked(CursorOwner::front_owner(owner, perm)));
526 CursorMut { list: ptr, current }
527 }
528
529 #[verus_spec(
544 with
545 Tracked(owner): Tracked<LinkedListOwner<M>>,
546 Tracked(perm): Tracked<vstd::simple_pptr::PointsTo<LinkedList<M>>>
547 )]
548 pub fn cursor_back_mut(ptr: PPtr<Self>) -> (res: (CursorMut<M>, Tracked<CursorOwner<M>>))
549 requires
550 perm.pptr() == ptr,
551 perm.is_init(),
552 perm.mem_contents().value().wf(owner),
553 owner.inv(),
554 ensures
555 res.0.wf(res.1@),
556 res.1@.inv(),
557 res.1@ == CursorOwner::back_owner_spec(owner, perm),
558 {
559 let ll = ptr.borrow(Tracked(&perm));
560 let current = ll.back;
561
562 (CursorMut { list: ptr, current }, Tracked(CursorOwner::back_owner(owner, perm)))
563 }
564
565 #[verus_spec(
567 with Tracked(owner): Tracked<&mut LinkedListOwner<M>>
568 )]
569 fn cursor_at_ghost_mut(ptr: PPtr<Self>) -> CursorMut<M> {
570 CursorMut { list: ptr, current: None }
571 }
572
573 #[verifier::external_body]
577 #[verus_spec(
578 with Tracked(owner): Tracked<& LinkedListOwner<M>>
579 )]
580 fn lazy_get_id(ptr: PPtr<Self>) -> (id: u64)
581 ensures
582 owner.list_id != 0 ==> id == owner.list_id,
583 {
584 unimplemented!()}
603}
604
605impl<M: AnyFrameMeta + Repr<MetaSlotSmall>> CursorMut<M> {
606 #[verus_spec(
613 with Tracked(owner): Tracked<CursorOwner<M>>
614 )]
615 pub fn move_next(&mut self)
616 requires
617 owner.inv(),
618 old(self).wf(owner),
619 ensures
620 self.model(owner.move_next_owner_spec()) == old(self).model(owner).move_next_spec(),
621 owner.move_next_owner_spec().inv(),
622 self.wf(owner.move_next_owner_spec()),
623 {
624 let ghost old_self = *self;
625
626 proof {
627 if self.current is Some {
628 assert(owner.list_own.inv_at(owner.index));
629 }
630 if owner.index < owner.length() - 1 {
631 assert(owner.list_own.inv_at(owner.index + 1));
632 owner.list_own.perms[owner.index + 1].pptr_implies_addr();
633 }
634 }
635
636 self.current = match self.current {
637 Some(current) => {
639 let current_md = MetadataAsLink::cast_to_metadata(current);
640 borrow_field!(current_md => metadata.next, owner.list_own.perms.tracked_borrow(owner.index))
641 },
642 None => borrow_field!(self.list => front, &owner.list_perm),
643 };
644
645 proof {
646 LinkedListOwner::<M>::view_preserves_len(owner.list_own.list);
647 assert(self.model(owner.move_next_owner_spec()).fore == old_self.model(owner).move_next_spec().fore);
648 assert(self.model(owner.move_next_owner_spec()).rear == old_self.model(owner).move_next_spec().rear);
649 }
650 }
651
652 #[verus_spec(
659 with Tracked(owner): Tracked<CursorOwner<M>>
660 )]
661 pub fn move_prev(&mut self)
662 requires
663 owner.inv(),
664 old(self).wf(owner),
665 ensures
666 self.model(owner.move_prev_owner_spec()) == old(self).model(owner).move_prev_spec(),
667 owner.move_prev_owner_spec().inv(),
668 self.wf(owner.move_prev_owner_spec()),
669 {
670 let ghost old_self = *self;
671
672 proof {
673 if self.current is Some {
674 assert(owner.list_own.inv_at(owner.index));
675 }
676 if 0 < owner.index {
677 assert(owner.list_own.inv_at(owner.index - 1));
678 owner.list_own.perms[owner.index - 1].pptr_implies_addr();
679 }
680 }
681
682 self.current = match self.current {
683 Some(current) => {
685 let current_md = MetadataAsLink::cast_to_metadata(current);
686 borrow_field!(current_md => metadata.prev, owner.list_own.perms.tracked_borrow(owner.index))
687 },
688 None => borrow_field!(self.list => back, &owner.list_perm),
689 };
690
691 proof {
692 LinkedListOwner::<M>::view_preserves_len(owner.list_own.list);
693
694 if owner@.list_model.list.len() > 0 {
695 if owner@.fore.len() > 0 {
696 assert(self.model(owner.move_prev_owner_spec()).fore == old_self.model(
697 owner,
698 ).move_prev_spec().fore);
699 assert(self.model(owner.move_prev_owner_spec()).rear == old_self.model(
700 owner,
701 ).move_prev_spec().rear);
702 if owner@.rear.len() > 0 {
703 assert(owner.list_own.inv_at(owner.index));
704 }
705 } else {
706 assert(owner.list_own.inv_at(owner.index));
707 assert(self.model(owner.move_prev_owner_spec()).rear == old_self.model(
708 owner,
709 ).move_prev_spec().rear);
710 assert(owner@.rear == owner@.list_model.list);
711 }
712 }
713 }
714 }
715
716 #[verus_spec(
749 with Tracked(regions) : Tracked<&mut MetaRegionOwners>,
750 Tracked(owner) : Tracked<&mut CursorOwner<M>>
751 )]
752 pub fn take_current(&mut self) -> (res: Option<(UniqueFrame<Link<M>>, Tracked<UniqueFrameOwner<Link<M>>>)>)
753 requires
754 old(self).wf(*old(owner)),
755 old(owner).inv(),
756 old(regions).inv(),
757 old(owner).length() > 0 ==> old(regions).slot_owners.contains_key(
758 frame_to_index(old(self).current.unwrap().addr()),
759 ),
760 ensures
761 old(owner).length() == 0 ==> res.is_none(),
762 res.is_some() ==> res.unwrap().0.model(res.unwrap().1@).meta == old(
763 owner,
764 ).list_own.list[old(owner).index]@,
765 res.is_some() ==> self.model(*owner) == old(self).model(*old(owner)).remove(),
766 res.is_some() ==> res.unwrap().1@.frame_link_inv(),
767 {
768 let ghost owner0 = *owner;
769
770 let current = self.current?;
771
772 assert(owner.list_own.inv_at(owner.index));
773 assert(owner.index > 0 ==> owner.list_own.inv_at(owner.index - 1));
774 assert(owner.index < owner.length() - 1 ==> owner.list_own.inv_at(owner.index + 1));
775
776 let meta_ptr = current.addr();
777 let paddr = meta_to_frame(meta_ptr);
778
779 let tracked cur_perm = owner.list_own.perms.tracked_remove(owner.index);
780 let tracked mut cur_own = owner.list_own.list.tracked_remove(owner.index);
781
782 #[verus_spec(with Tracked(regions), Tracked(cur_perm), Tracked(cur_own))]
783 let (frame, frame_own) = UniqueFrame::<Link<M>>::from_raw(paddr);
784 let mut frame = frame;
785 let tracked mut frame_own = frame_own.get();
786
787 let next_ptr = frame.meta().next;
788
789 #[verus_spec(with Tracked(&frame_own))]
790 let frame_meta = frame.meta_mut();
791
792 let opt_prev_link = borrow_field!(frame_meta => metadata.prev, &frame_own.meta_perm);
793
794 if let Some(prev_link) = opt_prev_link {
795 let prev = MetadataAsLink::cast_to_metadata(prev_link);
796 update_field!(prev => metadata.next <- next_ptr; owner.list_own.perms, owner.index-1);
799
800 assert(owner.index > 0);
801 } else {
802 update_field!(self.list => front <- next_ptr; owner.list_perm);
803 }
804
805 let prev_ptr = frame.meta().prev;
806
807 #[verus_spec(with Tracked(&frame_own))]
808 let frame_meta = frame.meta_mut();
809 let opt_next_link = frame_meta.borrow(Tracked(&frame_own.meta_perm)).metadata.next;
810
811 if let Some(next_link) = opt_next_link {
812 let next = MetadataAsLink::cast_to_metadata(next_link);
813 update_field!(next => metadata.prev <- prev_ptr; owner.list_own.perms, owner.index+1);
816
817 self.current = Some(next_link);
818 } else {
819 update_field!(self.list => back <- prev_ptr; owner.list_perm);
820
821 self.current = None;
822 }
823
824 #[verus_spec(with Tracked(&frame_own))]
825 let frame_meta = frame.meta_mut();
826
827 update_field!(frame_meta => metadata.next <- None; frame_own.meta_perm);
828 update_field!(frame_meta => metadata.prev <- None; frame_own.meta_perm);
829
830 let tracked mut slot_own = regions.slot_owners.tracked_remove(frame_to_index(paddr));
831
832 #[verus_spec(with Tracked(&frame_own.meta_perm.points_to))]
833 let slot = frame.slot();
834 let tracked mut inner_perms = frame_own.meta_perm.inner_perms;
835 slot.in_list.store(Tracked(&mut inner_perms.in_list), 0);
836 proof { frame_own.meta_perm.inner_perms = inner_perms; }
837
838 proof {
839 regions.slot_owners.tracked_insert(frame_to_index(paddr), slot_own);
840 }
841
842 update_field!(self.list => size -= 1; owner.list_perm);
843
844 proof {
845 owner0.remove_owner_spec_implies_model_spec(*owner);
846 }
847 Some((frame, Tracked(frame_own)))
848 }
849
850 #[verus_spec(
867 with Tracked(regions): Tracked<&mut MetaRegionOwners>,
868 Tracked(owner): Tracked<&mut CursorOwner<M>>,
869 Tracked(frame_own): Tracked<&mut UniqueFrameOwner<Link<M>>>
870 )]
871 pub fn insert_before(&mut self, mut frame: UniqueFrame<Link<M>>)
872 requires
873 old(self).wf(*old(owner)),
874 old(owner).inv(),
875 old(owner).list_own.list_id != 0,
876 old(frame_own).inv(),
877 old(frame_own).global_inv(*old(regions)),
878 frame.wf(*old(frame_own)),
879 old(owner).length() < usize::MAX,
880 old(regions).inv(),
881 old(regions).slots.contains_key(old(frame_own).slot_index),
882 old(regions).slot_owners[old(frame_own).slot_index].inner_perms.in_list.is_for(
883 old(regions).slots[old(frame_own).slot_index].value().in_list,
884 ),
885 old(frame_own).meta_perm.addr() == frame.ptr.addr(),
886 old(frame_own).frame_link_inv(),
887 ensures
888 self.model(*owner) == old(self).model(*old(owner)).insert(frame_own.meta_own@),
889 self.wf(*owner),
890 owner.inv(),
891 owner.list_own.list == old(owner).list_own.list.insert(old(owner).index, frame_own.meta_own),
892 owner.list_own.list_id == old(owner).list_own.list_id,
893 frame_own.meta_own.paddr == old(frame_own).meta_own.paddr,
894 frame_own.meta_own.in_list == old(owner).list_own.list_id,
895 {
896 let ghost owner0 = *owner;
897
898 assert(meta_addr(frame_own.slot_index) == frame.ptr.addr());
899 assert(regions.slot_owners.contains_key(frame_own.slot_index));
900 let tracked slot_own = regions.slot_owners.tracked_borrow(frame_own.slot_index);
901
902 #[verus_spec(with Tracked(frame_own))]
903 let frame_ptr = frame.meta_mut();
904 assert(frame_ptr.addr() == frame.ptr.addr());
905
906 let frame_ptr_as_link = MetadataAsLink::cast_from_metadata(frame_ptr);
907
908 if let Some(current) = self.current {
909 let current_md = MetadataAsLink::cast_to_metadata(current);
910
911 assert(owner.list_own.inv_at(owner.index));
912 assert(owner.index > 0 ==> owner.list_own.inv_at(owner.index - 1));
913 assert(owner.index < owner.length() - 1 ==> owner.list_own.inv_at(owner.index + 1));
914
915 let tracked mut cur_perm = owner.list_own.perms.tracked_remove(owner.index);
917 let opt_prev_link : Option<ReprPtr<MetaSlot, MetadataAsLink<M>>> =
918 borrow_field!(current_md => metadata.prev, &cur_perm);
919 proof {
920 owner.list_own.perms.tracked_insert(owner.index, cur_perm);
921 }
922
923 if let Some(prev_link) = opt_prev_link {
924 let prev = MetadataAsLink::cast_to_metadata(prev_link);
925
926 update_field!(prev => metadata.next <- Some(frame_ptr_as_link); owner.list_own.perms, owner.index-1);
928
929 update_field!(frame_ptr => metadata.prev <- Some(prev_link); frame_own.meta_perm);
930 update_field!(frame_ptr => metadata.next <- Some(current); frame_own.meta_perm);
931
932 update_field!(current_md => metadata.prev <- Some(frame_ptr_as_link); owner.list_own.perms, owner.index);
933 } else {
934 update_field!(frame_ptr => metadata.next <- Some(current); frame_own.meta_perm);
935
936 update_field!(current_md => metadata.prev <- Some(frame_ptr_as_link); owner.list_own.perms, owner.index);
937
938 update_field!(self.list => front <- Some(frame_ptr_as_link); owner.list_perm);
939 }
940 } else {
941 assert(0 < owner.length() ==> owner.list_own.inv_at(owner.index - 1));
942
943 if let Some(back) = borrow_field!(self.list => back, &owner.list_perm) {
944 let back_md = MetadataAsLink::cast_to_metadata(back);
945
946 assert(owner.index == owner.length());
947
948 update_field!(back_md => metadata.next <- Some(frame_ptr_as_link); owner.list_own.perms, owner.length()-1);
951
952 update_field!(frame_ptr => metadata.prev <- Some(back); frame_own.meta_perm);
953
954 update_field!(self.list => back <- Some(frame_ptr_as_link); owner.list_perm);
955 } else {
956 update_field!(self.list => front <- Some(frame_ptr_as_link); owner.list_perm);
958 update_field!(self.list => back <- Some(frame_ptr_as_link); owner.list_perm);
959 }
960 }
961
962 assert(regions.slot_owners.contains_key(frame_to_index(meta_to_frame(frame.ptr.addr()))));
963 let tracked mut slot_own = regions.slot_owners.tracked_remove(
964 frame_to_index(meta_to_frame(frame.ptr.addr())),
965 );
966
967 #[verus_spec(with Tracked(&mut owner.list_own))]
968 let list_id = LinkedList::<M>::lazy_get_id(self.list);
969
970 let tracked mut inner_perms;
971 proof {
972 inner_perms = frame_own.meta_perm.take_inner_perms();
973 }
974 #[verus_spec(with Tracked(&frame_own.meta_perm.points_to))]
975 let slot = frame.slot();
976 slot.in_list.store(Tracked(&mut inner_perms.in_list), list_id);
977 proof { frame_own.meta_perm.put_inner_perms(inner_perms); }
978
979 proof {
980 assert(frame_own.slot_index == frame_to_index(meta_to_frame(frame.ptr.addr())));
984 assert(slot_own.inner_perms.ref_count.value() != REF_COUNT_UNUSED);
985 assert(slot_own.inner_perms.ref_count.value() != 0);
986 assert(slot_own.inv());
987
988 regions.slot_owners.tracked_insert(frame_to_index(meta_to_frame(frame.ptr.addr())), slot_own)
989 }
990
991 assert(regions.inv()) by {
992 assert(forall|i: usize| #[trigger]
996 regions.slots.contains_key(i) ==>
997 regions.slots[i].value().wf(regions.slot_owners[i]));
998 };
999
1000 #[verus_spec(with Tracked(frame_own), Tracked(regions))]
1002 let _ = frame.into_raw();
1003
1004 update_field!(self.list => size += 1; owner.list_perm);
1005
1006 proof {
1007 CursorOwner::<M>::list_insert(owner, &mut frame_own.meta_own, &frame_own.meta_perm);
1008
1009 assert(forall|i: int| 0 <= i < owner.index - 1 ==> owner0.list_own.inv_at(i) ==> owner.list_own.inv_at(i)) by {};
1010 assert(forall|i: int| owner.index <= i < owner.length() ==> owner0.list_own.inv_at(i - 1) == owner.list_own.inv_at(i)) by {};
1011 assert(owner.list_own.inv_at(owner0.index as int));
1012
1013 assert(owner.list_own.list == owner0.list_own.list.insert(owner0.index, frame_own.meta_own));
1014 owner0.insert_owner_spec_implies_model_spec(frame_own.meta_own, *owner);
1015 }
1016 }
1017
1018 pub fn as_list(&self) -> PPtr<LinkedList<M>> {
1020 self.list
1021 }
1022}
1023
1024impl<M: AnyFrameMeta + Repr<MetaSlotSmall>> Link<M> {
1054 pub const fn new(meta: M) -> Self {
1056 Self { next: None, prev: None, meta }
1057 }
1058}
1059
1060}