Skip to content

Commit b4ec91d

Browse files
authored
Migrate to latest SpinLock (#336)
* Migrate to latest SpinLock * Minor
1 parent 10a97de commit b4ec91d

3 files changed

Lines changed: 49 additions & 83 deletions

File tree

ostd/src/sync/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ pub use self::{
2222
ArcRwMutexReadGuard, ArcRwMutexUpgradeableGuard, ArcRwMutexWriteGuard, RwMutex,
2323
RwMutexReadGuard, RwMutexUpgradeableGuard, RwMutexWriteGuard,
2424
},*/
25-
spin::{ArcSpinLockGuard, SpinLock, SpinLockGuard},
25+
spin::{SpinLock, SpinLockGuard},
2626
//wait::{WaitQueue, Waiter, Waker},
2727
};
2828
/*

ostd/src/sync/rwlock.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -579,14 +579,17 @@ unsafe impl<T: /*?Sized +*/ Send, G> Send for RwLock<T, G> {}
579579
#[verifier::external]
580580
unsafe impl<T: /*?Sized +*/ Send + Sync, G> Sync for RwLock<T, G> {}
581581

582+
#[verus_verify]
582583
impl<T: /*?Sized*/, G: SpinGuardian> !Send for RwLockWriteGuard<'_, T, G> {}
583584
#[verifier::external]
584585
unsafe impl<T: /*?Sized +*/ Sync, G: SpinGuardian> Sync for RwLockWriteGuard<'_, T, G> {}
585586

587+
#[verus_verify]
586588
impl<T: /*?Sized*/, G: SpinGuardian> !Send for RwLockReadGuard<'_, T, G> {}
587589
#[verifier::external]
588590
unsafe impl<T: /*?Sized +*/ Sync, G: SpinGuardian> Sync for RwLockReadGuard<'_, T, G> {}
589591

592+
#[verus_verify]
590593
impl<T: /*?Sized*/, G: SpinGuardian> !Send for RwLockUpgradeableGuard<'_, T, G> {}
591594
#[verifier::external]
592595
unsafe impl<T: /*?Sized +*/ Sync, G: SpinGuardian> Sync for RwLockUpgradeableGuard<'_, T, G> {}

ostd/src/sync/spin.rs

