Skip to content

Commit d09c549

Browse files
authored
Prove rwarc APIs (#350)
1 parent b6efad3 commit d09c549

1 file changed

Lines changed: 24 additions & 12 deletions

File tree

ostd/src/sync/rwarc.rs

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
// SPDX-License-Identifier: MPL-2.0
2+
use vstd::prelude::*;
3+
use vstd::atomic_ghost::*;
4+
use vstd_extra::prelude::*;
5+
26
use 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

710
use 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.
2932
pub struct RoArc<T>(Arc<Inner<T>>);
3033

34+
struct_with_invariants!{
3135
struct 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

3647
impl<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(1int)) };
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]
89100
impl<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

121132
impl<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)]
131143
mod 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

Comments
 (0)