// -*- C++ -*-
//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef _LIBCPP_THREAD
#define _LIBCPP_THREAD

/*

    thread synopsis

namespace std
{

class thread
{
public:
    class id;
    typedef pthread_t native_handle_type;

    thread() noexcept;
    template <class F, class ...Args> explicit thread(F&& f, Args&&... args);
    ~thread();

    thread(const thread&) = delete;
    thread(thread&& t) noexcept;

    thread& operator=(const thread&) = delete;
    thread& operator=(thread&& t) noexcept;

    void swap(thread& t) noexcept;

    bool joinable() const noexcept;
    void join();
    void detach();
    id get_id() const noexcept;
    native_handle_type native_handle();

    static unsigned hardware_concurrency() noexcept;
};

void swap(thread& x, thread& y) noexcept;

class thread::id
{
public:
    id() noexcept;
};

bool operator==(thread::id x, thread::id y) noexcept;
bool operator!=(thread::id x, thread::id y) noexcept;             // removed in C++20
bool operator< (thread::id x, thread::id y) noexcept;             // removed in C++20
bool operator<=(thread::id x, thread::id y) noexcept;             // removed in C++20
bool operator> (thread::id x, thread::id y) noexcept;             // removed in C++20
bool operator>=(thread::id x, thread::id y) noexcept;             // removed in C++20
strong_ordering operator<=>(thread::id x, thread::id y) noexcept; // C++20

template<class charT, class traits>
basic_ostream<charT, traits>&
operator<<(basic_ostream<charT, traits>& out, thread::id id);

namespace this_thread
{

thread::id get_id() noexcept;

void yield() noexcept;

template <class Clock, class Duration>
void sleep_until(const chrono::time_point<Clock, Duration>& abs_time);

template <class Rep, class Period>
void sleep_for(const chrono::duration<Rep, Period>& rel_time);

}  // this_thread

}  // std

*/

#include <__assert> // all public C++ headers provide the assertion handler
#include <__config>
#include <__functional/hash.h>
#include <__memory/unique_ptr.h>
#include <__mutex_base>
#include <__thread/poll_with_backoff.h>
#include <__thread/timed_backoff_policy.h>
#include <__threading_support>
#include <__utility/forward.h>
#include <cstddef>
#include <iosfwd>
#include <system_error>
#include <tuple>
#include <type_traits>
#include <version>

// standard-mandated includes

// [thread.syn]
#include <compare>

#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
#  pragma GCC system_header
#endif

_LIBCPP_PUSH_MACROS
#include <__undef_macros>

#ifdef _LIBCPP_HAS_NO_THREADS
# error "<thread> is not supported since libc++ has been configured without support for threads."
#endif

_LIBCPP_BEGIN_NAMESPACE_STD

template <class _Tp> class __thread_specific_ptr;
class _LIBCPP_TYPE_VIS __thread_struct;
class _LIBCPP_HIDDEN __thread_struct_imp;
class __assoc_sub_state;

_LIBCPP_FUNC_VIS __thread_specific_ptr<__thread_struct>& __thread_local_data();

class _LIBCPP_TYPE_VIS __thread_struct
{
    __thread_struct_imp* __p_;

    __thread_struct(const __thread_struct&);
    __thread_struct& operator=(const __thread_struct&);
public:
    __thread_struct();
    ~__thread_struct();

    void notify_all_at_thread_exit(condition_variable*, mutex*);
    void __make_ready_at_thread_exit(__assoc_sub_state*);
};

template <class _Tp>
class __thread_specific_ptr
{
    __libcpp_tls_key __key_;

     // Only __thread_local_data() may construct a __thread_specific_ptr
     // and only with _Tp == __thread_struct.
    static_assert((is_same<_Tp, __thread_struct>::value), "");
    __thread_specific_ptr();
    friend _LIBCPP_FUNC_VIS __thread_specific_ptr<__thread_struct>& __thread_local_data();

    __thread_specific_ptr(const __thread_specific_ptr&);
    __thread_specific_ptr& operator=(const __thread_specific_ptr&);

    _LIBCPP_HIDDEN static void _LIBCPP_TLS_DESTRUCTOR_CC __at_thread_exit(void*);

public:
    typedef _Tp* pointer;

    ~__thread_specific_ptr();

    _LIBCPP_INLINE_VISIBILITY
    pointer get() const {return static_cast<_Tp*>(__libcpp_tls_get(__key_));}
    _LIBCPP_INLINE_VISIBILITY
    pointer operator*() const {return *get();}
    _LIBCPP_INLINE_VISIBILITY
    pointer operator->() const {return get();}
    void set_pointer(pointer __p);
};