Lines changed: 45 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,6 @@ use core::{
1616
use super::{guard::SpinGuardian, LocalIrqDisabled /*, PreemptDisabled*/};
1717
//use crate::task::atomic_mode::AsAtomicModeGuard;
1818

19-
verus! {
20-
broadcast use group_deref_spec;
21-
}
22-
2319
/// A spin lock.
2420
///
2521
/// # Guard behavior
@@ -34,13 +30,14 @@ verus! {
3430
/// The guard behavior can be temporarily upgraded from [`PreemptDisabled`] to
3531
/// [`LocalIrqDisabled`] using the [`disable_irq`] method.
3632
///
33+
/// [`disable_irq`]: Self::disable_irq
34+
///
3735
/// # Verified Properties
3836
/// ## Verification Design
3937
/// To verify the correctness of spin lock, we use a ghost permission (i.e., not present in executable Rust). Only the owner of this permission can access the protected data in the cell.
4038
/// When [`lock`] or [`try_lock`] succeeds, the ghost permission is transferred to the lock guard and given to the user for accessing the protected data.
4139
/// When the lock guard is dropped, the ghost permission is transferred back to the spin lock.
4240
///
43-
/// [`disable_irq`]: Self::disable_irq
4441
/// [`lock`]: Self::lock
4542
/// [`try_lock`]: Self::try_lock
4643
///
@@ -148,7 +145,6 @@ impl<T, G> SpinLock<T, G> {
148145
}
149146
}
150147

151-
verus!{}
152148
impl<T,G> SpinLock<T,G>
153149
{
154150
/// Returns the unique [`CellId`](https://verus-lang.github.io/verus/verusdoc/vstd/cell/struct.CellId.html) of the internal `PCell<T>`.
@@ -210,7 +206,7 @@ impl<T, G: SpinGuardian> SpinLock<T, G> {
210206
///}.is_ok()
211207
/// ```
212208
#[verus_spec]
213-
pub fn lock(&self) -> SpinLockGuard<T, G> {
209+
pub fn lock(&self) -> SpinLockGuard<'_, T, G> {
214210
// Notice the guard must be created before acquiring the lock.
215211
proof!{ use_type_invariant(self);}
216212
proof_decl!{
@@ -219,41 +215,13 @@ impl<T, G: SpinGuardian> SpinLock<T, G> {
219215
let inner_guard = G::guard();
220216
proof_with! {=> Tracked(perm)}
221217
self.acquire_lock();
222-
SpinLockGuard_ {
218+
SpinLockGuard {
223219
lock: self,
224220
guard: inner_guard,
225221
v_perm: Tracked(perm),
226222
}
227223
}
228224

229-
/// Acquires the spin lock through an [`Arc`].
230-
///
231-
/// The method is similar to [`lock`], but it doesn't have the requirement
232-
/// for compile-time checked lifetimes of the lock guard.
233-
///
234-
/// [`lock`]: Self::lock
235-
///
236-
/// # Verified Properties
237-
/// Same as [`lock`].
238-
#[verus_spec]
239-
pub fn lock_arc(self: &Arc<Self>) -> ArcSpinLockGuard<T, G> {
240-
proof!{ use_type_invariant(self);}
241-
proof_decl!{
242-
let tracked mut perm: PointsTo<T> = arbitrary_cell_pointsto();
243-
}
244-
let inner_guard = G::guard();
245-
proof_with! {=> Tracked(perm)}
246-
self.acquire_lock();
247-
proof!{
248-
assert(perm.id() == (*self.clone().deref_spec()).cell_id());
249-
}
250-
SpinLockGuard_ {
251-
lock: self.clone(),
252-
guard: inner_guard,
253-
v_perm: Tracked(perm),
254-
}
255-
}
256-
257225
/// Tries acquiring the spin lock immediately.
258226
///
259227
/// # Verified Properties
@@ -266,13 +234,13 @@ impl<T, G: SpinGuardian> SpinLock<T, G> {
266234
/// - An exclusive permission to access the protected data is held by the guard.
267235
/// - The guard's permission matches the lock's internal cell ID.
268236
#[verus_spec]
269-
pub fn try_lock(&self) -> Option<SpinLockGuard<T, G>> {
237+
pub fn try_lock(&self) -> Option<SpinLockGuard<'_, T, G>> {
270238
let inner_guard = G::guard();
271239
proof_decl!{
272240
let tracked mut perm: Option<PointsTo<T>> = None;
273241
}
274242
if #[verus_spec(with => Tracked(perm))] self.try_acquire_lock() {
275-
let lock_guard = SpinLockGuard_ {
243+
let lock_guard = SpinLockGuard {
276244
lock: self,
277245
guard: inner_guard,
278246
v_perm: Tracked(perm.tracked_unwrap()),
@@ -385,12 +353,14 @@ impl<T: ?Sized + fmt::Debug, G> fmt::Debug for SpinLock<T, G> {
385353
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
386354
fmt::Debug::fmt(&self.inner.val, f)
387355
}
388-
}
356+
}*/
389357

390358
// SAFETY: Only a single lock holder is permitted to access the inner data of Spinlock.
391-
unsafe impl<T: ?Sized + Send, G> Send for SpinLock<T, G> {}
392-
unsafe impl<T: ?Sized + Send, G> Sync for SpinLock<T, G> {}
393-
*/
359+
#[verifier::external]
360+
unsafe impl<T: /*?Sized +*/ Send, G> Send for SpinLock<T, G> {}
361+
#[verifier::external]
362+
unsafe impl<T: /*?Sized +*/ Send, G> Sync for SpinLock<T, G> {}
363+
394364
/// A guard that provides exclusive access to the data protected by a [`SpinLock`].
395365
///
396366
/// # Verified Properties
@@ -408,91 +378,84 @@ unsafe impl<T: ?Sized + Send, G> Sync for SpinLock<T, G> {}
408378
/// ```rust
409379
/// #[verifier::type_invariant]
410380
/// spec fn type_inv(self) -> bool{
411-
/// self.lock.deref_spec().cell_id() == self.v_perm@.id()
381+
/// self.lock.cell_id() == self.v_perm@.id()
412382
/// }
413383
/// ```
414384
///
415385
/// *Note*: The invariant is encapsulated using the [`#[verifier::type_invariant]`](https://verus-lang.github.io/verus/guide/reference-type-invariants.html?highlight=type_#declaring-a-type-invariant) mechanism.
416386
/// It internally holds at all steps during the method executions and is **NOT** exposed in the public APIs' pre- and post-conditions.
417-
pub type SpinLockGuard<'a, T, G> = SpinLockGuard_<T, &'a SpinLock<T, G>, G>;
418-
/// A guard that provides exclusive access to the data protected by a `Arc<SpinLock>`.
419-
pub type ArcSpinLockGuard<T, G> = SpinLockGuard_<T, Arc<SpinLock<T, G>>, G>;
420-
421-
/// The guard of a spin lock.
422-
#[clippy::has_significant_drop]
423-
#[must_use]
424387
#[verifier::reject_recursive_types(T)]
425388
#[verifier::reject_recursive_types(G)]
426389
#[verus_verify]
427-
pub struct SpinLockGuard_<T /*: ?Sized*/, R: Deref<Target = SpinLock<T, G>>, G: SpinGuardian> {
390+
#[clippy::has_significant_drop]
391+
#[must_use]
392+
pub struct SpinLockGuard<'a, T /*: ?Sized*/, G: SpinGuardian> {
428393
guard: G::Guard,
429-
lock: R,
394+
lock: &'a SpinLock<T, G>,
430395
/// Ghost permission for verification
431396
v_perm: Tracked<PointsTo<T>>,
432397
}
433398

434399
verus! {
435-
impl<T, R: Deref<Target = SpinLock<T, G>>, G: SpinGuardian> SpinLockGuard_<T, R, G>
400+
impl<'a, T, G: SpinGuardian> SpinLockGuard<'a, T, G>
436401
{
437402
#[verifier::type_invariant]
438403
spec fn type_inv(self) -> bool{
439-
self.lock.deref_spec().cell_id() == self.v_perm@.id()
404+
self.lock.cell_id() == self.v_perm@.id()
440405
}
441406
}
442407
}
443408
/*
444-
impl<T: ?Sized, R: Deref<Target = SpinLock<T, G>>, G: SpinGuardian> AsAtomicModeGuard
445-
for SpinLockGuard_<T, R, G>
446-
{
409+
impl<T: ?Sized, G: SpinGuardian> AsAtomicModeGuard for SpinLockGuard<'_, T, G> {
447410
fn as_atomic_mode_guard(&self) -> &dyn crate::task::atomic_mode::InAtomicMode {
448411
self.guard.as_atomic_mode_guard()
449412
}
450-
}
413+
}*/
451414

452-
impl<T: ?Sized, R: Deref<Target = SpinLock<T, G>>, G: SpinGuardian> Deref
453-
for SpinLockGuard_<T, R, G>
454-
{
415+
verus!{
416+
#[verus_verify]
417+
impl<T: /*?Sized*/, G: SpinGuardian> Deref for SpinLockGuard<'_, T, G> {
455418
type Target = T;
456419

420+
#[verus_spec]
457421
fn deref(&self) -> &T {
458-
unsafe { &*self.lock.inner.val.get() }
422+
proof_decl! {
423+
let tracked read_perm = self.v_perm.borrow();
424+
}
425+
proof!{
426+
use_type_invariant(self);
427+
}
428+
// unsafe { &*self.lock.inner.val.get() }
429+
// The internal implementation of `PCell<T>::borrow` is exactly unsafe { &(*(*self.ucell).get()) },
430+
// and here we verify that we have the permission to call `borrow`.
431+
self.lock.inner.val.borrow(Tracked(read_perm))
459432
}
460433
}
434+
}
461435

462-
impl<T: ?Sized, R: Deref<Target = SpinLock<T, G>>, G: SpinGuardian> DerefMut
463-
for SpinLockGuard_<T, R, G>
464-
{
436+
/*
437+
impl<T: ?Sized, G: SpinGuardian> DerefMut for SpinLockGuard<'_, T, G> {
465438
fn deref_mut(&mut self) -> &mut Self::Target {
466439
unsafe { &mut *self.lock.inner.val.get() }
467440
}
468441
}
469442
470-
impl<T: ?Sized, R: Deref<Target = SpinLock<T, G>>, G: SpinGuardian> Drop
471-
for SpinLockGuard_<T, R, G>
472-
{
443+
impl<T: ?Sized, G: SpinGuardian> Drop for SpinLockGuard<'_, T, G> {
473444
fn drop(&mut self) {
474445
self.lock.release_lock();
475446
}
476447
}
477448
478-
impl<T: ?Sized + fmt::Debug, R: Deref<Target = SpinLock<T, G>>, G: SpinGuardian> fmt::Debug
479-
for SpinLockGuard_<T, R, G>
480-
{
449+
impl<T: ?Sized + fmt::Debug, G: SpinGuardian> fmt::Debug for SpinLockGuard<'_, T, G> {
481450
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
482451
fmt::Debug::fmt(&**self, f)
483452
}
484453
}*/
485454

486-
/*
487-
impl<T: ?Sized, R: Deref<Target = SpinLock<T, G>>, G: SpinGuardian> !Send
488-
for SpinLockGuard_<T, R, G>
489-
{
490-
}
455+
#[verus_verify]
456+
impl<T: ?Sized, G: SpinGuardian> !Send for SpinLockGuard<'_, T, G> {}
491457

492-
// SAFETY: `SpinLockGuard_` can be shared between tasks/threads in same CPU.
458+
#[verifier::external]
459+
// SAFETY: `SpinLockGuard` can be shared between tasks/threads in same CPU.
493460
// As `lock()` is only called when there are no race conditions caused by interrupts.
494-
unsafe impl<T: ?Sized + Sync, R: Deref<Target = SpinLock<T, G>> + Sync, G: SpinGuardian> Sync
495-
for SpinLockGuard_<T, R, G>
496-
{
497-
}
498-
*/
461+
unsafe impl<T: /*?Sized +*/ Sync, G: SpinGuardian> Sync for SpinLockGuard<'_, T, G> {}

0 commit comments

Comments
 (0)