@@ -16,10 +16,6 @@ use core::{
1616use 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!{ }
152148impl <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
434399verus ! {
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