//! A spinning mutex with a fairer unlock algorithm.
//!
//! This mutex is similar to the `SpinMutex` in that it uses spinning to avoid
//! context switches. However, it uses a fairer unlock algorithm that avoids
//! starvation of threads that are waiting for the lock.

use crate::{
    atomic::{AtomicUsize, Ordering},
    RelaxStrategy, Spin,
};
use core::{
    cell::UnsafeCell,
    fmt,
    marker::PhantomData,
    mem::ManuallyDrop,
    ops::{Deref, DerefMut},
};

// The lowest bit of `lock` is used to indicate whether the mutex is locked or not. The rest of the bits are used to
// store the number of starving threads.
const LOCKED: usize = 1;
const STARVED: usize = 2;

/// Number chosen by fair roll of the dice, adjust as needed.
const STARVATION_SPINS: usize = 1024;

/// A [spin lock](https://en.m.wikipedia.org/wiki/Spinlock) providing mutually exclusive access to data, but with a fairer
/// algorithm.
///
/// # Example
///
/// ```
/// use spin;
///
/// let lock = spin::mutex::FairMutex::<_>::new(0);
///
/// // Modify the data
/// *lock.lock() = 2;
///
/// // Read the data
/// let answer = *lock.lock();
/// assert_eq!(answer, 2);
/// ```
///
/// # Thread safety example
///
/// ```
/// use spin;
/// use std::sync::{Arc, Barrier};
///
/// let thread_count = 1000;
/// let spin_mutex = Arc::new(spin::mutex::FairMutex::<_>::new(0));
///
/// // We use a barrier to ensure the readout happens after all writing
/// let barrier = Arc::new(Barrier::new(thread_count + 1));
///
/// for _ in (0..thread_count) {
///     let my_barrier = barrier.clone();
///     let my_lock = spin_mutex.clone();
///     std::thread::spawn(move || {
///         let mut guard = my_lock.lock();
///         *guard += 1;
///
///         // Release the lock to prevent a deadlock
///         drop(guard);
///         my_barrier.wait();
///     });
/// }
///
/// barrier.wait();
///
/// let answer = { *spin_mutex.lock() };
/// assert_eq!(answer, thread_count);
/// ```
pub struct FairMutex<T: ?Sized, R = Spin> {
    phantom: PhantomData<R>,
    pub(crate) lock: AtomicUsize,
    data: UnsafeCell<T>,
}

/// A guard that provides mutable data access.
///
/// When the guard falls out of scope it will release the lock.
pub struct FairMutexGuard<'a, T: ?Sized + 'a> {
    lock: &'a AtomicUsize,
    data: *mut T,
}

/// A handle that indicates that we have been trying to acquire the lock for a while.
///
/// This handle is used to prevent starvation.
pub struct Starvation<'a, T: ?Sized + 'a, R> {
    lock: &'a FairMutex<T, R>,
}

/// Indicates whether a lock was rejected due to the lock being held by another thread or due to starvation.
#[derive(Debug)]
pub enum LockRejectReason {
    /// The lock was rejected due to the lock being held by another thread.
    Locked,

    /// The lock was rejected due to starvation.
    Starved,
}

// Same unsafe impls as `std::sync::Mutex`
unsafe impl<T: ?Sized + Send, R> Sync for FairMutex<T, R> {}
unsafe impl<T: ?Sized + Send, R> Send for FairMutex<T, R> {}

impl<T, R> FairMutex<T, R> {
    /// Creates a new [`FairMutex`] wrapping the supplied data.
    ///
    /// # Example
    ///
    /// ```
    /// use spin::mutex::FairMutex;
    ///
    /// static MUTEX: FairMutex<()> = FairMutex::<_>::new(());
    ///
    /// fn demo() {
    ///     let lock = MUTEX.lock();
    ///     // do something with lock
    ///     drop(lock);
    /// }
    /// ```
    #[inline(always)]
    pub const fn new(data: T) -> Self {
        FairMutex {
            lock: AtomicUsize::new(0),
            data: UnsafeCell::new(data),
            phantom: PhantomData,
        }
    }

    /// Consumes this [`FairMutex`] and unwraps the underlying data.
    ///
    /// # Example
    ///
    /// ```
    /// let lock = spin::mutex::FairMutex::<_>::new(42);
    /// assert_eq!(42, lock.into_inner());
    /// ```
    #[inline(always)]
    pub fn into_inner(self) -> T {
        // We know statically that there are no outstanding references to
        // `self` so there's no need to lock.
        let FairMutex { data, .. } = self;
        data.into_inner()
    }

