Skip to main content

std/sys/sync/rwlock/
no_threads.rs

1use crate::cell::Cell;
2
3pub struct RwLock {
4    // This platform has no threads, so we can use a Cell here.
5    mode: Cell<isize>,
6}
7
8unsafe impl Send for RwLock {}
9unsafe impl Sync for RwLock {} // no threads on this platform
10
11impl RwLock {
12    #[inline]
13    pub const fn new() -> RwLock {
14        RwLock { mode: Cell::new(0) }
15    }
16
17    #[inline]
18    pub fn read(&self) {
19        let m = self.mode.get();
20        if m >= 0 {
21            self.mode.set(m.checked_add(1).expect("rwlock overflowed read locks"));
22        } else {
23            rtabort!("rwlock locked for writing");
24        }
25    }
26
27    #[inline]
28    pub fn try_read(&self) -> bool {
29        let m = self.mode.get();
30        if m >= 0 {
31            if m == isize::MAX {
32                return false;
33            }
34            self.mode.set(m + 1);
35            true
36        } else {
37            false
38        }
39    }
40
41    #[inline]
42    pub fn write(&self) {
43        if self.mode.get() == 0 {
44            self.mode.set(-1);
45        } else {
46            rtabort!("rwlock locked for reading");
47        }
48    }
49
50    #[inline]
51    pub fn try_write(&self) -> bool {
52        if self.mode.get() == 0 {
53            self.mode.set(-1);
54            true
55        } else {
56            false
57        }
58    }
59
60    #[inline]
61    pub unsafe fn read_unlock(&self) {
62        assert!(
63            self.mode.replace(self.mode.get() - 1) > 0,
64            "rwlock has not been locked for reading"
65        );
66    }
67
68    #[inline]
69    pub unsafe fn write_unlock(&self) {
70        assert_eq!(self.mode.replace(0), -1, "rwlock has not been locked for writing");
71    }
72
73    #[inline]
74    pub unsafe fn downgrade(&self) {
75        assert_eq!(self.mode.replace(1), -1, "rwlock has not been locked for writing");
76    }
77}