xref: /llvm-project-15.0.7/libcxx/include/thread (revision ea48b6dc)
13e519524SHoward Hinnant// -*- C++ -*-
23e519524SHoward Hinnant//===--------------------------- thread -----------------------------------===//
33e519524SHoward Hinnant//
45b08a8a4SHoward Hinnant//                     The LLVM Compiler Infrastructure
53e519524SHoward Hinnant//
6412dbebeSHoward Hinnant// This file is dual licensed under the MIT and the University of Illinois Open
7412dbebeSHoward Hinnant// Source Licenses. See LICENSE.TXT for details.
83e519524SHoward Hinnant//
93e519524SHoward Hinnant//===----------------------------------------------------------------------===//
103e519524SHoward Hinnant
113e519524SHoward Hinnant#ifndef _LIBCPP_THREAD
123e519524SHoward Hinnant#define _LIBCPP_THREAD
133e519524SHoward Hinnant
143e519524SHoward Hinnant/*
153e519524SHoward Hinnant
163e519524SHoward Hinnant    thread synopsis
173e519524SHoward Hinnant
18e8e7af24SHoward Hinnant#define __STDCPP_THREADS__ __cplusplus
193e519524SHoward Hinnant
203e519524SHoward Hinnantnamespace std
213e519524SHoward Hinnant{
223e519524SHoward Hinnant
233e519524SHoward Hinnantclass thread
243e519524SHoward Hinnant{
253e519524SHoward Hinnantpublic:
263e519524SHoward Hinnant    class id;
273e519524SHoward Hinnant    typedef pthread_t native_handle_type;
283e519524SHoward Hinnant
2936101a5bSHoward Hinnant    thread() noexcept;
303e519524SHoward Hinnant    template <class F, class ...Args> explicit thread(F&& f, Args&&... args);
313e519524SHoward Hinnant    ~thread();
323e519524SHoward Hinnant
333e519524SHoward Hinnant    thread(const thread&) = delete;
3436101a5bSHoward Hinnant    thread(thread&& t) noexcept;
353e519524SHoward Hinnant
363e519524SHoward Hinnant    thread& operator=(const thread&) = delete;
3736101a5bSHoward Hinnant    thread& operator=(thread&& t) noexcept;
383e519524SHoward Hinnant
3936101a5bSHoward Hinnant    void swap(thread& t) noexcept;
403e519524SHoward Hinnant
4136101a5bSHoward Hinnant    bool joinable() const noexcept;
423e519524SHoward Hinnant    void join();
433e519524SHoward Hinnant    void detach();
4436101a5bSHoward Hinnant    id get_id() const noexcept;
453e519524SHoward Hinnant    native_handle_type native_handle();
463e519524SHoward Hinnant
4736101a5bSHoward Hinnant    static unsigned hardware_concurrency() noexcept;
483e519524SHoward Hinnant};
493e519524SHoward Hinnant
5036101a5bSHoward Hinnantvoid swap(thread& x, thread& y) noexcept;
513e519524SHoward Hinnant
523e519524SHoward Hinnantclass thread::id
533e519524SHoward Hinnant{
543e519524SHoward Hinnantpublic:
5536101a5bSHoward Hinnant    id() noexcept;
563e519524SHoward Hinnant};
573e519524SHoward Hinnant
5836101a5bSHoward Hinnantbool operator==(thread::id x, thread::id y) noexcept;
5936101a5bSHoward Hinnantbool operator!=(thread::id x, thread::id y) noexcept;
6036101a5bSHoward Hinnantbool operator< (thread::id x, thread::id y) noexcept;
6136101a5bSHoward Hinnantbool operator<=(thread::id x, thread::id y) noexcept;
6236101a5bSHoward Hinnantbool operator> (thread::id x, thread::id y) noexcept;
6336101a5bSHoward Hinnantbool operator>=(thread::id x, thread::id y) noexcept;
643e519524SHoward Hinnant
653e519524SHoward Hinnanttemplate<class charT, class traits>
663e519524SHoward Hinnantbasic_ostream<charT, traits>&
673e519524SHoward Hinnantoperator<<(basic_ostream<charT, traits>& out, thread::id id);
683e519524SHoward Hinnant
693e519524SHoward Hinnantnamespace this_thread
703e519524SHoward Hinnant{
713e519524SHoward Hinnant
7236101a5bSHoward Hinnantthread::id get_id() noexcept;
733e519524SHoward Hinnant
7436101a5bSHoward Hinnantvoid yield() noexcept;
753e519524SHoward Hinnant
763e519524SHoward Hinnanttemplate <class Clock, class Duration>
773e519524SHoward Hinnantvoid sleep_until(const chrono::time_point<Clock, Duration>& abs_time);
783e519524SHoward Hinnant
793e519524SHoward Hinnanttemplate <class Rep, class Period>
803e519524SHoward Hinnantvoid sleep_for(const chrono::duration<Rep, Period>& rel_time);
813e519524SHoward Hinnant
823e519524SHoward Hinnant}  // this_thread
833e519524SHoward Hinnant
843e519524SHoward Hinnant}  // std
853e519524SHoward Hinnant
863e519524SHoward Hinnant*/
873e519524SHoward Hinnant
883e519524SHoward Hinnant#include <__config>
893e519524SHoward Hinnant#include <iosfwd>
903e519524SHoward Hinnant#include <__functional_base>
913e519524SHoward Hinnant#include <type_traits>
923e519524SHoward Hinnant#include <cstddef>
933e519524SHoward Hinnant#include <functional>
943e519524SHoward Hinnant#include <memory>
953e519524SHoward Hinnant#include <system_error>
963e519524SHoward Hinnant#include <chrono>
973e519524SHoward Hinnant#include <__mutex_base>
988df61ea8SHoward Hinnant#ifndef _LIBCPP_HAS_NO_VARIADICS
998df61ea8SHoward Hinnant#include <tuple>
1008df61ea8SHoward Hinnant#endif
1013e519524SHoward Hinnant#include <pthread.h>
1023e519524SHoward Hinnant
103073458b1SHoward Hinnant#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
1043e519524SHoward Hinnant#pragma GCC system_header
105073458b1SHoward Hinnant#endif
1063e519524SHoward Hinnant
107e8e7af24SHoward Hinnant#define __STDCPP_THREADS__ __cplusplus
1083e519524SHoward Hinnant
1093e519524SHoward Hinnant_LIBCPP_BEGIN_NAMESPACE_STD
1103e519524SHoward Hinnant
111167fd108SHoward Hinnanttemplate <class _Tp>
112167fd108SHoward Hinnantclass __thread_specific_ptr
113167fd108SHoward Hinnant{
114167fd108SHoward Hinnant    pthread_key_t __key_;
115167fd108SHoward Hinnant
116167fd108SHoward Hinnant    __thread_specific_ptr(const __thread_specific_ptr&);
117167fd108SHoward Hinnant    __thread_specific_ptr& operator=(const __thread_specific_ptr&);
118167fd108SHoward Hinnant
119167fd108SHoward Hinnant    static void __at_thread_exit(void*);
120167fd108SHoward Hinnantpublic:
121167fd108SHoward Hinnant    typedef _Tp* pointer;
122167fd108SHoward Hinnant
123167fd108SHoward Hinnant    __thread_specific_ptr();
124167fd108SHoward Hinnant    ~__thread_specific_ptr();
125167fd108SHoward Hinnant
126e0601335SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
127167fd108SHoward Hinnant    pointer get() const {return static_cast<_Tp*>(pthread_getspecific(__key_));}
128e0601335SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
129167fd108SHoward Hinnant    pointer operator*() const {return *get();}
130e0601335SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
131167fd108SHoward Hinnant    pointer operator->() const {return get();}
132167fd108SHoward Hinnant    pointer release();
133167fd108SHoward Hinnant    void reset(pointer __p = nullptr);
134167fd108SHoward Hinnant};
135167fd108SHoward Hinnant
136167fd108SHoward Hinnanttemplate <class _Tp>
137167fd108SHoward Hinnantvoid
138167fd108SHoward Hinnant__thread_specific_ptr<_Tp>::__at_thread_exit(void* __p)
139167fd108SHoward Hinnant{
140167fd108SHoward Hinnant    delete static_cast<pointer>(__p);
141167fd108SHoward Hinnant}
142167fd108SHoward Hinnant
143167fd108SHoward Hinnanttemplate <class _Tp>
144167fd108SHoward Hinnant__thread_specific_ptr<_Tp>::__thread_specific_ptr()
145167fd108SHoward Hinnant{
146167fd108SHoward Hinnant    int __ec = pthread_key_create(&__key_, &__thread_specific_ptr::__at_thread_exit);
147a4d35ce2SHoward Hinnant#ifndef _LIBCPP_NO_EXCEPTIONS
148167fd108SHoward Hinnant    if (__ec)
149167fd108SHoward Hinnant        throw system_error(error_code(__ec, system_category()),
150167fd108SHoward Hinnant                           "__thread_specific_ptr construction failed");
151a4d35ce2SHoward Hinnant#endif
152167fd108SHoward Hinnant}
153167fd108SHoward Hinnant
154167fd108SHoward Hinnanttemplate <class _Tp>
155167fd108SHoward Hinnant__thread_specific_ptr<_Tp>::~__thread_specific_ptr()
156167fd108SHoward Hinnant{
157167fd108SHoward Hinnant    pthread_key_delete(__key_);
158167fd108SHoward Hinnant}
159167fd108SHoward Hinnant
160167fd108SHoward Hinnanttemplate <class _Tp>
161167fd108SHoward Hinnanttypename __thread_specific_ptr<_Tp>::pointer
162167fd108SHoward Hinnant__thread_specific_ptr<_Tp>::release()
163167fd108SHoward Hinnant{
164167fd108SHoward Hinnant    pointer __p = get();
165167fd108SHoward Hinnant    pthread_setspecific(__key_, 0);
166167fd108SHoward Hinnant    return __p;
167167fd108SHoward Hinnant}
168167fd108SHoward Hinnant
169167fd108SHoward Hinnanttemplate <class _Tp>
170167fd108SHoward Hinnantvoid
171167fd108SHoward Hinnant__thread_specific_ptr<_Tp>::reset(pointer __p)
172167fd108SHoward Hinnant{
173167fd108SHoward Hinnant    pointer __p_old = get();
174167fd108SHoward Hinnant    pthread_setspecific(__key_, __p);
175167fd108SHoward Hinnant    delete __p_old;
176167fd108SHoward Hinnant}
177167fd108SHoward Hinnant
1786e41256fSHoward Hinnantclass _LIBCPP_TYPE_VIS thread;
1796e41256fSHoward Hinnantclass _LIBCPP_TYPE_VIS __thread_id;
1803e519524SHoward Hinnant
1813e519524SHoward Hinnantnamespace this_thread
1823e519524SHoward Hinnant{
1833e519524SHoward Hinnant
184aeb85680SHoward Hinnant_LIBCPP_INLINE_VISIBILITY __thread_id get_id() _NOEXCEPT;
1853e519524SHoward Hinnant
1863e519524SHoward Hinnant}  // this_thread
1873e519524SHoward Hinnant
1886e41256fSHoward Hinnantclass _LIBCPP_TYPE_VIS __thread_id;
1896e41256fSHoward Hinnanttemplate<> struct _LIBCPP_TYPE_VIS hash<__thread_id>;
190f3d14a65SHoward Hinnant
1916e41256fSHoward Hinnantclass _LIBCPP_TYPE_VIS __thread_id
1923e519524SHoward Hinnant{
193128ba719SHoward Hinnant    // FIXME: pthread_t is a pointer on Darwin but a long on Linux.
194128ba719SHoward Hinnant    // NULL is the no-thread value on Darwin.  Someone needs to check
195128ba719SHoward Hinnant    // on other platforms.  We assume 0 works everywhere for now.
1963e519524SHoward Hinnant    pthread_t __id_;
1973e519524SHoward Hinnant
1983e519524SHoward Hinnantpublic:
199e0601335SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
20036101a5bSHoward Hinnant    __thread_id() _NOEXCEPT : __id_(0) {}
2013e519524SHoward Hinnant
202e0601335SHoward Hinnant    friend _LIBCPP_INLINE_VISIBILITY
20336101a5bSHoward Hinnant        bool operator==(__thread_id __x, __thread_id __y) _NOEXCEPT
2043e519524SHoward Hinnant        {return __x.__id_ == __y.__id_;}
205e0601335SHoward Hinnant    friend _LIBCPP_INLINE_VISIBILITY
20636101a5bSHoward Hinnant        bool operator!=(__thread_id __x, __thread_id __y) _NOEXCEPT
2073e519524SHoward Hinnant        {return !(__x == __y);}
208e0601335SHoward Hinnant    friend _LIBCPP_INLINE_VISIBILITY
20936101a5bSHoward Hinnant        bool operator< (__thread_id __x, __thread_id __y) _NOEXCEPT
2103e519524SHoward Hinnant        {return __x.__id_ < __y.__id_;}
211e0601335SHoward Hinnant    friend _LIBCPP_INLINE_VISIBILITY
21236101a5bSHoward Hinnant        bool operator<=(__thread_id __x, __thread_id __y) _NOEXCEPT
2133e519524SHoward Hinnant        {return !(__y < __x);}
214e0601335SHoward Hinnant    friend _LIBCPP_INLINE_VISIBILITY
21536101a5bSHoward Hinnant        bool operator> (__thread_id __x, __thread_id __y) _NOEXCEPT
2163e519524SHoward Hinnant        {return   __y < __x ;}
217e0601335SHoward Hinnant    friend _LIBCPP_INLINE_VISIBILITY
21836101a5bSHoward Hinnant        bool operator>=(__thread_id __x, __thread_id __y) _NOEXCEPT
2193e519524SHoward Hinnant        {return !(__x < __y);}
2203e519524SHoward Hinnant
2213e519524SHoward Hinnant    template<class _CharT, class _Traits>
2223e519524SHoward Hinnant    friend
223e0601335SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
2243e519524SHoward Hinnant    basic_ostream<_CharT, _Traits>&
2253e519524SHoward Hinnant    operator<<(basic_ostream<_CharT, _Traits>& __os, __thread_id __id)
2263e519524SHoward Hinnant        {return __os << __id.__id_;}
2273e519524SHoward Hinnant
2283e519524SHoward Hinnantprivate:
229e0601335SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
2303e519524SHoward Hinnant    __thread_id(pthread_t __id) : __id_(__id) {}
2313e519524SHoward Hinnant
232e4b2a743SHoward Hinnant    friend __thread_id this_thread::get_id() _NOEXCEPT;
2336e41256fSHoward Hinnant    friend class _LIBCPP_TYPE_VIS thread;
2346e41256fSHoward Hinnant    friend struct _LIBCPP_TYPE_VIS hash<__thread_id>;
2353e519524SHoward Hinnant};
2363e519524SHoward Hinnant
2373e519524SHoward Hinnanttemplate<>
2386e41256fSHoward Hinnantstruct _LIBCPP_TYPE_VIS hash<__thread_id>
2393e519524SHoward Hinnant    : public unary_function<__thread_id, size_t>
2403e519524SHoward Hinnant{
241e0601335SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
2423e519524SHoward Hinnant    size_t operator()(__thread_id __v) const
2433e519524SHoward Hinnant    {
244f3d14a65SHoward Hinnant        return hash<pthread_t>()(__v.__id_);
2453e519524SHoward Hinnant    }
2463e519524SHoward Hinnant};
2473e519524SHoward Hinnant
2483e519524SHoward Hinnantnamespace this_thread
2493e519524SHoward Hinnant{
2503e519524SHoward Hinnant
251e0601335SHoward Hinnantinline _LIBCPP_INLINE_VISIBILITY
2523e519524SHoward Hinnant__thread_id
25336101a5bSHoward Hinnantget_id() _NOEXCEPT
2543e519524SHoward Hinnant{
2553e519524SHoward Hinnant    return pthread_self();
2563e519524SHoward Hinnant}
2573e519524SHoward Hinnant
2583e519524SHoward Hinnant}  // this_thread
2593e519524SHoward Hinnant
2606e41256fSHoward Hinnantclass _LIBCPP_TYPE_VIS thread
2613e519524SHoward Hinnant{
2623e519524SHoward Hinnant    pthread_t __t_;
2633e519524SHoward Hinnant
264eb269257SHoward Hinnant    thread(const thread&);
265eb269257SHoward Hinnant    thread& operator=(const thread&);
2663e519524SHoward Hinnantpublic:
2673e519524SHoward Hinnant    typedef __thread_id id;
2683e519524SHoward Hinnant    typedef pthread_t native_handle_type;
2693e519524SHoward Hinnant
270e0601335SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
27136101a5bSHoward Hinnant    thread() _NOEXCEPT : __t_(0) {}
2723e519524SHoward Hinnant#ifndef _LIBCPP_HAS_NO_VARIADICS
273c003db1fSHoward Hinnant    template <class _Fp, class ..._Args,
2743e519524SHoward Hinnant              class = typename enable_if
2753e519524SHoward Hinnant              <
276c003db1fSHoward Hinnant                   !is_same<typename decay<_Fp>::type, thread>::value
2773e519524SHoward Hinnant              >::type
2783e519524SHoward Hinnant             >
279c003db1fSHoward Hinnant        explicit thread(_Fp&& __f, _Args&&... __args);
280b3371f6fSHoward Hinnant#else  // _LIBCPP_HAS_NO_VARIADICS
281c003db1fSHoward Hinnant    template <class _Fp> explicit thread(_Fp __f);
2823e519524SHoward Hinnant#endif
2833e519524SHoward Hinnant    ~thread();
2843e519524SHoward Hinnant
2857609c9b6SHoward Hinnant#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
286e0601335SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
28736101a5bSHoward Hinnant    thread(thread&& __t) _NOEXCEPT : __t_(__t.__t_) {__t.__t_ = 0;}
28836101a5bSHoward Hinnant    thread& operator=(thread&& __t) _NOEXCEPT;
2897609c9b6SHoward Hinnant#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
2903e519524SHoward Hinnant
291e0601335SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
29236101a5bSHoward Hinnant    void swap(thread& __t) _NOEXCEPT {_VSTD::swap(__t_, __t.__t_);}
2933e519524SHoward Hinnant
294e0601335SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
29536101a5bSHoward Hinnant    bool joinable() const _NOEXCEPT {return __t_ != 0;}
2963e519524SHoward Hinnant    void join();
2973e519524SHoward Hinnant    void detach();
298e0601335SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
29936101a5bSHoward Hinnant    id get_id() const _NOEXCEPT {return __t_;}
300e0601335SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
30136101a5bSHoward Hinnant    native_handle_type native_handle() _NOEXCEPT {return __t_;}
3023e519524SHoward Hinnant
30336101a5bSHoward Hinnant    static unsigned hardware_concurrency() _NOEXCEPT;
3043e519524SHoward Hinnant};
3053e519524SHoward Hinnant
306167fd108SHoward Hinnantclass __assoc_sub_state;
307167fd108SHoward Hinnant
308c950e77dSHoward Hinnantclass _LIBCPP_HIDDEN __thread_struct_imp;
309167fd108SHoward Hinnant
310167fd108SHoward Hinnantclass __thread_struct
311167fd108SHoward Hinnant{
312167fd108SHoward Hinnant    __thread_struct_imp* __p_;
313167fd108SHoward Hinnant
314167fd108SHoward Hinnant    __thread_struct(const __thread_struct&);
315167fd108SHoward Hinnant    __thread_struct& operator=(const __thread_struct&);
316167fd108SHoward Hinnantpublic:
317167fd108SHoward Hinnant    __thread_struct();
318167fd108SHoward Hinnant    ~__thread_struct();
319167fd108SHoward Hinnant
320b77c0c03SHoward Hinnant    void notify_all_at_thread_exit(condition_variable*, mutex*);
321167fd108SHoward Hinnant    void __make_ready_at_thread_exit(__assoc_sub_state*);
322167fd108SHoward Hinnant};
323167fd108SHoward Hinnant
32410e4a48aSHoward Hinnant__thread_specific_ptr<__thread_struct>& __thread_local_data();
325167fd108SHoward Hinnant
3268df61ea8SHoward Hinnant#ifndef _LIBCPP_HAS_NO_VARIADICS
3278df61ea8SHoward Hinnant
328c003db1fSHoward Hinnanttemplate <class _Fp, class ..._Args, size_t ..._Indices>
3298df61ea8SHoward Hinnantinline _LIBCPP_INLINE_VISIBILITY
3308df61ea8SHoward Hinnantvoid
331*ea48b6dcSHoward Hinnant__thread_execute(tuple<_Fp, _Args...>& __t, __tuple_indices<_Indices...>)
3328df61ea8SHoward Hinnant{
333ce48a113SHoward Hinnant    __invoke(_VSTD::move(_VSTD::get<0>(__t)), _VSTD::move(_VSTD::get<_Indices>(__t))...);
3348df61ea8SHoward Hinnant}
3358df61ea8SHoward Hinnant
336c003db1fSHoward Hinnanttemplate <class _Fp>
3378df61ea8SHoward Hinnantvoid*
3388df61ea8SHoward Hinnant__thread_proxy(void* __vp)
3398df61ea8SHoward Hinnant{
3408df61ea8SHoward Hinnant    __thread_local_data().reset(new __thread_struct);
341c003db1fSHoward Hinnant    std::unique_ptr<_Fp> __p(static_cast<_Fp*>(__vp));
342c003db1fSHoward Hinnant    typedef typename __make_tuple_indices<tuple_size<_Fp>::value, 1>::type _Index;
343*ea48b6dcSHoward Hinnant    __thread_execute(*__p, _Index());
3448df61ea8SHoward Hinnant    return nullptr;
3458df61ea8SHoward Hinnant}
3468df61ea8SHoward Hinnant
347c003db1fSHoward Hinnanttemplate <class _Fp, class ..._Args,
3488df61ea8SHoward Hinnant          class
3498df61ea8SHoward Hinnant         >
350c003db1fSHoward Hinnantthread::thread(_Fp&& __f, _Args&&... __args)
3518df61ea8SHoward Hinnant{
352c003db1fSHoward Hinnant    typedef tuple<typename decay<_Fp>::type, typename decay<_Args>::type...> _Gp;
353c003db1fSHoward Hinnant    _VSTD::unique_ptr<_Gp> __p(new _Gp(__decay_copy(_VSTD::forward<_Fp>(__f)),
354ce48a113SHoward Hinnant                                __decay_copy(_VSTD::forward<_Args>(__args))...));
355c003db1fSHoward Hinnant    int __ec = pthread_create(&__t_, 0, &__thread_proxy<_Gp>, __p.get());
3568df61ea8SHoward Hinnant    if (__ec == 0)
3578df61ea8SHoward Hinnant        __p.release();
3588df61ea8SHoward Hinnant    else
3598df61ea8SHoward Hinnant        __throw_system_error(__ec, "thread constructor failed");
3608df61ea8SHoward Hinnant}
3618df61ea8SHoward Hinnant
3628df61ea8SHoward Hinnant#else  // _LIBCPP_HAS_NO_VARIADICS
3638df61ea8SHoward Hinnant
364c003db1fSHoward Hinnanttemplate <class _Fp>
3653e519524SHoward Hinnantvoid*
3663e519524SHoward Hinnant__thread_proxy(void* __vp)
3673e519524SHoward Hinnant{
36810e4a48aSHoward Hinnant    __thread_local_data().reset(new __thread_struct);
369c003db1fSHoward Hinnant    std::unique_ptr<_Fp> __p(static_cast<_Fp*>(__vp));
3703e519524SHoward Hinnant    (*__p)();
3713e519524SHoward Hinnant    return nullptr;
3723e519524SHoward Hinnant}
3733e519524SHoward Hinnant
374c003db1fSHoward Hinnanttemplate <class _Fp>
375c003db1fSHoward Hinnantthread::thread(_Fp __f)
3763e519524SHoward Hinnant{
377c003db1fSHoward Hinnant    std::unique_ptr<_Fp> __p(new _Fp(__f));
378c003db1fSHoward Hinnant    int __ec = pthread_create(&__t_, 0, &__thread_proxy<_Fp>, __p.get());
3793e519524SHoward Hinnant    if (__ec == 0)
3803e519524SHoward Hinnant        __p.release();
3813e519524SHoward Hinnant    else
3823e519524SHoward Hinnant        __throw_system_error(__ec, "thread constructor failed");
3833e519524SHoward Hinnant}
3843e519524SHoward Hinnant
385b3371f6fSHoward Hinnant#endif  // _LIBCPP_HAS_NO_VARIADICS
3863e519524SHoward Hinnant
3877609c9b6SHoward Hinnant#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
3883e519524SHoward Hinnant
389e0601335SHoward Hinnantinline _LIBCPP_INLINE_VISIBILITY
3903e519524SHoward Hinnantthread&
39136101a5bSHoward Hinnantthread::operator=(thread&& __t) _NOEXCEPT
3923e519524SHoward Hinnant{
393cbbf633eSHoward Hinnant    if (__t_ != 0)
3943e519524SHoward Hinnant        terminate();
3953e519524SHoward Hinnant    __t_ = __t.__t_;
396cbbf633eSHoward Hinnant    __t.__t_ = 0;
3973e519524SHoward Hinnant    return *this;
3983e519524SHoward Hinnant}
3993e519524SHoward Hinnant
4007609c9b6SHoward Hinnant#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
4013e519524SHoward Hinnant
402e0601335SHoward Hinnantinline _LIBCPP_INLINE_VISIBILITY
40336101a5bSHoward Hinnantvoid swap(thread& __x, thread& __y) _NOEXCEPT {__x.swap(__y);}
4043e519524SHoward Hinnant
4053e519524SHoward Hinnantnamespace this_thread
4063e519524SHoward Hinnant{
4073e519524SHoward Hinnant
4083e519524SHoward Hinnantvoid sleep_for(const chrono::nanoseconds& ns);
4093e519524SHoward Hinnant
4103e519524SHoward Hinnanttemplate <class _Rep, class _Period>
4113e519524SHoward Hinnantvoid
4123e519524SHoward Hinnantsleep_for(const chrono::duration<_Rep, _Period>& __d)
4133e519524SHoward Hinnant{
4143e519524SHoward Hinnant    using namespace chrono;
415aad745a0SHoward Hinnant    if (__d > duration<_Rep, _Period>::zero())
416aad745a0SHoward Hinnant    {
417aad745a0SHoward Hinnant        _LIBCPP_CONSTEXPR duration<long double> _Max = nanoseconds::max();
418aad745a0SHoward Hinnant        nanoseconds __ns;
419aad745a0SHoward Hinnant        if (__d < _Max)
420aad745a0SHoward Hinnant        {
421aad745a0SHoward Hinnant            __ns = duration_cast<nanoseconds>(__d);
4223e519524SHoward Hinnant            if (__ns < __d)
4233e519524SHoward Hinnant                ++__ns;
424aad745a0SHoward Hinnant        }
425aad745a0SHoward Hinnant        else
426aad745a0SHoward Hinnant            __ns = nanoseconds::max();
4273e519524SHoward Hinnant        sleep_for(__ns);
4283e519524SHoward Hinnant    }
429aad745a0SHoward Hinnant}
4303e519524SHoward Hinnant
4313e519524SHoward Hinnanttemplate <class _Clock, class _Duration>
4323e519524SHoward Hinnantvoid
4333e519524SHoward Hinnantsleep_until(const chrono::time_point<_Clock, _Duration>& __t)
4343e519524SHoward Hinnant{
4353e519524SHoward Hinnant    using namespace chrono;
4363e519524SHoward Hinnant    mutex __mut;
4373e519524SHoward Hinnant    condition_variable __cv;
4383e519524SHoward Hinnant    unique_lock<mutex> __lk(__mut);
4393e519524SHoward Hinnant    while (_Clock::now() < __t)
4403e519524SHoward Hinnant        __cv.wait_until(__lk, __t);
4413e519524SHoward Hinnant}
4423e519524SHoward Hinnant
4433e519524SHoward Hinnanttemplate <class _Duration>
444e0601335SHoward Hinnantinline _LIBCPP_INLINE_VISIBILITY
4453e519524SHoward Hinnantvoid
4463dc6455fSHoward Hinnantsleep_until(const chrono::time_point<chrono::steady_clock, _Duration>& __t)
4473e519524SHoward Hinnant{
4483e519524SHoward Hinnant    using namespace chrono;
4493dc6455fSHoward Hinnant    sleep_for(__t - steady_clock::now());
4503e519524SHoward Hinnant}
4513e519524SHoward Hinnant
452e0601335SHoward Hinnantinline _LIBCPP_INLINE_VISIBILITY
45336101a5bSHoward Hinnantvoid yield() _NOEXCEPT {sched_yield();}
4543e519524SHoward Hinnant
4553e519524SHoward Hinnant}  // this_thread
4563e519524SHoward Hinnant
4573e519524SHoward Hinnant_LIBCPP_END_NAMESPACE_STD
4583e519524SHoward Hinnant
4593e519524SHoward Hinnant#endif  // _LIBCPP_THREAD
460