template <class _Tp>
void _LIBCPP_TLS_DESTRUCTOR_CC
__thread_specific_ptr<_Tp>::__at_thread_exit(void* __p)
{
    delete static_cast<pointer>(__p);
}

template <class _Tp>
__thread_specific_ptr<_Tp>::__thread_specific_ptr()
{
  int __ec =
      __libcpp_tls_create(&__key_, &__thread_specific_ptr::__at_thread_exit);
  if (__ec)
    __throw_system_error(__ec, "__thread_specific_ptr construction failed");
}

template <class _Tp>
__thread_specific_ptr<_Tp>::~__thread_specific_ptr()
{
    // __thread_specific_ptr is only created with a static storage duration
    // so this destructor is only invoked during program termination. Invoking
    // pthread_key_delete(__key_) may prevent other threads from deleting their
    // thread local data. For this reason we leak the key.
}

template <class _Tp>
void
__thread_specific_ptr<_Tp>::set_pointer(pointer __p)
{
    _LIBCPP_ASSERT(get() == nullptr,
                   "Attempting to overwrite thread local data");
    std::__libcpp_tls_set(__key_, __p);
}

template<>
struct _LIBCPP_TEMPLATE_VIS hash<__thread_id>
    : public __unary_function<__thread_id, size_t>
{
    _LIBCPP_INLINE_VISIBILITY
    size_t operator()(__thread_id __v) const _NOEXCEPT
    {
        return hash<__libcpp_thread_id>()(__v.__id_);
    }
};

template<class _CharT, class _Traits>
_LIBCPP_INLINE_VISIBILITY
basic_ostream<_CharT, _Traits>&
operator<<(basic_ostream<_CharT, _Traits>& __os, __thread_id __id)
{return __os << __id.__id_;}

class _LIBCPP_TYPE_VIS thread
{
    __libcpp_thread_t __t_;

    thread(const thread&);
    thread& operator=(const thread&);
public:
    typedef __thread_id id;
    typedef __libcpp_thread_t native_handle_type;

    _LIBCPP_INLINE_VISIBILITY
    thread() _NOEXCEPT : __t_(_LIBCPP_NULL_THREAD) {}
#ifndef _LIBCPP_CXX03_LANG
    template <class _Fp, class ..._Args,
              class = __enable_if_t<!is_same<__remove_cvref_t<_Fp>, thread>::value> >
        _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
        explicit thread(_Fp&& __f, _Args&&... __args);
#else  // _LIBCPP_CXX03_LANG
    template <class _Fp>
    _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
    explicit thread(_Fp __f);
#endif
    ~thread();

    _LIBCPP_INLINE_VISIBILITY
    thread(thread&& __t) _NOEXCEPT : __t_(__t.__t_) {
        __t.__t_ = _LIBCPP_NULL_THREAD;
    }

    _LIBCPP_INLINE_VISIBILITY
    thread& operator=(thread&& __t) _NOEXCEPT {
        if (!__libcpp_thread_isnull(&__t_))
            terminate();
        __t_ = __t.__t_;
        __t.__t_ = _LIBCPP_NULL_THREAD;
        return *this;
    }

    _LIBCPP_INLINE_VISIBILITY
    void swap(thread& __t) _NOEXCEPT {_VSTD::swap(__t_, __t.__t_);}

    _LIBCPP_INLINE_VISIBILITY
    bool joinable() const _NOEXCEPT {return !__libcpp_thread_isnull(&__t_);}
    void join();
    void detach();
    _LIBCPP_INLINE_VISIBILITY
    id get_id() const _NOEXCEPT {return __libcpp_thread_get_id(&__t_);}
    _LIBCPP_INLINE_VISIBILITY
    native_handle_type native_handle() _NOEXCEPT {return __t_;}

    static unsigned hardware_concurrency() _NOEXCEPT;
};

#ifndef _LIBCPP_CXX03_LANG

template <class _TSp, class _Fp, class ..._Args, size_t ..._Indices>
inline _LIBCPP_INLINE_VISIBILITY
void
__thread_execute(tuple<_TSp, _Fp, _Args...>& __t, __tuple_indices<_Indices...>)
{
    _VSTD::__invoke(_VSTD::move(_VSTD::get<1>(__t)), _VSTD::move(_VSTD::get<_Indices>(__t))...);
}

template <class _Fp>
_LIBCPP_INLINE_VISIBILITY
void* __thread_proxy(void* __vp)
{
    // _Fp = tuple< unique_ptr<__thread_struct>, Functor, Args...>
    unique_ptr<_Fp> __p(static_cast<_Fp*>(__vp));
    __thread_local_data().set_pointer(_VSTD::get<0>(*__p.get()).release());
    typedef typename __make_tuple_indices<tuple_size<_Fp>::value, 2>::type _Index;
    _VSTD::__thread_execute(*__p.get(), _Index());
    return nullptr;
}

