// -*- C++ -*-
//===--------------------------- thread -----------------------------------===//
//
// 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

#define __STDCPP_THREADS__ __cplusplus

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;
bool operator< (thread::id x, thread::id y) noexcept;
bool operator<=(thread::id x, thread::id y) noexcept;
bool operator> (thread::id x, thread::id y) noexcept;
bool operator>=(thread::id x, thread::id y) noexcept;

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 <__config>
#include <iosfwd>
#include <__functional_base>
#include <type_traits>
#include <cstddef>
#include <functional>
#include <memory>
#include <system_error>
#include <chrono>
#include <__mutex_base>
#ifndef _LIBCPP_CXX03_LANG
#include <tuple>
#endif
#include <__threading_support>
#include <__debug>

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

_LIBCPP_PUSH_MACROS
#include <__undef_macros>

#define __STDCPP_THREADS__ __cplusplus

#ifdef _LIBCPP_HAS_NO_THREADS
#error <thread> is not supported on this single threaded system
#else // !_LIBCPP_HAS_NO_THREADS

_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");
    __libcpp_tls_set(__key_, __p);
}

class _LIBCPP_TYPE_VIS thread;
class _LIBCPP_TYPE_VIS __thread_id;

namespace this_thread
{

_LIBCPP_INLINE_VISIBILITY __thread_id get_id() _NOEXCEPT;

}  // this_thread

template<> struct hash<__thread_id>;

class _LIBCPP_TEMPLATE_VIS __thread_id
{
    // FIXME: pthread_t is a pointer on Darwin but a long on Linux.
    // NULL is the no-thread value on Darwin.  Someone needs to check
    // on other platforms.  We assume 0 works everywhere for now.
    __libcpp_thread_id __id_;

public:
    _LIBCPP_INLINE_VISIBILITY
    __thread_id() _NOEXCEPT : __id_(0) {}

    friend _LIBCPP_INLINE_VISIBILITY
        bool operator==(__thread_id __x, __thread_id __y) _NOEXCEPT
        {return __libcpp_thread_id_equal(__x.__id_, __y.__id_);}
    friend _LIBCPP_INLINE_VISIBILITY
        bool operator!=(__thread_id __x, __thread_id __y) _NOEXCEPT
        {return !(__x == __y);}
    friend _LIBCPP_INLINE_VISIBILITY
        bool operator< (__thread_id __x, __thread_id __y) _NOEXCEPT
        {return  __libcpp_thread_id_less(__x.__id_, __y.__id_);}
    friend _LIBCPP_INLINE_VISIBILITY
        bool operator<=(__thread_id __x, __thread_id __y) _NOEXCEPT
        {return !(__y < __x);}
    friend _LIBCPP_INLINE_VISIBILITY
        bool operator> (__thread_id __x, __thread_id __y) _NOEXCEPT
        {return   __y < __x ;}
    friend _LIBCPP_INLINE_VISIBILITY
        bool operator>=(__thread_id __x, __thread_id __y) _NOEXCEPT
        {return !(__x < __y);}

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

private:
    _LIBCPP_INLINE_VISIBILITY
    __thread_id(__libcpp_thread_id __id) : __id_(__id) {}

    friend __thread_id this_thread::get_id() _NOEXCEPT;
    friend class _LIBCPP_TYPE_VIS thread;
    friend struct _LIBCPP_TEMPLATE_VIS hash<__thread_id>;
};

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_);
    }
};

namespace this_thread
{

inline _LIBCPP_INLINE_VISIBILITY
__thread_id
get_id() _NOEXCEPT
{
    return __libcpp_thread_get_current_id();
}

}  // this_thread

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 = typename enable_if
              <
                   !is_same<typename __uncvref<_Fp>::type, thread>::value
              >::type
             >
        _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();

#ifndef _LIBCPP_CXX03_LANG
    _LIBCPP_INLINE_VISIBILITY
    thread(thread&& __t) _NOEXCEPT : __t_(__t.__t_) {__t.__t_ = _LIBCPP_NULL_THREAD;}
    _LIBCPP_INLINE_VISIBILITY
    thread& operator=(thread&& __t) _NOEXCEPT;
#endif  // _LIBCPP_CXX03_LANG

    _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...>)
{
    __invoke(_VSTD::move(_VSTD::get<1>(__t)), _VSTD::move(_VSTD::get<_Indices>(__t))...);
}

template <class _Fp>
void* __thread_proxy(void* __vp)
{
    // _Fp = std::tuple< unique_ptr<__thread_struct>, Functor, Args...>
    std::unique_ptr<_Fp> __p(static_cast<_Fp*>(__vp));
    __thread_local_data().set_pointer(_VSTD::get<0>(*__p).release());
    typedef typename __make_tuple_indices<tuple_size<_Fp>::value, 2>::type _Index;
    __thread_execute(*__p, _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;
    _VSTD::unique_ptr<_Gp> __p(
            new _Gp(std::move(__tsp),
                    __decay_copy(_VSTD::forward<_Fp>(__f)),
                    __decay_copy(_VSTD::forward<_Args>(__args))...));
    int __ec = __libcpp_thread_create(&__t_, &__thread_proxy<_Gp>, __p.get());
    if (__ec == 0)
        __p.release();
    else
        __throw_system_error(__ec, "thread constructor failed");
}

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

#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>
void* __thread_proxy_cxx03(void* __vp)
{
    std::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 std::unique_ptr<_InvokePair> _PairPtr;
    _PairPtr __pp(new _InvokePair(__f));
    int __ec = __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>
void
sleep_for(const chrono::duration<_Rep, _Period>& __d)
{
    using namespace chrono;
    if (__d > duration<_Rep, _Period>::zero())
    {
#if defined(_LIBCPP_COMPILER_GCC) && (__powerpc__ || __POWERPC__)
    //  GCC's long double const folding is incomplete for IBM128 long doubles.
        _LIBCPP_CONSTEXPR duration<long double> _Max = nanoseconds::max();
#else
        _LIBCPP_CONSTEXPR duration<long double> _Max = duration<long double>(ULLONG_MAX/1000000000ULL) ;
#endif
        nanoseconds __ns;
        if (__d < _Max)
        {
            __ns = duration_cast<nanoseconds>(__d);
            if (__ns < __d)
                ++__ns;
        }
        else
            __ns = nanoseconds::max();
        sleep_for(__ns);
    }
}

template <class _Clock, class _Duration>
void
sleep_until(const chrono::time_point<_Clock, _Duration>& __t)
{
    using namespace chrono;
    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)
{
    using namespace chrono;
    sleep_for(__t - steady_clock::now());
}

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

}  // this_thread

_LIBCPP_END_NAMESPACE_STD

#endif // !_LIBCPP_HAS_NO_THREADS

_LIBCPP_POP_MACROS

#endif  // _LIBCPP_THREAD