    /// Returns a mutable pointer to the underlying data.
    ///
    /// This is mostly meant to be used for applications which require manual unlocking, but where
    /// storing both the lock and the pointer to the inner data gets inefficient.
    ///
    /// # Example
    /// ```
    /// let lock = spin::mutex::FairMutex::<_>::new(42);
    ///
    /// unsafe {
    ///     core::mem::forget(lock.lock());
    ///
    ///     assert_eq!(lock.as_mut_ptr().read(), 42);
    ///     lock.as_mut_ptr().write(58);
    ///
    ///     lock.force_unlock();
    /// }
    ///
    /// assert_eq!(*lock.lock(), 58);
    ///
    /// ```
    #[inline(always)]
    pub fn as_mut_ptr(&self) -> *mut T {
        self.data.get()
    }
}

impl<T: ?Sized, R: RelaxStrategy> FairMutex<T, R> {
    /// Locks the [`FairMutex`] and returns a guard that permits access to the inner data.
    ///
    /// The returned value may be dereferenced for data access
    /// and the lock will be dropped when the guard falls out of scope.
    ///
    /// ```
    /// let lock = spin::mutex::FairMutex::<_>::new(0);
    /// {
    ///     let mut data = lock.lock();
    ///     // The lock is now locked and the data can be accessed
    ///     *data += 1;
    ///     // The lock is implicitly dropped at the end of the scope
    /// }
    /// ```
    #[inline(always)]
    pub fn lock(&self) -> FairMutexGuard<T> {
        // Can fail to lock even if the spinlock is not locked. May be more efficient than `try_lock`
        // when called in a loop.
        let mut spins = 0;
        while self
            .lock
            .compare_exchange_weak(0, 1, Ordering::Acquire, Ordering::Relaxed)
            .is_err()
        {
            // Wait until the lock looks unlocked before retrying
            while self.is_locked() {
                R::relax();

                // If we've been spinning for a while, switch to a fairer strategy that will prevent
                // newer users from stealing our lock from us.
                if spins > STARVATION_SPINS {
                    return self.starve().lock();
                }
                spins += 1;
            }
        }

        FairMutexGuard {
            lock: &self.lock,
            data: unsafe { &mut *self.data.get() },
        }
    }
}

impl<T: ?Sized, R> FairMutex<T, R> {
    /// Returns `true` if the lock is currently held.
    ///
    /// # Safety
    ///
    /// This function provides no synchronization guarantees and so its result should be considered 'out of date'
    /// the instant it is called. Do not use it for synchronization purposes. However, it may be useful as a heuristic.
    #[inline(always)]
    pub fn is_locked(&self) -> bool {
        self.lock.load(Ordering::Relaxed) & LOCKED != 0
    }

    /// Force unlock this [`FairMutex`].
    ///
    /// # Safety
    ///
    /// This is *extremely* unsafe if the lock is not held by the current
    /// thread. However, this can be useful in some instances for exposing the
    /// lock to FFI that doesn't know how to deal with RAII.
    #[inline(always)]
    pub unsafe fn force_unlock(&self) {
        self.lock.fetch_and(!LOCKED, Ordering::Release);
    }

    /// Try to lock this [`FairMutex`], returning a lock guard if successful.
    ///
    /// # Example
    ///
    /// ```
    /// let lock = spin::mutex::FairMutex::<_>::new(42);
    ///
    /// let maybe_guard = lock.try_lock();
    /// assert!(maybe_guard.is_some());
    ///
    /// // `maybe_guard` is still held, so the second call fails
    /// let maybe_guard2 = lock.try_lock();
    /// assert!(maybe_guard2.is_none());
    /// ```
    #[inline(always)]
    pub fn try_lock(&self) -> Option<FairMutexGuard<T>> {
        self.try_lock_starver().ok()
    }

    /// Tries to lock this [`FairMutex`] and returns a result that indicates whether the lock was
    /// rejected due to a starver or not.
    #[inline(always)]
    pub fn try_lock_starver(&self) -> Result<FairMutexGuard<T>, LockRejectReason> {
        match self
            .lock
            .compare_exchange(0, LOCKED, Ordering::Acquire, Ordering::Relaxed)
            .unwrap_or_else(|x| x)
        {
            0 => Ok(FairMutexGuard {
                lock: &self.lock,
                data: unsafe { &mut *self.data.get() },
            }),
            LOCKED => Err(LockRejectReason::Locked),
            _ => Err(LockRejectReason::Starved),
        }
    }

