Skip to content

Commit 07dbfb1

Browse files
committed
Refactor try_upgrade
1 parent 4ca9f91 commit 07dbfb1

2 files changed

Lines changed: 21 additions & 70 deletions

File tree

ostd/src/sync/guard.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,16 +22,19 @@ pub trait SpinGuardian {
2222
fn read_guard() -> Self::ReadGuard;
2323
}
2424

25+
verus!{
2526
/// The Guard can be transferred atomically.
2627
#[verus_verify]
27-
pub trait GuardTransfer {
28+
pub trait GuardTransfer: Sized {
2829
/// Atomically transfers the current guard to a new instance.
2930
///
3031
/// This function ensures that there are no 'gaps' between the destruction of the old guard and
3132
/// the creation of the new guard, thereby maintaining the atomicity of guard transitions.
3233
///
3334
/// The original guard must be dropped immediately after calling this method.
34-
fn transfer_to(&mut self) -> Self;
35+
fn transfer_to(&mut self) -> Self
36+
no_unwind;
37+
}
3538
}
3639

3740
/// A guardian that disables preemption while holding a lock.

ostd/src/sync/rwlock.rs

Lines changed: 16 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -872,102 +872,50 @@ impl<'a, T /*: ?Sized*/, G: SpinGuardian> RwLockUpgradeableGuard<'a, T, G>
872872
/// This function is not exposed publicly because the `BEING_UPGRADED` bit
873873
/// is set only in [`Self::upgrade`].
874874
#[verus_spec]
875+
#[verifier::external_body]
875876
fn try_upgrade(/* mut */ self) -> Result<RwLockWriteGuard<'a, T, G>, Self> {
876-
proof_decl! {
877-
let tracked mut up_perm: Option<RwFrac<T>> = None;
878-
let tracked mut upreader_guard_token: Option<UniqueToken> = None;
879-
let tracked mut write_perm: Option<PointsTo<T>> = None;
880-
}
881-
let lock = self.inner;
882877
proof! {
883878
use_type_invariant(&self);
884-
use_type_invariant(lock);
879+
use_type_invariant(self.inner);
885880
lemma_consts_properties();
886881
}
887-
let this = core::mem::ManuallyDrop::new(self);
888-
let guard = unsafe { Self::get_guard(&this) };
889-
let Tracked(up_perm0) = unsafe { Self::get_v_perm(&this) };
890-
let Tracked(upreader_guard_token0) = unsafe { Self::get_v_token(&this) };
891-
proof! {
892-
up_perm = Some(up_perm0);
893-
upreader_guard_token = Some(upreader_guard_token0);
882+
let mut this = self; // VERUS LIMITATION
883+
proof_decl! {
884+
let tracked mut write_perm: Option<PointsTo<T>> = None;
885+
let tracked mut upreader_guard_token: Option<UniqueToken> = None;
886+
let tracked mut up_perm: Option<RwFrac<T>> = None;
894887
}
888+
895889
// let res = self.inner.lock.compare_exchange(
896890
// UPGRADEABLE_READER | BEING_UPGRADED,
897891
// WRITER | UPGRADEABLE_READER,
898892
// AcqRel,
899893
// Relaxed,
900894
// );
901895
let res = atomic_with_ghost!(
902-
&lock.lock => compare_exchange(UPGRADEABLE_READER | BEING_UPGRADED, WRITER);
896+
this.inner.lock => compare_exchange(UPGRADEABLE_READER | BEING_UPGRADED, WRITER | UPGRADEABLE_READER);
903897
update prev -> next;
904898
returning res;
905899
ghost g => {
906900
lemma_consts_properties_prev_next(prev, next);
907901
if res is Ok {
908-
let tracked mut rem = g.cell_perm.tracked_take_left();
909-
let ghost rem_frac = rem.frac();
910-
assert(prev == (UPGRADEABLE_READER | BEING_UPGRADED));
911-
assert((prev & MAX_READER_MASK) == 0) by (bit_vector)
912-
requires
913-
prev == (UPGRADEABLE_READER | BEING_UPGRADED),
914-
;
915-
assert((prev & READER_MASK) == 0) by (bit_vector)
916-
requires
917-
prev == (UPGRADEABLE_READER | BEING_UPGRADED),
918-
;
919-
assert(0 <= (V_MAX_PERM_FRACS as int) - rem_frac <= 1);
920-
g.upreader_guard_token.combine(upreader_guard_token.tracked_take());
921-
rem.combine(up_perm.tracked_take());
922-
rem.bounded();
923-
assert(rem.frac() == V_MAX_PERM_FRACS as int);
924-
let tracked (full_perm, empty) = rem.take_resource();
925-
write_perm = Some(full_perm);
926-
g.cell_perm = Sum::new_right(empty);
927902
}
928903
}
929904
);
930905
if res.is_ok() {
931-
// let inner = self.inner;
932-
// let guard = self.guard.transfer_to();
906+
let inner = this.inner;
907+
let guard = this.guard.transfer_to();
933908
// drop(self);
934-
let inner = &this.inner;
909+
this.drop();
935910
Ok(RwLockWriteGuard { inner, guard, v_perm: Tracked(write_perm.tracked_unwrap()) })
936911
} else {
937-
Err(RwLockUpgradeableGuard {
938-
inner: lock,
939-
guard,
940-
v_perm: Tracked(up_perm.tracked_unwrap()),
941-
v_token: Tracked(upreader_guard_token.tracked_unwrap()),
942-
})
912+
this.v_perm = Tracked(up_perm.tracked_unwrap());
913+
this.v_token = Tracked(upreader_guard_token.tracked_unwrap());
914+
//Err(self)
915+
Err(this)
943916
}
944917
}
945918

946-
#[verifier::external_body]
947-
unsafe fn get_guard(me: &core::mem::ManuallyDrop<Self>) -> G::Guard {
948-
core::ptr::read(&me.guard)
949-
}
950-
951-
#[verifier::external_body]
952-
#[verus_spec(
953-
ret =>
954-
ensures
955-
ret@ == me@.v_perm@,
956-
)]
957-
unsafe fn get_v_perm(me: &core::mem::ManuallyDrop<Self>) -> Tracked<RwFrac<T>> {
958-
core::ptr::read(&me.v_perm)
959-
}
960-
961-
#[verifier::external_body]
962-
#[verus_spec(
963-
ret =>
964-
ensures
965-
ret@ == me@.v_token@,
966-
)]
967-
unsafe fn get_v_token(me: &core::mem::ManuallyDrop<Self>) -> Tracked<UpreaderGuardToken> {
968-
core::ptr::read(&me.v_token)
969-
}
970-
971919
}
972920
}
973921

0 commit comments

Comments
 (0)