xref: /llvm-project-15.0.7/libcxx/include/thread (revision 412dbebe)
13e519524SHoward Hinnant// -*- C++ -*-
23e519524SHoward Hinnant//===--------------------------- thread -----------------------------------===//
33e519524SHoward Hinnant//
45b08a8a4SHoward Hinnant//                     The LLVM Compiler Infrastructure
53e519524SHoward Hinnant//
6*412dbebeSHoward Hinnant// This file is dual licensed under the MIT and the University of Illinois Open
7*412dbebeSHoward 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
293e519524SHoward Hinnant    thread();
303e519524SHoward Hinnant    template <class F, class ...Args> explicit thread(F&& f, Args&&... args);
313e519524SHoward Hinnant    ~thread();
323e519524SHoward Hinnant
333e519524SHoward Hinnant    thread(const thread&) = delete;
343e519524SHoward Hinnant    thread(thread&& t);
353e519524SHoward Hinnant
363e519524SHoward Hinnant    thread& operator=(const thread&) = delete;
373e519524SHoward Hinnant    thread& operator=(thread&& t);
383e519524SHoward Hinnant
393e519524SHoward Hinnant    void swap(thread& t);
403e519524SHoward Hinnant
413e519524SHoward Hinnant    bool joinable() const;
423e519524SHoward Hinnant    void join();
433e519524SHoward Hinnant    void detach();
443e519524SHoward Hinnant    id get_id() const;
453e519524SHoward Hinnant    native_handle_type native_handle();
463e519524SHoward Hinnant
473e519524SHoward Hinnant    static unsigned hardware_concurrency();
483e519524SHoward Hinnant};
493e519524SHoward Hinnant
503e519524SHoward Hinnantvoid swap(thread& x, thread& y);
513e519524SHoward Hinnant
523e519524SHoward Hinnantclass thread::id
533e519524SHoward Hinnant{
543e519524SHoward Hinnantpublic:
553e519524SHoward Hinnant    id();
563e519524SHoward Hinnant};
573e519524SHoward Hinnant
583e519524SHoward Hinnantbool operator==(thread::id x, thread::id y);
593e519524SHoward Hinnantbool operator!=(thread::id x, thread::id y);
603e519524SHoward Hinnantbool operator< (thread::id x, thread::id y);
613e519524SHoward Hinnantbool operator<=(thread::id x, thread::id y);
623e519524SHoward Hinnantbool operator> (thread::id x, thread::id y);
633e519524SHoward Hinnantbool operator>=(thread::id x, thread::id y);
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
723e519524SHoward Hinnantthread::id get_id();
733e519524SHoward Hinnant
743e519524SHoward Hinnantvoid yield();
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>
983e519524SHoward Hinnant#include <pthread.h>
993e519524SHoward Hinnant
1003e519524SHoward Hinnant#pragma GCC system_header
1013e519524SHoward Hinnant
102e8e7af24SHoward Hinnant#define __STDCPP_THREADS__ __cplusplus
1033e519524SHoward Hinnant
1043e519524SHoward Hinnant_LIBCPP_BEGIN_NAMESPACE_STD
1053e519524SHoward Hinnant
106167fd108SHoward Hinnanttemplate <class _Tp>
107167fd108SHoward Hinnantclass __thread_specific_ptr
108167fd108SHoward Hinnant{
109167fd108SHoward Hinnant    pthread_key_t __key_;
110167fd108SHoward Hinnant
111167fd108SHoward Hinnant    __thread_specific_ptr(const __thread_specific_ptr&);
112167fd108SHoward Hinnant    __thread_specific_ptr& operator=(const __thread_specific_ptr&);
113167fd108SHoward Hinnant
114167fd108SHoward Hinnant    static void __at_thread_exit(void*);
115167fd108SHoward Hinnantpublic:
116167fd108SHoward Hinnant    typedef _Tp* pointer;
117167fd108SHoward Hinnant
118167fd108SHoward Hinnant    __thread_specific_ptr();
119167fd108SHoward Hinnant    ~__thread_specific_ptr();
120167fd108SHoward Hinnant
121e0601335SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
122167fd108SHoward Hinnant    pointer get() const {return static_cast<_Tp*>(pthread_getspecific(__key_));}
123e0601335SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
124167fd108SHoward Hinnant    pointer operator*() const {return *get();}
125e0601335SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
126167fd108SHoward Hinnant    pointer operator->() const {return get();}
127167fd108SHoward Hinnant    pointer release();
128167fd108SHoward Hinnant    void reset(pointer __p = nullptr);
129167fd108SHoward Hinnant};
130167fd108SHoward Hinnant
131167fd108SHoward Hinnanttemplate <class _Tp>
132167fd108SHoward Hinnantvoid
133167fd108SHoward Hinnant__thread_specific_ptr<_Tp>::__at_thread_exit(void* __p)
134167fd108SHoward Hinnant{
135167fd108SHoward Hinnant	delete static_cast<pointer>(__p);
136167fd108SHoward Hinnant}
137167fd108SHoward Hinnant
138167fd108SHoward Hinnanttemplate <class _Tp>
139167fd108SHoward Hinnant__thread_specific_ptr<_Tp>::__thread_specific_ptr()
140167fd108SHoward Hinnant{
141167fd108SHoward Hinnant    int __ec = pthread_key_create(&__key_, &__thread_specific_ptr::__at_thread_exit);
142167fd108SHoward Hinnant	if (__ec)
143167fd108SHoward Hinnant		throw system_error(error_code(__ec, system_category()),
144167fd108SHoward Hinnant		                   "__thread_specific_ptr construction failed");
145167fd108SHoward Hinnant}
146167fd108SHoward Hinnant
147167fd108SHoward Hinnanttemplate <class _Tp>
148167fd108SHoward Hinnant__thread_specific_ptr<_Tp>::~__thread_specific_ptr()
149167fd108SHoward Hinnant{
150167fd108SHoward Hinnant	pthread_key_delete(__key_);
151167fd108SHoward Hinnant}
152167fd108SHoward Hinnant
153167fd108SHoward Hinnanttemplate <class _Tp>
154167fd108SHoward Hinnanttypename __thread_specific_ptr<_Tp>::pointer
155167fd108SHoward Hinnant__thread_specific_ptr<_Tp>::release()
156167fd108SHoward Hinnant{
157167fd108SHoward Hinnant	pointer __p = get();
158167fd108SHoward Hinnant	pthread_setspecific(__key_, 0);
159167fd108SHoward Hinnant	return __p;
160167fd108SHoward Hinnant}
161167fd108SHoward Hinnant
162167fd108SHoward Hinnanttemplate <class _Tp>
163167fd108SHoward Hinnantvoid
164167fd108SHoward Hinnant__thread_specific_ptr<_Tp>::reset(pointer __p)
165167fd108SHoward Hinnant{
166167fd108SHoward Hinnant	pointer __p_old = get();
167167fd108SHoward Hinnant	pthread_setspecific(__key_, __p);
168167fd108SHoward Hinnant	delete __p_old;
169167fd108SHoward Hinnant}
170167fd108SHoward Hinnant
1713e519524SHoward Hinnantclass thread;
1723e519524SHoward Hinnantclass __thread_id;
1733e519524SHoward Hinnant
1743e519524SHoward Hinnantnamespace this_thread
1753e519524SHoward Hinnant{
1763e519524SHoward Hinnant
1773e519524SHoward Hinnant__thread_id get_id();
1783e519524SHoward Hinnant
1793e519524SHoward Hinnant}  // this_thread
1803e519524SHoward Hinnant
181e0601335SHoward Hinnantclass _LIBCPP_VISIBLE __thread_id
1823e519524SHoward Hinnant{
183128ba719SHoward Hinnant    // FIXME: pthread_t is a pointer on Darwin but a long on Linux.
184128ba719SHoward Hinnant    // NULL is the no-thread value on Darwin.  Someone needs to check
185128ba719SHoward Hinnant    // on other platforms.  We assume 0 works everywhere for now.
1863e519524SHoward Hinnant    pthread_t __id_;
1873e519524SHoward Hinnant
1883e519524SHoward Hinnantpublic:
189e0601335SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
1903e519524SHoward Hinnant    __thread_id() : __id_(0) {}
1913e519524SHoward Hinnant
192e0601335SHoward Hinnant    friend _LIBCPP_INLINE_VISIBILITY
193e0601335SHoward Hinnant        bool operator==(__thread_id __x, __thread_id __y)
1943e519524SHoward Hinnant        {return __x.__id_ == __y.__id_;}
195e0601335SHoward Hinnant    friend _LIBCPP_INLINE_VISIBILITY
196e0601335SHoward Hinnant        bool operator!=(__thread_id __x, __thread_id __y)
1973e519524SHoward Hinnant        {return !(__x == __y);}
198e0601335SHoward Hinnant    friend _LIBCPP_INLINE_VISIBILITY
199e0601335SHoward Hinnant        bool operator< (__thread_id __x, __thread_id __y)
2003e519524SHoward Hinnant        {return __x.__id_ < __y.__id_;}
201e0601335SHoward Hinnant    friend _LIBCPP_INLINE_VISIBILITY
202e0601335SHoward Hinnant        bool operator<=(__thread_id __x, __thread_id __y)
2033e519524SHoward Hinnant        {return !(__y < __x);}
204e0601335SHoward Hinnant    friend _LIBCPP_INLINE_VISIBILITY
205e0601335SHoward Hinnant        bool operator> (__thread_id __x, __thread_id __y)
2063e519524SHoward Hinnant        {return   __y < __x ;}
207e0601335SHoward Hinnant    friend _LIBCPP_INLINE_VISIBILITY
208e0601335SHoward Hinnant        bool operator>=(__thread_id __x, __thread_id __y)
2093e519524SHoward Hinnant        {return !(__x < __y);}
2103e519524SHoward Hinnant
2113e519524SHoward Hinnant    template<class _CharT, class _Traits>
2123e519524SHoward Hinnant    friend
213e0601335SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
2143e519524SHoward Hinnant    basic_ostream<_CharT, _Traits>&
2153e519524SHoward Hinnant    operator<<(basic_ostream<_CharT, _Traits>& __os, __thread_id __id)
2163e519524SHoward Hinnant        {return __os << __id.__id_;}
2173e519524SHoward Hinnant
2183e519524SHoward Hinnantprivate:
219e0601335SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
2203e519524SHoward Hinnant    __thread_id(pthread_t __id) : __id_(__id) {}
2213e519524SHoward Hinnant
2223e519524SHoward Hinnant    friend __thread_id this_thread::get_id();
223e0601335SHoward Hinnant    friend class _LIBCPP_VISIBLE thread;
2243e519524SHoward Hinnant};
2253e519524SHoward Hinnant
2263e519524SHoward Hinnanttemplate<class _Tp> struct hash;
2273e519524SHoward Hinnant
2283e519524SHoward Hinnanttemplate<>
229e0601335SHoward Hinnantstruct _LIBCPP_VISIBLE hash<__thread_id>
2303e519524SHoward Hinnant    : public unary_function<__thread_id, size_t>
2313e519524SHoward Hinnant{
232e0601335SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
2333e519524SHoward Hinnant    size_t operator()(__thread_id __v) const
2343e519524SHoward Hinnant    {
2353e519524SHoward Hinnant        const size_t* const __p = reinterpret_cast<const size_t*>(&__v);
2363e519524SHoward Hinnant        return *__p;
2373e519524SHoward Hinnant    }
2383e519524SHoward Hinnant};
2393e519524SHoward Hinnant
2403e519524SHoward Hinnantnamespace this_thread
2413e519524SHoward Hinnant{
2423e519524SHoward Hinnant
243e0601335SHoward Hinnantinline _LIBCPP_INLINE_VISIBILITY
2443e519524SHoward Hinnant__thread_id
2453e519524SHoward Hinnantget_id()
2463e519524SHoward Hinnant{
2473e519524SHoward Hinnant    return pthread_self();
2483e519524SHoward Hinnant}
2493e519524SHoward Hinnant
2503e519524SHoward Hinnant}  // this_thread
2513e519524SHoward Hinnant
252e0601335SHoward Hinnantclass _LIBCPP_VISIBLE thread
2533e519524SHoward Hinnant{
2543e519524SHoward Hinnant    pthread_t __t_;
2553e519524SHoward Hinnant
256eb269257SHoward Hinnant    thread(const thread&);
257eb269257SHoward Hinnant    thread& operator=(const thread&);
2583e519524SHoward Hinnantpublic:
2593e519524SHoward Hinnant    typedef __thread_id id;
2603e519524SHoward Hinnant    typedef pthread_t native_handle_type;
2613e519524SHoward Hinnant
262e0601335SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
2633e519524SHoward Hinnant    thread() : __t_(0) {}
2643e519524SHoward Hinnant#ifndef _LIBCPP_HAS_NO_VARIADICS
2653e519524SHoward Hinnant    template <class _F, class ..._Args,
2663e519524SHoward Hinnant              class = typename enable_if
2673e519524SHoward Hinnant              <
2683e519524SHoward Hinnant                   !is_same<typename decay<_F>::type, thread>::value
2693e519524SHoward Hinnant              >::type
2703e519524SHoward Hinnant             >
2713e519524SHoward Hinnant        explicit thread(_F&& __f, _Args&&... __args);
272b3371f6fSHoward Hinnant#else  // _LIBCPP_HAS_NO_VARIADICS
2733e519524SHoward Hinnant    template <class _F> explicit thread(_F __f);
2743e519524SHoward Hinnant#endif
2753e519524SHoward Hinnant    ~thread();
2763e519524SHoward Hinnant
2777609c9b6SHoward Hinnant#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
278e0601335SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
2793e519524SHoward Hinnant    thread(thread&& __t) : __t_(__t.__t_) {__t.__t_ = 0;}
2803e519524SHoward Hinnant    thread& operator=(thread&& __t);
2817609c9b6SHoward Hinnant#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
2823e519524SHoward Hinnant
283e0601335SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
2843e519524SHoward Hinnant    void swap(thread& __t) {_STD::swap(__t_, __t.__t_);}
2853e519524SHoward Hinnant
286e0601335SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
287128ba719SHoward Hinnant    bool joinable() const {return __t_ != 0;}
2883e519524SHoward Hinnant    void join();
2893e519524SHoward Hinnant    void detach();
290e0601335SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
2913e519524SHoward Hinnant    id get_id() const {return __t_;}
292e0601335SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
2933e519524SHoward Hinnant    native_handle_type native_handle() {return __t_;}
2943e519524SHoward Hinnant
2953e519524SHoward Hinnant    static unsigned hardware_concurrency();
2963e519524SHoward Hinnant};
2973e519524SHoward Hinnant
298167fd108SHoward Hinnantclass __assoc_sub_state;
299167fd108SHoward Hinnant
300167fd108SHoward Hinnantclass __thread_struct_imp;
301167fd108SHoward Hinnant
302167fd108SHoward Hinnantclass __thread_struct
303167fd108SHoward Hinnant{
304167fd108SHoward Hinnant    __thread_struct_imp* __p_;
305167fd108SHoward Hinnant
306167fd108SHoward Hinnant    __thread_struct(const __thread_struct&);
307167fd108SHoward Hinnant    __thread_struct& operator=(const __thread_struct&);
308167fd108SHoward Hinnantpublic:
309167fd108SHoward Hinnant    __thread_struct();
310167fd108SHoward Hinnant    ~__thread_struct();
311167fd108SHoward Hinnant
312b77c0c03SHoward Hinnant    void notify_all_at_thread_exit(condition_variable*, mutex*);
313167fd108SHoward Hinnant    void __make_ready_at_thread_exit(__assoc_sub_state*);
314167fd108SHoward Hinnant};
315167fd108SHoward Hinnant
31610e4a48aSHoward Hinnant__thread_specific_ptr<__thread_struct>& __thread_local_data();
317167fd108SHoward Hinnant
3183e519524SHoward Hinnanttemplate <class _F>
3193e519524SHoward Hinnantvoid*
3203e519524SHoward Hinnant__thread_proxy(void* __vp)
3213e519524SHoward Hinnant{
32210e4a48aSHoward Hinnant    __thread_local_data().reset(new __thread_struct);
3233e519524SHoward Hinnant    std::unique_ptr<_F> __p(static_cast<_F*>(__vp));
3243e519524SHoward Hinnant    (*__p)();
3253e519524SHoward Hinnant    return nullptr;
3263e519524SHoward Hinnant}
3273e519524SHoward Hinnant
3283e519524SHoward Hinnant#ifndef _LIBCPP_HAS_NO_VARIADICS
3293e519524SHoward Hinnant
3303e519524SHoward Hinnanttemplate <class _F, class ..._Args,
3313e519524SHoward Hinnant          class
3323e519524SHoward Hinnant         >
3333e519524SHoward Hinnantthread::thread(_F&& __f, _Args&&... __args)
3343e519524SHoward Hinnant{
3353e519524SHoward Hinnant    typedef decltype(bind(std::forward<_F>(__f), std::forward<_Args>(__args)...)) _G;
3363e519524SHoward Hinnant    std::unique_ptr<_G> __p(new _G(bind(std::forward<_F>(__f),
3373e519524SHoward Hinnant                              std::forward<_Args>(__args)...)));
3383e519524SHoward Hinnant    int __ec = pthread_create(&__t_, 0, &__thread_proxy<_G>, __p.get());
3393e519524SHoward Hinnant    if (__ec == 0)
3403e519524SHoward Hinnant        __p.release();
3413e519524SHoward Hinnant    else
3423e519524SHoward Hinnant        __throw_system_error(__ec, "thread constructor failed");
3433e519524SHoward Hinnant}
3443e519524SHoward Hinnant
345b3371f6fSHoward Hinnant#else  // _LIBCPP_HAS_NO_VARIADICS
3463e519524SHoward Hinnant
3473e519524SHoward Hinnanttemplate <class _F>
3483e519524SHoward Hinnantthread::thread(_F __f)
3493e519524SHoward Hinnant{
3503e519524SHoward Hinnant    std::unique_ptr<_F> __p(new _F(__f));
3513e519524SHoward Hinnant    int __ec = pthread_create(&__t_, 0, &__thread_proxy<_F>, __p.get());
3523e519524SHoward Hinnant    if (__ec == 0)
3533e519524SHoward Hinnant        __p.release();
3543e519524SHoward Hinnant    else
3553e519524SHoward Hinnant        __throw_system_error(__ec, "thread constructor failed");
3563e519524SHoward Hinnant}
3573e519524SHoward Hinnant
358b3371f6fSHoward Hinnant#endif  // _LIBCPP_HAS_NO_VARIADICS
3593e519524SHoward Hinnant
3607609c9b6SHoward Hinnant#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
3613e519524SHoward Hinnant
362e0601335SHoward Hinnantinline _LIBCPP_INLINE_VISIBILITY
3633e519524SHoward Hinnantthread&
3643e519524SHoward Hinnantthread::operator=(thread&& __t)
3653e519524SHoward Hinnant{
366cbbf633eSHoward Hinnant    if (__t_ != 0)
3673e519524SHoward Hinnant        terminate();
3683e519524SHoward Hinnant    __t_ = __t.__t_;
369cbbf633eSHoward Hinnant    __t.__t_ = 0;
3703e519524SHoward Hinnant    return *this;
3713e519524SHoward Hinnant}
3723e519524SHoward Hinnant
3737609c9b6SHoward Hinnant#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
3743e519524SHoward Hinnant
375e0601335SHoward Hinnantinline _LIBCPP_INLINE_VISIBILITY
3763e519524SHoward Hinnantvoid swap(thread& __x, thread& __y) {__x.swap(__y);}
3773e519524SHoward Hinnant
3783e519524SHoward Hinnantnamespace this_thread
3793e519524SHoward Hinnant{
3803e519524SHoward Hinnant
3813e519524SHoward Hinnantvoid sleep_for(const chrono::nanoseconds& ns);
3823e519524SHoward Hinnant
3833e519524SHoward Hinnanttemplate <class _Rep, class _Period>
3843e519524SHoward Hinnantvoid
3853e519524SHoward Hinnantsleep_for(const chrono::duration<_Rep, _Period>& __d)
3863e519524SHoward Hinnant{
3873e519524SHoward Hinnant    using namespace chrono;
3883e519524SHoward Hinnant    nanoseconds __ns = duration_cast<nanoseconds>(__d);
3893e519524SHoward Hinnant    if (__ns < __d)
3903e519524SHoward Hinnant        ++__ns;
3913e519524SHoward Hinnant    sleep_for(__ns);
3923e519524SHoward Hinnant}
3933e519524SHoward Hinnant
3943e519524SHoward Hinnanttemplate <class _Clock, class _Duration>
3953e519524SHoward Hinnantvoid
3963e519524SHoward Hinnantsleep_until(const chrono::time_point<_Clock, _Duration>& __t)
3973e519524SHoward Hinnant{
3983e519524SHoward Hinnant    using namespace chrono;
3993e519524SHoward Hinnant    mutex __mut;
4003e519524SHoward Hinnant    condition_variable __cv;
4013e519524SHoward Hinnant    unique_lock<mutex> __lk(__mut);
4023e519524SHoward Hinnant    while (_Clock::now() < __t)
4033e519524SHoward Hinnant        __cv.wait_until(__lk, __t);
4043e519524SHoward Hinnant}
4053e519524SHoward Hinnant
4063e519524SHoward Hinnanttemplate <class _Duration>
407e0601335SHoward Hinnantinline _LIBCPP_INLINE_VISIBILITY
4083e519524SHoward Hinnantvoid
4093e519524SHoward Hinnantsleep_until(const chrono::time_point<chrono::monotonic_clock, _Duration>& __t)
4103e519524SHoward Hinnant{
4113e519524SHoward Hinnant    using namespace chrono;
4123e519524SHoward Hinnant    sleep_for(__t - monotonic_clock::now());
4133e519524SHoward Hinnant}
4143e519524SHoward Hinnant
415e0601335SHoward Hinnantinline _LIBCPP_INLINE_VISIBILITY
4163e519524SHoward Hinnantvoid yield() {sched_yield();}
4173e519524SHoward Hinnant
4183e519524SHoward Hinnant}  // this_thread
4193e519524SHoward Hinnant
4203e519524SHoward Hinnant_LIBCPP_END_NAMESPACE_STD
4213e519524SHoward Hinnant
4223e519524SHoward Hinnant#endif  // _LIBCPP_THREAD
423