Skip to content

Commit 3ca509e

Browse files
authored
[WIP] Merge rcu version (#193)
* Add `SpinGuardGhostInner` * Fix minor * Temp progress * Trivial merge
1 parent 1e5b8bf commit 3ca509e

34 files changed

Lines changed: 4249 additions & 304 deletions

File tree

lock-protocol/src/exec/mod.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
1-
mod rcu;
2-
mod rw;
1+
// mod rcu;
2+
// mod rw;
33
// mod test_map;
4-
54
use vstd::{invariant, prelude::*};
65
use core::num;
76
use std::collections::HashMap;

lock-protocol/src/exec/rcu/cpu.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use vstd::prelude::*;
22

33
use crate::spec::{common::*, utils::*, rcu::*};
4-
use super::{common::*, types::*};
4+
use super::common::*;
55

66
verus! {
77

lock-protocol/src/exec/rcu/cursor/locking.rs

Lines changed: 41 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use vstd_extra::ghost_tree::Node;
88
use vstd_extra::manually_drop::*;
99

1010
use crate::spec::{common::*, utils::*, rcu::*};
11-
use super::super::{common::*, types::*, cpu::*};
11+
use super::super::{common::*, cpu::*};
1212
use super::super::{frame::meta::*, page_table::*};
1313
use super::super::node::{
1414
PageTableNode, PageTableNodeRef, PageTableGuard,
@@ -167,8 +167,8 @@ pub(super) fn lock_range<'rcu>(
167167
subtree_root_opt->Some_0.wf(),
168168
subtree_root_opt->Some_0.inst().cpu_num() == GLOBAL_CPU_NUM,
169169
subtree_root_opt->Some_0.inst_id() == pt.inst@.id(),
170-
subtree_root_opt->Some_0.guard->Some_0.stray_perm@.value() == false,
171-
subtree_root_opt->Some_0.guard->Some_0.in_protocol@ == true,
170+
subtree_root_opt->Some_0.guard->Some_0.stray_perm().value() == false,
171+
subtree_root_opt->Some_0.guard->Some_0.in_protocol() == true,
172172
// TODO
173173
m.inv(),
174174
m.inst_id() == pt.inst@.id(),
@@ -216,9 +216,10 @@ pub(super) fn lock_range<'rcu>(
216216
)
217217
}
218218

219-
pub fn unlock_range(cursor: &mut Cursor<'_>, m: Tracked<LockProtocolModel>) -> (res: Tracked<
220-
LockProtocolModel,
221-
>)
219+
pub fn unlock_range(
220+
cursor: &mut Cursor<'_>,
221+
m: Tracked<LockProtocolModel>
222+
) -> (res: Tracked<LockProtocolModel>)
222223
requires
223224
old(cursor).wf(),
224225
m@.inv(),
@@ -314,8 +315,8 @@ fn try_traverse_and_lock_subtree_root<'rcu>(
314315
&&& res.0->Some_0.wf()
315316
&&& res.0->Some_0.inst().cpu_num() == GLOBAL_CPU_NUM
316317
&&& res.0->Some_0.inst_id() == pt.inst@.id()
317-
&&& res.0->Some_0.guard->Some_0.stray_perm@.value() == false
318-
&&& res.0->Some_0.guard->Some_0.in_protocol@ == true
318+
&&& res.0->Some_0.guard->Some_0.stray_perm().value() == false
319+
&&& res.0->Some_0.guard->Some_0.in_protocol() == true
319320
&&& res.1@.inv()
320321
&&& res.1@.inst_id() == pt.inst@.id()
321322
&&& res.1@.state() is Locking
@@ -346,7 +347,7 @@ fn try_traverse_and_lock_subtree_root<'rcu>(
346347
&&& cur_node_guard->Some_0.inst_id() == pt.inst@.id()
347348
&&& cur_node_guard->Some_0.nid() == cur_nid
348349
&&& cur_node_guard->Some_0.inner.deref().level_spec() == cur_level
349-
&&& cur_node_guard->Some_0.guard->Some_0.in_protocol@ == false
350+
&&& cur_node_guard->Some_0.guard->Some_0.in_protocol() == false
350351
},
351352
ensures
352353
1 <= cur_level <= MAX_NR_LEVELS,
@@ -360,7 +361,7 @@ fn try_traverse_and_lock_subtree_root<'rcu>(
360361
&&& cur_node_guard->Some_0.inst_id() == pt.inst@.id()
361362
&&& cur_node_guard->Some_0.nid() == cur_nid
362363
&&& cur_node_guard->Some_0.inner.deref().level_spec() == cur_level
363-
&&& cur_node_guard->Some_0.guard->Some_0.in_protocol@ == false
364+
&&& cur_node_guard->Some_0.guard->Some_0.in_protocol() == false
364365
},
365366
decreases cur_level,
366367
{
@@ -469,7 +470,7 @@ fn try_traverse_and_lock_subtree_root<'rcu>(
469470
m.token = new_token.1.get();
470471
}
471472
pt_guard.put_node_token(Tracked(new_node_token));
472-
pt_guard.update_in_protocol(Ghost(true));
473+
pt_guard.update_in_protocol(Tracked(true));
473474
}
474475
(Some(pt_guard), Tracked(m))
475476
}
@@ -487,26 +488,29 @@ fn dfs_acquire_lock(
487488
// cur_node_va: Vaddr,
488489
// va_range: Range<Vaddr>,
489490
m: Tracked<LockProtocolModel>,
490-
) -> (res: Tracked<LockProtocolModel>)
491+
forgot_guards: Tracked<SubTreeForgotGuard>,
492+
) -> (res: (Tracked<LockProtocolModel>, Tracked<SubTreeForgotGuard>))
491493
requires
492494
cur_node.wf(),
493-
cur_node.guard->Some_0.stray_perm@.value() == false,
494-
cur_node.guard->Some_0.in_protocol@ == true,
495+
cur_node.guard->Some_0.stray_perm().value() == false,
496+
cur_node.guard->Some_0.in_protocol() == true,
495497
m@.inv(),
496498
m@.inst_id() == cur_node.inst_id(),
497499
m@.state() is Locking,
498500
m@.cur_node() == cur_node.nid() + 1,
499501
m@.node_is_locked(cur_node.nid()),
500502
ensures
501-
res@.inv(),
502-
res@.inst_id() == cur_node.inst_id(),
503-
res@.state() is Locking,
504-
res@.sub_tree_rt() == m@.sub_tree_rt(),
505-
res@.cur_node() == NodeHelper::next_outside_subtree(cur_node.nid()),
503+
res.0@.inv(),
504+
res.0@.inst_id() == cur_node.inst_id(),
505+
res.0@.state() is Locking,
506+
res.0@.sub_tree_rt() == m@.sub_tree_rt(),
507+
res.0@.cur_node() == NodeHelper::next_outside_subtree(cur_node.nid()),
506508
decreases cur_node.deref().deref().level_spec(),
507509
{
508510
broadcast use crate::spec::utils::group_node_helper_lemmas;
509511

512+
let tracked mut forgot_guards = forgot_guards.get();
513+
510514
let cur_level = cur_node.deref().deref().level();
511515
if cur_level == 1 {
512516
assert(m@.cur_node() == NodeHelper::next_outside_subtree(cur_node.nid())) by {
@@ -531,8 +535,8 @@ fn dfs_acquire_lock(
531535
invariant
532536
0 <= i <= 512,
533537
cur_node.wf(),
534-
cur_node.guard->Some_0.stray_perm@.value() == false,
535-
cur_node.guard->Some_0.in_protocol@ == true,
538+
cur_node.guard->Some_0.stray_perm().value() == false,
539+
cur_node.guard->Some_0.in_protocol() == true,
536540
cur_node.deref().deref().level_spec() > 1,
537541
NodeHelper::is_not_leaf(cur_node.nid()),
538542
m.inv(),
@@ -560,7 +564,7 @@ fn dfs_acquire_lock(
560564
cur_node.tracked_borrow_guard().tracked_borrow_pte_token();
561565
assert(pa_pte_array_token.value().is_alive(entry.idx as nat));
562566
assert(pa_pte_array_token.value().get_paddr(entry.idx as nat)
563-
== cur_node.guard->Some_0.perms@.inner.value()[entry.idx as int].inner.paddr());
567+
== cur_node.guard->Some_0.perms().inner.value()[entry.idx as int].inner.paddr());
564568
assert(NodeHelper::in_subtree_range(m.sub_tree_rt(), pt.nid@)) by {
565569
assert(NodeHelper::in_subtree_range(m.sub_tree_rt(), cur_node.nid()));
566570
}
@@ -574,13 +578,19 @@ fn dfs_acquire_lock(
574578
// let va_start = va_range.start.max(child_node_va);
575579
// let va_end = va_range.end.min(child_node_va_end);
576580
// dfs_acquire_lock(guard, &mut pt_guard, child_node_va, va_start..va_end);
577-
assert(pt_guard.guard->Some_0.stray_perm@.value() == false);
581+
assert(pt_guard.guard->Some_0.stray_perm().value() == false);
578582
let res = dfs_acquire_lock(guard, &pt_guard, Tracked(m));
579583
proof {
580584
m = res.get();
581585
}
586+
// Forget the page table guard.
587+
assert(pt_guard.guard is Some);
588+
let tracked guard = pt_guard.guard.tracked_unwrap()
589+
let tracked forgot_guard = guard.inner.get();
590+
proof {
591+
forgot_guards.tracked_put(pt.nid@, forgot_guard);
592+
}
582593
let _ = ManuallyDrop::new(pt_guard);
583-
584594
},
585595
ChildRef::Frame(_, _, _) => unreached(),
586596
ChildRef::None => {
@@ -589,7 +599,7 @@ fn dfs_acquire_lock(
589599
proof {
590600
let ghost nid = NodeHelper::get_child(cur_node.nid(), i as nat);
591601
let tracked pte_token: &PteArrayToken =
592-
cur_node.guard.tracked_borrow().pte_token.borrow().tracked_borrow();
602+
cur_node.guard.tracked_borrow().tracked_borrow_pte_token();
593603
assert(pte_token.value().is_void(i as nat));
594604
assert(NodeHelper::in_subtree_range(m.sub_tree_rt(), nid)) by {
595605
NodeHelper::lemma_in_subtree_is_child_in_subtree(
@@ -660,7 +670,7 @@ fn dfs_acquire_lock(
660670
i += 1;
661671
}
662672

663-
Tracked(m)
673+
(Tracked(m), Tracked(forgot_guards))
664674
}
665675

666676
/// Releases the locks for the given range in the sub-tree rooted at the node.
@@ -679,8 +689,8 @@ fn dfs_release_lock<'rcu>(
679689
) -> (res: Tracked<LockProtocolModel>)
680690
requires
681691
cur_node.wf(),
682-
cur_node.guard->Some_0.stray_perm@.value() == false,
683-
cur_node.guard->Some_0.in_protocol@ == true,
692+
cur_node.guard->Some_0.stray_perm().value() == false,
693+
cur_node.guard->Some_0.in_protocol() == true,
684694
m@.inv(),
685695
m@.inst_id() == cur_node.inst_id(),
686696
m@.state() is Locking,
@@ -724,8 +734,8 @@ fn dfs_release_lock<'rcu>(
724734
invariant
725735
0 <= i <= 512,
726736
cur_node.wf(),
727-
cur_node.guard->Some_0.stray_perm@.value() == false,
728-
cur_node.guard->Some_0.in_protocol@ == true,
737+
cur_node.guard->Some_0.stray_perm().value() == false,
738+
cur_node.guard->Some_0.in_protocol() == true,
729739
m.inv(),
730740
m.inst_id() == cur_node.inst_id(),
731741
m.state() is Locking,
@@ -807,7 +817,7 @@ fn dfs_release_lock<'rcu>(
807817
proof {
808818
let ghost nid = NodeHelper::get_child(cur_node.nid(), i as nat);
809819
let tracked pte_token: &PteArrayToken =
810-
cur_node.guard.tracked_borrow().pte_token.borrow().tracked_borrow();
820+
cur_node.guard.tracked_borrow().tracked_borrow_pte_token();
811821
assert(m.cur_node() == NodeHelper::next_outside_subtree(nid)) by {
812822
if i + 1 < 512 {
813823
assert(m.cur_node() == NodeHelper::get_child(

lock-protocol/src/exec/rcu/cursor/mod.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,7 @@ use std::{marker::PhantomData, ops::Range};
55
use vstd::prelude::*;
66

77
use crate::spec::{common::*, utils::*, rcu::*};
8-
use super::{common::*, types::*, cpu::*};
9-
use super::page_table::PageTable;
8+
use super::{common::*, cpu::*};
109
use super::node::PageTableGuard;
1110
use crate::mm::page_table::cursor::MAX_NR_LEVELS;
1211
use crate::task::DisabledPreemptGuard;

lock-protocol/src/exec/rcu/node/entry.rs

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ impl<C: PageTableConfig> Entry<C> {
3232
pub open spec fn wf(&self, node: PageTableGuard<C>) -> bool {
3333
&&& self.pte.wf_with_node(*(node.deref().deref()), self.idx as nat)
3434
&&& 0 <= self.idx < 512
35-
&&& node.guard is Some ==> node.guard->Some_0.perms@.relate_pte(self.pte, self.idx as nat)
35+
&&& node.guard is Some ==> node.guard->Some_0.perms().relate_pte(self.pte, self.idx as nat)
3636
}
3737

3838
pub open spec fn nid(&self, node: PageTableGuard<C>) -> NodeId {
@@ -91,14 +91,14 @@ impl<C: PageTableConfig> Entry<C> {
9191
new_child.wf_with_node(old(self).idx as nat, *old(node)),
9292
!(new_child is PageTable),
9393
old(node).wf(),
94-
old(node).guard->Some_0.stray_perm@.value() == false,
94+
old(node).guard->Some_0.stray_perm().value() == false,
9595
ensures
9696
self.wf(*node),
9797
new_child.wf_into_pte(self.pte),
9898
self.idx == old(self).idx,
9999
if res is PageTable {
100100
&&& node.wf_except(self.idx as nat)
101-
&&& node.guard->Some_0.pte_token@->Some_0.value().is_alive(self.idx as nat)
101+
&&& node.guard->Some_0.view_pte_token().value().is_alive(self.idx as nat)
102102
} else {
103103
node.wf()
104104
},
@@ -128,24 +128,24 @@ impl<C: PageTableConfig> Entry<C> {
128128
old(self).wf(*old(node)),
129129
old(node).wf(),
130130
NodeHelper::is_not_leaf(old(node).nid()),
131-
old(node).guard->Some_0.stray_perm@.value() == false,
132-
old(node).guard->Some_0.in_protocol@ == false,
131+
old(node).guard->Some_0.stray_perm().value() == false,
132+
old(node).guard->Some_0.in_protocol() == false,
133133
ensures
134134
self.wf(*node),
135135
self.idx == old(self).idx,
136136
node.wf(),
137137
node.inst_id() == old(node).inst_id(),
138138
node.nid() == old(node).nid(),
139139
node.inner.deref().level_spec() == old(node).inner.deref().level_spec(),
140-
node.guard->Some_0.in_protocol == old(node).guard->Some_0.in_protocol,
140+
node.guard->Some_0.in_protocol() == old(node).guard->Some_0.in_protocol(),
141141
!(old(self).is_none() && old(node).inner.deref().level_spec() > 1) <==> res is None,
142142
res is Some ==> {
143143
&&& res->Some_0.wf()
144144
&&& res->Some_0.inst_id() == node.inst_id()
145145
&&& res->Some_0.nid() == NodeHelper::get_child(node.nid(), self.idx as nat)
146146
&&& res->Some_0.inner.deref().level_spec() + 1 == node.inner.deref().level_spec()
147-
&&& res->Some_0.guard->Some_0.stray_perm@.value() == false
148-
&&& res->Some_0.guard->Some_0.in_protocol@ == false
147+
&&& res->Some_0.guard->Some_0.stray_perm().value() == false
148+
&&& res->Some_0.guard->Some_0.in_protocol() == false
149149
},
150150
{
151151
broadcast use group_node_helper_lemmas;
@@ -156,8 +156,9 @@ impl<C: PageTableConfig> Entry<C> {
156156
let level = node.inner.deref().level();
157157
let ghost cur_nid = self.nid(*node);
158158
let mut lock_guard = node.guard.take().unwrap();
159-
let tracked node_token = lock_guard.node_token.get().tracked_unwrap();
160-
let tracked pte_token = lock_guard.pte_token.get().tracked_unwrap();
159+
let tracked mut lock_guard_inner = lock_guard.inner.get();
160+
let tracked node_token = lock_guard_inner.node_token.tracked_unwrap();
161+
let tracked pte_token = lock_guard_inner.pte_token.tracked_unwrap();
161162
assert(node_token.value() is LockedOutside);
162163
assert(pte_token.value().is_void(self.idx as nat));
163164
assert(cur_nid != NodeHelper::root_id()) by {
@@ -181,8 +182,11 @@ impl<C: PageTableConfig> Entry<C> {
181182
);
182183
let new_page = RcuDrop::new(res.0);
183184
let tracked pte_token = res.1.get();
184-
lock_guard.node_token = Tracked(Some(node_token));
185-
lock_guard.pte_token = Tracked(Some(pte_token));
185+
proof {
186+
lock_guard_inner.node_token = Some(node_token);
187+
lock_guard_inner.pte_token = Some(pte_token);
188+
}
189+
lock_guard.inner = Tracked(lock_guard_inner);
186190
node.guard = Some(lock_guard);
187191
let paddr = new_page.start_paddr();
188192

0 commit comments

Comments
 (0)