    /// Indicates that the current user has been waiting for the lock for a while
    /// and that the lock should yield to this thread over a newly arriving thread.
    ///
    /// # Example
    ///
    /// ```
    /// let lock = spin::mutex::FairMutex::<_>::new(42);
    ///
    /// // Lock the mutex to simulate it being used by another user.
    /// let guard1 = lock.lock();
    ///
    /// // Try to lock the mutex.
    /// let guard2 = lock.try_lock();
    /// assert!(guard2.is_none());
    ///
    /// // Wait for a while.
    /// wait_for_a_while();
    ///
    /// // We are now starved, indicate as such.
    /// let starve = lock.starve();
    ///
    /// // Once the lock is released, another user trying to lock it will
    /// // fail.
    /// drop(guard1);
    /// let guard3 = lock.try_lock();
    /// assert!(guard3.is_none());
    ///
    /// // However, we will be able to lock it.
    /// let guard4 = starve.try_lock();
    /// assert!(guard4.is_ok());
    ///
    /// # fn wait_for_a_while() {}
    /// ```
    pub fn starve(&self) -> Starvation<'_, T, R> {
        // Add a new starver to the state.
        if self.lock.fetch_add(STARVED, Ordering::Relaxed) > (core::isize::MAX - 1) as usize {
            // In the event of a potential lock overflow, abort.
            crate::abort();
        }

        Starvation { lock: self }
    }

    /// Returns a mutable reference to the underlying data.
    ///
    /// Since this call borrows the [`FairMutex`] mutably, and a mutable reference is guaranteed to be exclusive in
    /// Rust, no actual locking needs to take place -- the mutable borrow statically guarantees no locks exist. As
    /// such, this is a 'zero-cost' operation.
    ///
    /// # Example
    ///
    /// ```
    /// let mut lock = spin::mutex::FairMutex::<_>::new(0);
    /// *lock.get_mut() = 10;
    /// assert_eq!(*lock.lock(), 10);
    /// ```
    #[inline(always)]
    pub fn get_mut(&mut self) -> &mut T {
        // We know statically that there are no other references to `self`, so
        // there's no need to lock the inner mutex.
        unsafe { &mut *self.data.get() }
    }
}

impl<T: ?Sized + fmt::Debug, R> fmt::Debug for FairMutex<T, R> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        struct LockWrapper<'a, T: ?Sized + fmt::Debug>(Option<FairMutexGuard<'a, T>>);

        impl<T: ?Sized + fmt::Debug> fmt::Debug for LockWrapper<'_, T> {
            fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
                match &self.0 {
                    Some(guard) => fmt::Debug::fmt(guard, f),
                    None => f.write_str("<locked>"),
                }
            }
        }

        f.debug_struct("FairMutex")
            .field("data", &LockWrapper(self.try_lock()))
            .finish()
    }
}

impl<T: ?Sized + Default, R> Default for FairMutex<T, R> {
    fn default() -> Self {
        Self::new(Default::default())
    }
}

impl<T, R> From<T> for FairMutex<T, R> {
    fn from(data: T) -> Self {
        Self::new(data)
    }
}

impl<'a, T: ?Sized> FairMutexGuard<'a, T> {
    /// Leak the lock guard, yielding a mutable reference to the underlying data.
    ///
    /// Note that this function will permanently lock the original [`FairMutex`].
    ///
    /// ```
    /// let mylock = spin::mutex::FairMutex::<_>::new(0);
    ///
    /// let data: &mut i32 = spin::mutex::FairMutexGuard::leak(mylock.lock());
    ///
    /// *data = 1;
    /// assert_eq!(*data, 1);
    /// ```
    #[inline(always)]
    pub fn leak(this: Self) -> &'a mut T {
        // Use ManuallyDrop to avoid stacked-borrow invalidation
        let mut this = ManuallyDrop::new(this);
        // We know statically that only we are referencing data
        unsafe { &mut *this.data }
    }
}

impl<'a, T: ?Sized + fmt::Debug> fmt::Debug for FairMutexGuard<'a, T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        fmt::Debug::fmt(&**self, f)
    }
}

impl<'a, T: ?Sized + fmt::Display> fmt::Display for FairMutexGuard<'a, T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        fmt::Display::fmt(&**self, f)
    }
}

impl<'a, T: ?Sized> Deref for FairMutexGuard<'a, T> {
    type Target = T;
    fn deref(&self) -> &T {
        // We know statically that only we are referencing data
        unsafe { &*self.data }
    }
}

