mod condvar {
    use crate::sys::locks::Mutex;
    use crate::time::Duration;

    pub struct Condvar {}

    impl Condvar {
        #[inline]
        #[rustc_const_stable(feature = "const_locks", since = "1.63.0")]
        pub const fn new() -> Condvar {
            Condvar {}
        }

        #[inline]
        pub fn notify_one(&self) {}

        #[inline]
        pub fn notify_all(&self) {}

        pub unsafe fn wait(&self, _mutex: &Mutex) {
            panic!("condvar wait not supported")
        }

        pub unsafe fn wait_timeout(&self, _mutex: &Mutex, _dur: Duration) -> bool {
            panic!("condvar wait not supported");
        }
    }
}

mod mutex {
    use crate::cell::Cell;

    pub struct Mutex {
        // This platform has no threads, so we can use a Cell here.
        locked: Cell<bool>,
    }

    unsafe impl Send for Mutex {}
    unsafe impl Sync for Mutex {} // no threads on this platform

    impl Mutex {
        #[inline]
        #[rustc_const_stable(feature = "const_locks", since = "1.63.0")]
        pub const fn new() -> Mutex {
            Mutex { locked: Cell::new(false) }
        }

        #[inline]
        pub fn lock(&self) {
            assert_eq!(self.locked.replace(true), false, "cannot recursively acquire mutex");
        }

        #[inline]
        pub unsafe fn unlock(&self) {
            self.locked.set(false);
        }

        #[inline]
        pub fn try_lock(&self) -> bool {
            self.locked.replace(true) == false
        }
    }
}

mod rwlock {
    use crate::cell::Cell;

    pub struct RwLock {
        // This platform has no threads, so we can use a Cell here.
        mode: Cell<isize>,
    }

    unsafe impl Send for RwLock {}
    unsafe impl Sync for RwLock {} // no threads on this platform

    impl RwLock {
        #[inline]
        #[rustc_const_stable(feature = "const_locks", since = "1.63.0")]
        pub const fn new() -> RwLock {
            RwLock { mode: Cell::new(0) }
        }

        #[inline]
        pub fn read(&self) {
            let m = self.mode.get();
            if m >= 0 {
                self.mode.set(m + 1);
            } else {
                rtabort!("rwlock locked for writing");
            }
        }

        #[inline]
        pub fn try_read(&self) -> bool {
            let m = self.mode.get();
            if m >= 0 {
                self.mode.set(m + 1);
                true
            } else {
                false
            }
        }

        #[inline]
        pub fn write(&self) {
            if self.mode.replace(-1) != 0 {
                rtabort!("rwlock locked for reading")
            }
        }

        #[inline]
        pub fn try_write(&self) -> bool {
            if self.mode.get() == 0 {
                self.mode.set(-1);
                true
            } else {
                false
            }
        }

        #[inline]
        pub unsafe fn read_unlock(&self) {
            self.mode.set(self.mode.get() - 1);
        }

        #[inline]
        pub unsafe fn write_unlock(&self) {
            assert_eq!(self.mode.replace(0), -1);
        }
    }
}

pub use condvar::Condvar;
pub use mutex::Mutex;
pub use rwlock::RwLock;
