//! A wait-flag-based thread parker.
//!
//! Some operating systems provide low-level parking primitives like wait counts,
//! event flags or semaphores which are not susceptible to race conditions (meaning
//! the wakeup can occur before the wait operation). To implement the `std` thread
//! parker on top of these primitives, we only have to ensure that parking is fast
//! when the thread token is available, the atomic ordering guarantees are maintained
//! and spurious wakeups are minimized.
//!
//! To achieve this, this parker uses an atomic variable with three states: `EMPTY`,
//! `PARKED` and `NOTIFIED`:
//! * `EMPTY` means the token has not been made available, but the thread is not
//!    currently waiting on it.
//! * `PARKED` means the token is not available and the thread is parked.
//! * `NOTIFIED` means the token is available.
//!
//! `park` and `park_timeout` change the state from `EMPTY` to `PARKED` and from
//! `NOTIFIED` to `EMPTY`. If the state was `NOTIFIED`, the thread was unparked and
//! execution can continue without calling into the OS. If the state was `EMPTY`,
//! the token is not available and the thread waits on the primitive (here called
//! "wait flag").
//!
//! `unpark` changes the state to `NOTIFIED`. If the state was `PARKED`, the thread
//! is or will be sleeping on the wait flag, so we raise it.

use crate::pin::Pin;
use crate::sync::atomic::AtomicI8;
use crate::sync::atomic::Ordering::{Acquire, Relaxed, Release};
use crate::sys::wait_flag::WaitFlag;
use crate::time::Duration;

const EMPTY: i8 = 0;
const PARKED: i8 = -1;
const NOTIFIED: i8 = 1;

pub struct Parker {
    state: AtomicI8,
    wait_flag: WaitFlag,
}

impl Parker {
    /// Construct a parker for the current thread. The UNIX parker
    /// implementation requires this to happen in-place.
    pub unsafe fn new(parker: *mut Parker) {
        parker.write(Parker { state: AtomicI8::new(EMPTY), wait_flag: WaitFlag::new() })
    }

    // This implementation doesn't require `unsafe` and `Pin`, but other implementations do.
    pub unsafe fn park(self: Pin<&Self>) {
        match self.state.fetch_sub(1, Acquire) {
            // NOTIFIED => EMPTY
            NOTIFIED => return,
            // EMPTY => PARKED
            EMPTY => (),
            _ => panic!("inconsistent park state"),
        }

        // Avoid waking up from spurious wakeups (these are quite likely, see below).
        loop {
            self.wait_flag.wait();

            match self.state.compare_exchange(NOTIFIED, EMPTY, Acquire, Relaxed) {
                Ok(_) => return,
                Err(PARKED) => (),
                Err(_) => panic!("inconsistent park state"),
            }
        }
    }

    // This implementation doesn't require `unsafe` and `Pin`, but other implementations do.
    pub unsafe fn park_timeout(self: Pin<&Self>, dur: Duration) {
        match self.state.fetch_sub(1, Acquire) {
            NOTIFIED => return,
            EMPTY => (),
            _ => panic!("inconsistent park state"),
        }

        self.wait_flag.wait_timeout(dur);

        // Either a wakeup or a timeout occurred. Wakeups may be spurious, as there can be
        // a race condition when `unpark` is performed between receiving the timeout and
        // resetting the state, resulting in the eventflag being set unnecessarily. `park`
        // is protected against this by looping until the token is actually given, but
        // here we cannot easily tell.

        // Use `swap` to provide acquire ordering.
        match self.state.swap(EMPTY, Acquire) {
            NOTIFIED => (),
            PARKED => (),
            _ => panic!("inconsistent park state"),
        }
    }

    // This implementation doesn't require `Pin`, but other implementations do.
    pub fn unpark(self: Pin<&Self>) {
        let state = self.state.swap(NOTIFIED, Release);

        if state == PARKED {
            self.wait_flag.raise();
        }
    }
}