template <class _Fp, class ..._Args,
          class
         >
thread::thread(_Fp&& __f, _Args&&... __args)
{
    typedef unique_ptr<__thread_struct> _TSPtr;
    _TSPtr __tsp(new __thread_struct);
    typedef tuple<_TSPtr, typename decay<_Fp>::type, typename decay<_Args>::type...> _Gp;
    unique_ptr<_Gp> __p(
            new _Gp(_VSTD::move(__tsp),
                    _VSTD::forward<_Fp>(__f),
                    _VSTD::forward<_Args>(__args)...));
    int __ec = _VSTD::__libcpp_thread_create(&__t_, &__thread_proxy<_Gp>, __p.get());
    if (__ec == 0)
        __p.release();
    else
        __throw_system_error(__ec, "thread constructor failed");
}

#else  // _LIBCPP_CXX03_LANG

template <class _Fp>
struct __thread_invoke_pair {
    // This type is used to pass memory for thread local storage and a functor
    // to a newly created thread because std::pair doesn't work with
    // std::unique_ptr in C++03.
    __thread_invoke_pair(_Fp& __f) : __tsp_(new __thread_struct), __fn_(__f) {}
    unique_ptr<__thread_struct> __tsp_;
    _Fp __fn_;
};

template <class _Fp>
_LIBCPP_HIDE_FROM_ABI void* __thread_proxy_cxx03(void* __vp)
{
    unique_ptr<_Fp> __p(static_cast<_Fp*>(__vp));
    __thread_local_data().set_pointer(__p->__tsp_.release());
    (__p->__fn_)();
    return nullptr;
}

template <class _Fp>
thread::thread(_Fp __f)
{

    typedef __thread_invoke_pair<_Fp> _InvokePair;
    typedef unique_ptr<_InvokePair> _PairPtr;
    _PairPtr __pp(new _InvokePair(__f));
    int __ec = _VSTD::__libcpp_thread_create(&__t_, &__thread_proxy_cxx03<_InvokePair>, __pp.get());
    if (__ec == 0)
        __pp.release();
    else
        __throw_system_error(__ec, "thread constructor failed");
}

#endif // _LIBCPP_CXX03_LANG

inline _LIBCPP_INLINE_VISIBILITY
void swap(thread& __x, thread& __y) _NOEXCEPT {__x.swap(__y);}

namespace this_thread
{

_LIBCPP_FUNC_VIS void sleep_for(const chrono::nanoseconds& __ns);

template <class _Rep, class _Period>
_LIBCPP_HIDE_FROM_ABI void
sleep_for(const chrono::duration<_Rep, _Period>& __d)
{
    if (__d > chrono::duration<_Rep, _Period>::zero())
    {
        // The standard guarantees a 64bit signed integer resolution for nanoseconds,
        // so use INT64_MAX / 1e9 as cut-off point. Use a constant to avoid <climits>
        // and issues with long double folding on PowerPC with GCC.
        _LIBCPP_CONSTEXPR chrono::duration<long double> _Max =
            chrono::duration<long double>(9223372036.0L);
        chrono::nanoseconds __ns;
        if (__d < _Max)
        {
            __ns = chrono::duration_cast<chrono::nanoseconds>(__d);
            if (__ns < __d)
                ++__ns;
        }
        else
            __ns = chrono::nanoseconds::max();
        this_thread::sleep_for(__ns);
    }
}

template <class _Clock, class _Duration>
_LIBCPP_HIDE_FROM_ABI void
sleep_until(const chrono::time_point<_Clock, _Duration>& __t)
{
    mutex __mut;
    condition_variable __cv;
    unique_lock<mutex> __lk(__mut);
    while (_Clock::now() < __t)
        __cv.wait_until(__lk, __t);
}

template <class _Duration>
inline _LIBCPP_INLINE_VISIBILITY
void
sleep_until(const chrono::time_point<chrono::steady_clock, _Duration>& __t)
{
    this_thread::sleep_for(__t - chrono::steady_clock::now());
}

inline _LIBCPP_INLINE_VISIBILITY
void yield() _NOEXCEPT {__libcpp_thread_yield();}

} // namespace this_thread

_LIBCPP_END_NAMESPACE_STD

_LIBCPP_POP_MACROS

#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 17
#  include <chrono>
#endif

#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
#  include <functional>
#endif

#endif // _LIBCPP_THREAD
