Skip to content

Commit 1cf1c54

Browse files
authored
Update exclusive logical resource library (#351)
* Rename ExclusiveGhost * Simplifies ExclusiveGhost definition and add doc * Remove confusing `UniqueTokenStorage` and use `Option<UniqueToken>` in `RwLock`` * Add wf in csum postconditions * Add `Excl`
1 parent c09a819 commit 1cf1c54

7 files changed

Lines changed: 404 additions & 259 deletions

File tree

ostd/src/sync/rwlock.rs

Lines changed: 44 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -94,9 +94,9 @@ tracked struct RwPerms<T> {
9494
read_retract_token: ReadRetractToken,
9595
/// The permission to retract the set of `UPGRADEABLE_READER` bit, it can be spilit at two pieces,
9696
/// which allows at most 1 failing `try_upread` to subtract the `UPGRADEABLE_READER` bit, and 1 reserved in the lock atomic.
97-
upread_retract_token: UniqueTokenStorage,
97+
upread_retract_token: Option<UniqueToken>,
9898
/// Tracks whether there is a live `RwLockUpgradeableGuard`.
99-
upreader_guard_token: UniqueTokenStorage,
99+
upreader_guard_token: Option<UniqueToken>,
100100
/// Tracks the number of live `RwLockReadGuard`s.
101101
read_guard_token: TokenStorage<V_MAX_READ_GUARDS>,
102102
}
@@ -238,11 +238,11 @@ closed spec fn wf(self) -> bool {
238238
// The number of active readers, including both `RwLockReadGuard`s and `RwLockUpgradeableGuard`s.
239239
let total_active_readers: int = if !active_writer { (V_MAX_PERM_FRACS as int) - remaining_pcell_perms } else { 0 };
240240
// The number of active `RwLockUpgradeableGuard`, which can only be 0 or 1.
241-
let active_upgrade_guard: bool = g.upreader_guard_token.is_empty();
241+
let active_upgrade_guard: bool = g.upreader_guard_token is None;
242242
// The number of active `RwLockReadGuard`s.
243243
let active_read_guards: int = V_MAX_READ_GUARDS - g.read_guard_token.frac();
244244
// The first `try_upread` that fails, which has not returned yet.
245-
let pending_failed_upread_attempt: bool = g.upread_retract_token.is_empty();
245+
let pending_failed_upread_attempt: bool = g.upread_retract_token is None;
246246
// The number of `try_read` attempts that will fail.
247247
let failed_reader_attempts: int = V_MAX_READ_RETRACT_FRACS - g.read_retract_token.frac();
248248

@@ -262,8 +262,6 @@ closed spec fn wf(self) -> bool {
262262
&&& !(active_writer && total_active_readers > 0)
263263
&&& g.read_retract_token.wf()
264264
&&& g.cell_perm_resource.wf()
265-
&&& g.upread_retract_token.wf()
266-
&&& g.upreader_guard_token.wf()
267265
&&& g.read_guard_token.wf()
268266
&&& g.cell_perm_resource.is_resource_owner()
269267
&&& g.cell_perm_resource.has_resource()
@@ -278,8 +276,8 @@ closed spec fn wf(self) -> bool {
278276
&&& empty.id() == v_id@.frac_id
279277
&&& g.cell_perm_resource.frac() == V_MAX_PERM_FRACS - 1
280278
}
281-
&&& v_id@.upread_retract_token_id == g.upread_retract_token.id()
282-
&&& v_id@.upreader_guard_token_id == g.upreader_guard_token.id()
279+
&&& g.upread_retract_token is Some ==> {g.upread_retract_token->Some_0.id() == v_id@.upread_retract_token_id && g.upread_retract_token->Some_0.wf()}
280+
&&& g.upreader_guard_token is Some ==> {g.upreader_guard_token->Some_0.id() == v_id@.upreader_guard_token_id && g.upreader_guard_token->Some_0.wf()}
283281
&&& v_id@.read_retract_token_id == g.read_retract_token.id()
284282
&&& v_id@.read_guard_token_id == g.read_guard_token.id()
285283
&&& v_id@.cell_perm_resource_id == g.cell_perm_resource.id()
@@ -361,8 +359,8 @@ impl<T, G> RwLock<T, G> {
361359
let tracked cell_perm_resource = SumResource::alloc_left(frac_perm);
362360
proof_decl!{
363361
let tracked read_retract_token = TokenStorage::<V_MAX_READ_RETRACT_FRACS>::alloc(());
364-
let tracked upread_retract_token = UniqueTokenStorage::alloc(());
365-
let tracked upreader_guard_token = UniqueTokenStorage::alloc(());
362+
let tracked upread_retract_token = UniqueToken::alloc(());
363+
let tracked upreader_guard_token = UniqueToken::alloc(());
366364
let tracked read_guard_token = TokenStorage::<V_MAX_READ_GUARDS>::alloc(());
367365
}
368366
let ghost v_id = RwId {
@@ -376,8 +374,8 @@ impl<T, G> RwLock<T, G> {
376374
let tracked perms = RwPerms {
377375
cell_perm_resource,
378376
read_retract_token,
379-
upread_retract_token,
380-
upreader_guard_token,
377+
upread_retract_token: Some(upread_retract_token),
378+
upreader_guard_token: Some(upreader_guard_token),
381379
read_guard_token,
382380
};
383381

@@ -580,11 +578,11 @@ impl<T /*: ?Sized*/ , G: SpinGuardian> RwLock<T, G> {
580578
let tracked mut tmp = g.cell_perm_resource.take_resource_left();
581579
perm = Some(tmp.split(1int));
582580
g.cell_perm_resource.put_resource_left(tmp);
583-
upreader_guard_token = Some(g.upreader_guard_token.take());
581+
upreader_guard_token = Some(g.upreader_guard_token.tracked_take());
584582
left_token = Some(g.cell_perm_resource.split_left_without_resource(1int));
585583
}
586584
else if prev & (WRITER | UPGRADEABLE_READER) == WRITER {
587-
retract_upgrade_token = Some(g.upread_retract_token.take());
585+
retract_upgrade_token = Some(g.upread_retract_token.tracked_take());
588586
}
589587
}
590588
) & (WRITER | UPGRADEABLE_READER);
@@ -608,7 +606,13 @@ impl<T /*: ?Sized*/ , G: SpinGuardian> RwLock<T, G> {
608606
let next_usize = next as usize;
609607
lemma_consts_properties_value(prev_usize);
610608
lemma_consts_properties_prev_next(prev_usize, next_usize);
611-
g.upread_retract_token.join(retract_upgrade_token.tracked_unwrap());
609+
if g.upread_retract_token is Some {
610+
let tracked mut token = retract_upgrade_token.tracked_unwrap();
611+
token.validate_with_other(g.upread_retract_token.tracked_borrow());
612+
}
613+
else{
614+
g.upread_retract_token= retract_upgrade_token;
615+
}
612616
}
613617
);
614618
}
@@ -915,6 +919,7 @@ impl<'a, T, G: SpinGuardian> RwLockUpgradeableGuard<'a, T, G> {
915919
&&& self.v_perm@.frac() == 1
916920
&&& self.v_cell_perm_token@.frac() == 1
917921
&&& self.inner.upreader_guard_token_id() == self.v_guard_token@.id()
922+
&&& self.v_guard_token@.wf()
918923
}
919924
}
920925

@@ -977,7 +982,7 @@ impl<'a, T /*: ?Sized*/, G: SpinGuardian> RwLockUpgradeableGuard<'a, T, G>
977982
let tracked mut write_perm: Option<PointsTo<T>> = None;
978983
let tracked mut guard_perm: Option<RwFrac<T>> = Some(guard_perm0);
979984
let tracked mut err_guard_perm: Option<RwFrac<T>> = None;
980-
let tracked mut guard_token: Option<UniqueToken> = Some(guard_token0);
985+
let tracked mut guard_token: UniqueToken = guard_token0;
981986
let tracked mut err_guard_token: Option<UniqueToken> = None;
982987
let tracked mut retract_upgrade_token: Option<UniqueToken> = None;
983988
let tracked mut left_token: Option<Left<RwFrac<T>,NoPerm<T>,V_MAX_PERM_FRACS>> = Some(cell_perm_token0);
@@ -998,8 +1003,11 @@ impl<'a, T /*: ?Sized*/, G: SpinGuardian> RwLockUpgradeableGuard<'a, T, G>
9981003
ghost g => {
9991004
lemma_consts_properties_prev_next(prev, next);
10001005
if res is Ok {
1001-
g.upreader_guard_token.join(guard_token.tracked_unwrap());
1002-
retract_upgrade_token = Some(g.upread_retract_token.take());
1006+
if g.upreader_guard_token is Some {
1007+
guard_token.validate_with_other(g.upreader_guard_token.tracked_borrow());
1008+
}
1009+
g.upreader_guard_token = Some(guard_token);
1010+
retract_upgrade_token = Some(g.upread_retract_token.tracked_take());
10031011
g.cell_perm_resource.validate_with_left(left_token.tracked_borrow());
10041012
g.cell_perm_resource.join_left(left_token.tracked_unwrap());
10051013
let tracked mut rem = g.cell_perm_resource.take_resource_left();
@@ -1008,10 +1016,10 @@ impl<'a, T /*: ?Sized*/, G: SpinGuardian> RwLockUpgradeableGuard<'a, T, G>
10081016
write_perm = Some(full_perm);
10091017
g.cell_perm_resource.change_to_right(empty);
10101018
right_token = Some(g.cell_perm_resource.split_right_without_resource(1int));
1011-
1019+
10121020
} else {
10131021
err_guard_perm = guard_perm;
1014-
err_guard_token = guard_token;
1022+
err_guard_token = Some(guard_token);
10151023
err_left_token = left_token;
10161024
}
10171025
}
@@ -1027,9 +1035,12 @@ impl<'a, T /*: ?Sized*/, G: SpinGuardian> RwLockUpgradeableGuard<'a, T, G>
10271035
let next_usize = next as usize;
10281036
lemma_consts_properties_value(prev_usize);
10291037
lemma_consts_properties_prev_next(prev_usize, next_usize);
1030-
let tracked token = retract_upgrade_token.tracked_unwrap();
1038+
let tracked mut token = retract_upgrade_token.tracked_unwrap();
10311039
let tracked mut perm = write_perm.tracked_unwrap();
1032-
g.upread_retract_token.join(token);
1040+
if g.upread_retract_token is Some {
1041+
token.validate_with_other(g.upread_retract_token.tracked_borrow());
1042+
}
1043+
g.upread_retract_token = Some(token);
10331044
write_perm = Some(perm);
10341045
}
10351046
);
@@ -1099,12 +1110,17 @@ impl<T /*: ?Sized*/, G: SpinGuardian> RwLockUpgradeableGuard<'_, T, G>
10991110
let next_usize = next as usize;
11001111
lemma_consts_properties_value(prev_usize);
11011112
lemma_consts_properties_prev_next(prev_usize, next_usize);
1102-
g.upreader_guard_token.join(guard_token);
1103-
g.cell_perm_resource.validate_with_left(&cell_perm_token);
1104-
let tracked mut rem = g.cell_perm_resource.take_resource_left();
1105-
rem.combine(perm);
1106-
g.cell_perm_resource.put_resource_left(rem);
1107-
g.cell_perm_resource.join_left(cell_perm_token);
1113+
if g.upreader_guard_token is Some {
1114+
guard_token.validate_with_other(g.upreader_guard_token.tracked_borrow());
1115+
assert(false);
1116+
} else {
1117+
g.upreader_guard_token= Some(guard_token);
1118+
g.cell_perm_resource.validate_with_left(&cell_perm_token);
1119+
let tracked mut rem = g.cell_perm_resource.take_resource_left();
1120+
rem.combine(perm);
1121+
g.cell_perm_resource.put_resource_left(rem);
1122+
g.cell_perm_resource.join_left(cell_perm_token);
1123+
}
11081124
}
11091125
);
11101126
}

0 commit comments

Comments
 (0)