impl<'a, T: ?Sized> DerefMut for FairMutexGuard<'a, T> {
    fn deref_mut(&mut self) -> &mut T {
        // We know statically that only we are referencing data
        unsafe { &mut *self.data }
    }
}

impl<'a, T: ?Sized> Drop for FairMutexGuard<'a, T> {
    /// The dropping of the MutexGuard will release the lock it was created from.
    fn drop(&mut self) {
        self.lock.fetch_and(!LOCKED, Ordering::Release);
    }
}

impl<'a, T: ?Sized, R> Starvation<'a, T, R> {
    /// Attempts the lock the mutex if we are the only starving user.
    ///
    /// This allows another user to lock the mutex if they are starving as well.
    pub fn try_lock_fair(self) -> Result<FairMutexGuard<'a, T>, Self> {
        // Try to lock the mutex.
        if self
            .lock
            .lock
            .compare_exchange(
                STARVED,
                STARVED | LOCKED,
                Ordering::Acquire,
                Ordering::Relaxed,
            )
            .is_ok()
        {
            // We are the only starving user, lock the mutex.
            Ok(FairMutexGuard {
                lock: &self.lock.lock,
                data: self.lock.data.get(),
            })
        } else {
            // Another user is starving, fail.
            Err(self)
        }
    }

    /// Attempts to lock the mutex.
    ///
    /// If the lock is currently held by another thread, this will return `None`.
    ///
    /// # Example
    ///
    /// ```
    /// let lock = spin::mutex::FairMutex::<_>::new(42);
    ///
    /// // Lock the mutex to simulate it being used by another user.
    /// let guard1 = lock.lock();
    ///
    /// // Try to lock the mutex.
    /// let guard2 = lock.try_lock();
    /// assert!(guard2.is_none());
    ///
    /// // Wait for a while.
    /// wait_for_a_while();
    ///
    /// // We are now starved, indicate as such.
    /// let starve = lock.starve();
    ///
    /// // Once the lock is released, another user trying to lock it will
    /// // fail.
    /// drop(guard1);
    /// let guard3 = lock.try_lock();
    /// assert!(guard3.is_none());
    ///
    /// // However, we will be able to lock it.
    /// let guard4 = starve.try_lock();
    /// assert!(guard4.is_ok());
    ///
    /// # fn wait_for_a_while() {}
    /// ```
    pub fn try_lock(self) -> Result<FairMutexGuard<'a, T>, Self> {
        // Try to lock the mutex.
        if self.lock.lock.fetch_or(LOCKED, Ordering::Acquire) & LOCKED == 0 {
            // We have successfully locked the mutex.
            // By dropping `self` here, we decrement the starvation count.
            Ok(FairMutexGuard {
                lock: &self.lock.lock,
                data: self.lock.data.get(),
            })
        } else {
            Err(self)
        }
    }
}

impl<'a, T: ?Sized, R: RelaxStrategy> Starvation<'a, T, R> {
    /// Locks the mutex.
    pub fn lock(mut self) -> FairMutexGuard<'a, T> {
        // Try to lock the mutex.
        loop {
            match self.try_lock() {
                Ok(lock) => return lock,
                Err(starve) => self = starve,
            }

            // Relax until the lock is released.
            while self.lock.is_locked() {
                R::relax();
            }
        }
    }
}

impl<'a, T: ?Sized, R> Drop for Starvation<'a, T, R> {
    fn drop(&mut self) {
        // As there is no longer a user being starved, we decrement the starver count.
        self.lock.lock.fetch_sub(STARVED, Ordering::Release);
    }
}

impl fmt::Display for LockRejectReason {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match self {
            LockRejectReason::Locked => write!(f, "locked"),
            LockRejectReason::Starved => write!(f, "starved"),
        }
    }
}

#[cfg(feature = "std")]
impl std::error::Error for LockRejectReason {}

#[cfg(feature = "lock_api")]
unsafe impl<R: RelaxStrategy> lock_api_crate::RawMutex for FairMutex<(), R> {
    type GuardMarker = lock_api_crate::GuardSend;

    const INIT: Self = Self::new(());

    fn lock(&self) {
        // Prevent guard destructor running
        core::mem::forget(Self::lock(self));
    }

    fn try_lock(&self) -> bool {
        // Prevent guard destructor running
        Self::try_lock(self).map(core::mem::forget).is_some()
    }

    unsafe fn unlock(&self) {
        self.force_unlock();
    }

    fn is_locked(&self) -> bool {
        Self::is_locked(self)
    }
}

