use crate::num::NonZero;
use crate::sync::atomic::{Atomic, Ordering};

/// A unique identifier for a running thread.
///
/// A `ThreadId` is an opaque object that uniquely identifies each thread
/// created during the lifetime of a process. `ThreadId`s are guaranteed not to
/// be reused, even when a thread terminates. `ThreadId`s are under the control
/// of Rust's standard library and there may not be any relationship between
/// `ThreadId` and the underlying platform's notion of a thread identifier --
/// the two concepts cannot, therefore, be used interchangeably. A `ThreadId`
/// can be retrieved from the [`id`] method on a [`Thread`].
///
/// # Examples
///
/// ```
/// use std::thread;
///
/// let other_thread = thread::spawn(|| {
///     thread::current().id()
/// });
///
/// let other_thread_id = other_thread.join().unwrap();
/// assert!(thread::current().id() != other_thread_id);
/// ```
///
/// [`Thread`]: super::Thread
/// [`id`]: super::Thread::id
#[stable(feature = "thread_id", since = "1.19.0")]
#[derive(Eq, PartialEq, Clone, Copy, Hash, Debug)]
pub struct ThreadId(NonZero<u64>);

impl ThreadId {
    // Generate a new unique thread ID.
    pub(crate) fn new() -> ThreadId {
        #[cold]
        fn exhausted() -> ! {
            panic!("failed to generate unique thread ID: bitspace exhausted")
        }

        cfg_select! {
            target_has_atomic = "64" => {
                use crate::sync::atomic::AtomicU64;

                static COUNTER: Atomic<u64> = AtomicU64::new(0);

                let mut last = COUNTER.load(Ordering::Relaxed);
                loop {
                    let Some(id) = last.checked_add(1) else {
                        exhausted();
                    };

                    match COUNTER.compare_exchange_weak(last, id, Ordering::Relaxed, Ordering::Relaxed) {
                        Ok(_) => return ThreadId(NonZero::new(id).unwrap()),
                        Err(id) => last = id,
                    }
                }
            }
            _ => {
                use crate::cell::SyncUnsafeCell;
                use crate::hint::spin_loop;
                use crate::sync::atomic::AtomicBool;
                use crate::thread::yield_now;

                // If we don't have a 64-bit atomic we use a small spinlock. We don't use Mutex
                // here as we might be trying to get the current thread id in the global allocator,
                // and on some platforms Mutex requires allocation.
                static COUNTER_LOCKED: Atomic<bool> = AtomicBool::new(false);
                static COUNTER: SyncUnsafeCell<u64> = SyncUnsafeCell::new(0);

                // Acquire lock.
                let mut spin = 0;
                // Miri doesn't like it when we yield here as it interferes with deterministically
                // scheduling threads, so avoid `compare_exchange_weak` to avoid spurious yields.
                while COUNTER_LOCKED.swap(true, Ordering::Acquire) {
                    if spin <= 3 {
                        for _ in 0..(1 << spin) {
                            spin_loop();
                        }
                    } else {
                        yield_now();
                    }
                    spin += 1;
                }
                // This was `false` before the swap, so we got the lock.

                // SAFETY: we have an exclusive lock on the counter.
                unsafe {
                    if let Some(id) = (*COUNTER.get()).checked_add(1) {
                        *COUNTER.get() = id;
                        COUNTER_LOCKED.store(false, Ordering::Release);
                        ThreadId(NonZero::new(id).unwrap())
                    } else {
                        COUNTER_LOCKED.store(false, Ordering::Release);
                        exhausted()
                    }
                }
            }
        }
    }

    #[cfg(any(not(target_thread_local), target_has_atomic = "64"))]
    pub(super) fn from_u64(v: u64) -> Option<ThreadId> {
        NonZero::new(v).map(ThreadId)
    }

    /// This returns a numeric identifier for the thread identified by this
    /// `ThreadId`.
    ///
    /// As noted in the documentation for the type itself, it is essentially an
    /// opaque ID, but is guaranteed to be unique for each thread. The returned
    /// value is entirely opaque -- only equality testing is stable. Note that
    /// it is not guaranteed which values new threads will return, and this may
    /// change across Rust versions.
    #[must_use]
    #[unstable(feature = "thread_id_value", issue = "67939")]
    pub fn as_u64(&self) -> NonZero<u64> {
        self.0
    }
}
