11// SPDX-License-Identifier: MPL-2.0
2+ use vstd:: prelude:: * ;
3+ use vstd:: atomic_ghost:: * ;
4+ use vstd_extra:: prelude:: * ;
5+
26use alloc:: sync:: Arc ;
3- use core:: sync:: atomic:: { fence, AtomicUsize , Ordering } ;
7+ // use core::sync::atomic::{fence, AtomicUsize, Ordering};
48
5- use vstd:: prelude:: * ;
69
710use super :: { PreemptDisabled , RwLock , RwLockReadGuard , RwLockWriteGuard } ;
811
@@ -28,31 +31,39 @@ pub struct RwArc<T>(Arc<Inner<T>>);
2831/// the type and method documentation for more details.
2932pub struct RoArc <T >( Arc <Inner <T >>) ;
3033
34+ struct_with_invariants!{
3135struct Inner <T > {
3236 data: RwLock <T , PreemptDisabled >,
33- num_rw: AtomicUsize ,
37+ num_rw: AtomicUsize <_, int, _>,
38+ }
39+
40+ closed spec fn wf( & self ) -> bool {
41+ invariant on num_rw with ( data) is ( v: usize , g: int) {
42+ v == g
43+ }
44+ }
3445}
3546
3647impl <T > RwArc <T > {
3748 /// Creates a new `RwArc<T>`.
38- #[ verifier:: external_body]
3949 pub fn new( data: T ) -> Self {
40- let inner = Inner { data: RwLock :: new( data) , num_rw: AtomicUsize :: new( 1 ) } ;
50+ //let inner = Inner { data: RwLock::new(data), num_rw: AtomicUsize::new(1) };
51+ let data = RwLock :: new( data) ;
52+ let inner = Inner { data, num_rw: AtomicUsize :: new( Ghost ( data) , 1 , Tracked ( 1 int) ) } ;
4153 Self ( Arc :: new( inner) )
4254 }
4355
4456 /// Acquires the read lock for immutable access.
45- #[ verifier:: external_body]
4657 pub fn read( & self ) -> RwLockReadGuard <T , PreemptDisabled > {
4758 self . 0 . data. read( )
4859 }
4960
5061 /// Acquires the write lock for mutable access.
51- #[ verifier:: external_body]
5262 pub fn write( & self ) -> RwLockWriteGuard <T , PreemptDisabled > {
5363 self . 0 . data. write( )
5464 }
5565
66+ /*
5667 /// Returns an immutable reference if no other `RwArc` points to the same allocation.
5768 ///
5869 /// This method is cheap because it does not acquire a lock.
@@ -77,14 +88,14 @@ impl<T> RwArc<T> {
7788 // reference to the data, so it's okay to create an immutable reference like the one below.
7889 Some(unsafe { &*data_ptr })
7990 }
80-
91+ */
8192 /// Clones a [`RoArc`] that points to the same allocation.
8293 #[ verifier:: external_body]
8394 pub fn clone_ro( & self ) -> RoArc <T > {
8495 RoArc ( self . 0 . clone( ) )
8596 }
8697}
87-
98+ /*
8899// #[verifier::external]
89100impl<T> Clone for RwArc<T> {
90101 #[verifier::external_body]
@@ -116,7 +127,7 @@ impl<T: Clone> RwArc<T> {
116127 let guard = self.read();
117128 guard.clone()
118129 }
119- }
130+ }*/
120131
121132impl <T > RoArc <T > {
122133 /// Acquires the read lock for immutable access.
@@ -127,7 +138,8 @@ impl<T> RoArc<T> {
127138}
128139
129140} // verus!
130- /* #[cfg(ktest)]
141+
142+ #[ cfg( ktest) ]
131143mod test {
132144 use super :: * ;
133145 use crate :: prelude:: * ;
@@ -146,4 +158,4 @@ mod test {
146158 drop ( rw2) ;
147159 assert_eq ! ( rw1. get( ) , Some ( 1 ) . as_ref( ) ) ;
148160 }
149- } */
161+ }
0 commit comments