#[cfg(test)]
mod tests {
    use std::prelude::v1::*;

    use std::sync::atomic::{AtomicUsize, Ordering};
    use std::sync::mpsc::channel;
    use std::sync::Arc;
    use std::thread;

    type FairMutex<T> = super::FairMutex<T>;

    #[derive(Eq, PartialEq, Debug)]
    struct NonCopy(i32);

    #[test]
    fn smoke() {
        let m = FairMutex::<_>::new(());
        drop(m.lock());
        drop(m.lock());
    }

    #[test]
    fn lots_and_lots() {
        static M: FairMutex<()> = FairMutex::<_>::new(());
        static mut CNT: u32 = 0;
        const J: u32 = 1000;
        const K: u32 = 3;

        fn inc() {
            for _ in 0..J {
                unsafe {
                    let _g = M.lock();
                    CNT += 1;
                }
            }
        }

        let (tx, rx) = channel();
        for _ in 0..K {
            let tx2 = tx.clone();
            thread::spawn(move || {
                inc();
                tx2.send(()).unwrap();
            });
            let tx2 = tx.clone();
            thread::spawn(move || {
                inc();
                tx2.send(()).unwrap();
            });
        }

        drop(tx);
        for _ in 0..2 * K {
            rx.recv().unwrap();
        }
        assert_eq!(unsafe { CNT }, J * K * 2);
    }

    #[test]
    fn try_lock() {
        let mutex = FairMutex::<_>::new(42);

        // First lock succeeds
        let a = mutex.try_lock();
        assert_eq!(a.as_ref().map(|r| **r), Some(42));

        // Additional lock fails
        let b = mutex.try_lock();
        assert!(b.is_none());

        // After dropping lock, it succeeds again
        ::core::mem::drop(a);
        let c = mutex.try_lock();
        assert_eq!(c.as_ref().map(|r| **r), Some(42));
    }

    #[test]
    fn test_into_inner() {
        let m = FairMutex::<_>::new(NonCopy(10));
        assert_eq!(m.into_inner(), NonCopy(10));
    }

    #[test]
    fn test_into_inner_drop() {
        struct Foo(Arc<AtomicUsize>);
        impl Drop for Foo {
            fn drop(&mut self) {
                self.0.fetch_add(1, Ordering::SeqCst);
            }
        }
        let num_drops = Arc::new(AtomicUsize::new(0));
        let m = FairMutex::<_>::new(Foo(num_drops.clone()));
        assert_eq!(num_drops.load(Ordering::SeqCst), 0);
        {
            let _inner = m.into_inner();
            assert_eq!(num_drops.load(Ordering::SeqCst), 0);
        }
        assert_eq!(num_drops.load(Ordering::SeqCst), 1);
    }

    #[test]
    fn test_mutex_arc_nested() {
        // Tests nested mutexes and access
        // to underlying data.
        let arc = Arc::new(FairMutex::<_>::new(1));
        let arc2 = Arc::new(FairMutex::<_>::new(arc));
        let (tx, rx) = channel();
        let _t = thread::spawn(move || {
            let lock = arc2.lock();
            let lock2 = lock.lock();
            assert_eq!(*lock2, 1);
            tx.send(()).unwrap();
        });
        rx.recv().unwrap();
    }

    #[test]
    fn test_mutex_arc_access_in_unwind() {
        let arc = Arc::new(FairMutex::<_>::new(1));
        let arc2 = arc.clone();
        let _ = thread::spawn(move || -> () {
            struct Unwinder {
                i: Arc<FairMutex<i32>>,
            }
            impl Drop for Unwinder {
                fn drop(&mut self) {
                    *self.i.lock() += 1;
                }
            }
            let _u = Unwinder { i: arc2 };
            panic!();
        })
        .join();
        let lock = arc.lock();
        assert_eq!(*lock, 2);
    }

    #[test]
    fn test_mutex_unsized() {
        let mutex: &FairMutex<[i32]> = &FairMutex::<_>::new([1, 2, 3]);
        {
            let b = &mut *mutex.lock();
            b[0] = 4;
            b[2] = 5;
        }
        let comp: &[i32] = &[4, 2, 5];
        assert_eq!(&*mutex.lock(), comp);
    }

    #[test]
    fn test_mutex_force_lock() {
        let lock = FairMutex::<_>::new(());
        ::std::mem::forget(lock.lock());
        unsafe {
            lock.force_unlock();
        }
        assert!(lock.try_lock().is_some());
    }
}
