xref: /freebsd/contrib/llvm-project/libcxx/include/thread (revision 349cc55c9796c4596a5b9904cd3281af295f878f)
10b57cec5SDimitry Andric// -*- C++ -*-
2*349cc55cSDimitry Andric//===----------------------------------------------------------------------===//
30b57cec5SDimitry Andric//
40b57cec5SDimitry Andric// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
50b57cec5SDimitry Andric// See https://llvm.org/LICENSE.txt for license information.
60b57cec5SDimitry Andric// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
70b57cec5SDimitry Andric//
80b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
90b57cec5SDimitry Andric
100b57cec5SDimitry Andric#ifndef _LIBCPP_THREAD
110b57cec5SDimitry Andric#define _LIBCPP_THREAD
120b57cec5SDimitry Andric
130b57cec5SDimitry Andric/*
140b57cec5SDimitry Andric
150b57cec5SDimitry Andric    thread synopsis
160b57cec5SDimitry Andric
170b57cec5SDimitry Andricnamespace std
180b57cec5SDimitry Andric{
190b57cec5SDimitry Andric
200b57cec5SDimitry Andricclass thread
210b57cec5SDimitry Andric{
220b57cec5SDimitry Andricpublic:
230b57cec5SDimitry Andric    class id;
240b57cec5SDimitry Andric    typedef pthread_t native_handle_type;
250b57cec5SDimitry Andric
260b57cec5SDimitry Andric    thread() noexcept;
270b57cec5SDimitry Andric    template <class F, class ...Args> explicit thread(F&& f, Args&&... args);
280b57cec5SDimitry Andric    ~thread();
290b57cec5SDimitry Andric
300b57cec5SDimitry Andric    thread(const thread&) = delete;
310b57cec5SDimitry Andric    thread(thread&& t) noexcept;
320b57cec5SDimitry Andric
330b57cec5SDimitry Andric    thread& operator=(const thread&) = delete;
340b57cec5SDimitry Andric    thread& operator=(thread&& t) noexcept;
350b57cec5SDimitry Andric
360b57cec5SDimitry Andric    void swap(thread& t) noexcept;
370b57cec5SDimitry Andric
380b57cec5SDimitry Andric    bool joinable() const noexcept;
390b57cec5SDimitry Andric    void join();
400b57cec5SDimitry Andric    void detach();
410b57cec5SDimitry Andric    id get_id() const noexcept;
420b57cec5SDimitry Andric    native_handle_type native_handle();
430b57cec5SDimitry Andric
440b57cec5SDimitry Andric    static unsigned hardware_concurrency() noexcept;
450b57cec5SDimitry Andric};
460b57cec5SDimitry Andric
470b57cec5SDimitry Andricvoid swap(thread& x, thread& y) noexcept;
480b57cec5SDimitry Andric
490b57cec5SDimitry Andricclass thread::id
500b57cec5SDimitry Andric{
510b57cec5SDimitry Andricpublic:
520b57cec5SDimitry Andric    id() noexcept;
530b57cec5SDimitry Andric};
540b57cec5SDimitry Andric
550b57cec5SDimitry Andricbool operator==(thread::id x, thread::id y) noexcept;
560b57cec5SDimitry Andricbool operator!=(thread::id x, thread::id y) noexcept;
570b57cec5SDimitry Andricbool operator< (thread::id x, thread::id y) noexcept;
580b57cec5SDimitry Andricbool operator<=(thread::id x, thread::id y) noexcept;
590b57cec5SDimitry Andricbool operator> (thread::id x, thread::id y) noexcept;
600b57cec5SDimitry Andricbool operator>=(thread::id x, thread::id y) noexcept;
610b57cec5SDimitry Andric
620b57cec5SDimitry Andrictemplate<class charT, class traits>
630b57cec5SDimitry Andricbasic_ostream<charT, traits>&
640b57cec5SDimitry Andricoperator<<(basic_ostream<charT, traits>& out, thread::id id);
650b57cec5SDimitry Andric
660b57cec5SDimitry Andricnamespace this_thread
670b57cec5SDimitry Andric{
680b57cec5SDimitry Andric
690b57cec5SDimitry Andricthread::id get_id() noexcept;
700b57cec5SDimitry Andric
710b57cec5SDimitry Andricvoid yield() noexcept;
720b57cec5SDimitry Andric
730b57cec5SDimitry Andrictemplate <class Clock, class Duration>
740b57cec5SDimitry Andricvoid sleep_until(const chrono::time_point<Clock, Duration>& abs_time);
750b57cec5SDimitry Andric
760b57cec5SDimitry Andrictemplate <class Rep, class Period>
770b57cec5SDimitry Andricvoid sleep_for(const chrono::duration<Rep, Period>& rel_time);
780b57cec5SDimitry Andric
790b57cec5SDimitry Andric}  // this_thread
800b57cec5SDimitry Andric
810b57cec5SDimitry Andric}  // std
820b57cec5SDimitry Andric
830b57cec5SDimitry Andric*/
840b57cec5SDimitry Andric
850b57cec5SDimitry Andric#include <__config>
86fe6060f1SDimitry Andric#include <__debug>
870b57cec5SDimitry Andric#include <__functional_base>
88fe6060f1SDimitry Andric#include <__mutex_base>
89*349cc55cSDimitry Andric#include <__thread/poll_with_backoff.h>
90fe6060f1SDimitry Andric#include <__threading_support>
91*349cc55cSDimitry Andric#include <__utility/decay_copy.h>
92fe6060f1SDimitry Andric#include <__utility/forward.h>
93fe6060f1SDimitry Andric#include <chrono>
940b57cec5SDimitry Andric#include <cstddef>
950b57cec5SDimitry Andric#include <functional>
96fe6060f1SDimitry Andric#include <iosfwd>
970b57cec5SDimitry Andric#include <memory>
980b57cec5SDimitry Andric#include <system_error>
990b57cec5SDimitry Andric#include <tuple>
100fe6060f1SDimitry Andric#include <type_traits>
1010b57cec5SDimitry Andric
1020b57cec5SDimitry Andric#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
1030b57cec5SDimitry Andric#pragma GCC system_header
1040b57cec5SDimitry Andric#endif
1050b57cec5SDimitry Andric
1060b57cec5SDimitry Andric_LIBCPP_PUSH_MACROS
1070b57cec5SDimitry Andric#include <__undef_macros>
1080b57cec5SDimitry Andric
1090b57cec5SDimitry Andric#ifdef _LIBCPP_HAS_NO_THREADS
1100b57cec5SDimitry Andric#error <thread> is not supported on this single threaded system
1110b57cec5SDimitry Andric#else // !_LIBCPP_HAS_NO_THREADS
1120b57cec5SDimitry Andric
1130b57cec5SDimitry Andric_LIBCPP_BEGIN_NAMESPACE_STD
1140b57cec5SDimitry Andric
1150b57cec5SDimitry Andrictemplate <class _Tp> class __thread_specific_ptr;
1160b57cec5SDimitry Andricclass _LIBCPP_TYPE_VIS __thread_struct;
1170b57cec5SDimitry Andricclass _LIBCPP_HIDDEN __thread_struct_imp;
1180b57cec5SDimitry Andricclass __assoc_sub_state;
1190b57cec5SDimitry Andric
1200b57cec5SDimitry Andric_LIBCPP_FUNC_VIS __thread_specific_ptr<__thread_struct>& __thread_local_data();
1210b57cec5SDimitry Andric
1220b57cec5SDimitry Andricclass _LIBCPP_TYPE_VIS __thread_struct
1230b57cec5SDimitry Andric{
1240b57cec5SDimitry Andric    __thread_struct_imp* __p_;
1250b57cec5SDimitry Andric
1260b57cec5SDimitry Andric    __thread_struct(const __thread_struct&);
1270b57cec5SDimitry Andric    __thread_struct& operator=(const __thread_struct&);
1280b57cec5SDimitry Andricpublic:
1290b57cec5SDimitry Andric    __thread_struct();
1300b57cec5SDimitry Andric    ~__thread_struct();
1310b57cec5SDimitry Andric
1320b57cec5SDimitry Andric    void notify_all_at_thread_exit(condition_variable*, mutex*);
1330b57cec5SDimitry Andric    void __make_ready_at_thread_exit(__assoc_sub_state*);
1340b57cec5SDimitry Andric};
1350b57cec5SDimitry Andric
1360b57cec5SDimitry Andrictemplate <class _Tp>
1370b57cec5SDimitry Andricclass __thread_specific_ptr
1380b57cec5SDimitry Andric{
1390b57cec5SDimitry Andric    __libcpp_tls_key __key_;
1400b57cec5SDimitry Andric
1410b57cec5SDimitry Andric     // Only __thread_local_data() may construct a __thread_specific_ptr
1420b57cec5SDimitry Andric     // and only with _Tp == __thread_struct.
1430b57cec5SDimitry Andric    static_assert((is_same<_Tp, __thread_struct>::value), "");
1440b57cec5SDimitry Andric    __thread_specific_ptr();
1450b57cec5SDimitry Andric    friend _LIBCPP_FUNC_VIS __thread_specific_ptr<__thread_struct>& __thread_local_data();
1460b57cec5SDimitry Andric
1470b57cec5SDimitry Andric    __thread_specific_ptr(const __thread_specific_ptr&);
1480b57cec5SDimitry Andric    __thread_specific_ptr& operator=(const __thread_specific_ptr&);
1490b57cec5SDimitry Andric
1500b57cec5SDimitry Andric    _LIBCPP_HIDDEN static void _LIBCPP_TLS_DESTRUCTOR_CC __at_thread_exit(void*);
1510b57cec5SDimitry Andric
1520b57cec5SDimitry Andricpublic:
1530b57cec5SDimitry Andric    typedef _Tp* pointer;
1540b57cec5SDimitry Andric
1550b57cec5SDimitry Andric    ~__thread_specific_ptr();
1560b57cec5SDimitry Andric
1570b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
1580b57cec5SDimitry Andric    pointer get() const {return static_cast<_Tp*>(__libcpp_tls_get(__key_));}
1590b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
1600b57cec5SDimitry Andric    pointer operator*() const {return *get();}
1610b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
1620b57cec5SDimitry Andric    pointer operator->() const {return get();}
1630b57cec5SDimitry Andric    void set_pointer(pointer __p);
1640b57cec5SDimitry Andric};
1650b57cec5SDimitry Andric
1660b57cec5SDimitry Andrictemplate <class _Tp>
1670b57cec5SDimitry Andricvoid _LIBCPP_TLS_DESTRUCTOR_CC
1680b57cec5SDimitry Andric__thread_specific_ptr<_Tp>::__at_thread_exit(void* __p)
1690b57cec5SDimitry Andric{
1700b57cec5SDimitry Andric    delete static_cast<pointer>(__p);
1710b57cec5SDimitry Andric}
1720b57cec5SDimitry Andric
1730b57cec5SDimitry Andrictemplate <class _Tp>
1740b57cec5SDimitry Andric__thread_specific_ptr<_Tp>::__thread_specific_ptr()
1750b57cec5SDimitry Andric{
1760b57cec5SDimitry Andric  int __ec =
1770b57cec5SDimitry Andric      __libcpp_tls_create(&__key_, &__thread_specific_ptr::__at_thread_exit);
1780b57cec5SDimitry Andric  if (__ec)
1790b57cec5SDimitry Andric    __throw_system_error(__ec, "__thread_specific_ptr construction failed");
1800b57cec5SDimitry Andric}
1810b57cec5SDimitry Andric
1820b57cec5SDimitry Andrictemplate <class _Tp>
1830b57cec5SDimitry Andric__thread_specific_ptr<_Tp>::~__thread_specific_ptr()
1840b57cec5SDimitry Andric{
1850b57cec5SDimitry Andric    // __thread_specific_ptr is only created with a static storage duration
1860b57cec5SDimitry Andric    // so this destructor is only invoked during program termination. Invoking
1870b57cec5SDimitry Andric    // pthread_key_delete(__key_) may prevent other threads from deleting their
1880b57cec5SDimitry Andric    // thread local data. For this reason we leak the key.
1890b57cec5SDimitry Andric}
1900b57cec5SDimitry Andric
1910b57cec5SDimitry Andrictemplate <class _Tp>
1920b57cec5SDimitry Andricvoid
1930b57cec5SDimitry Andric__thread_specific_ptr<_Tp>::set_pointer(pointer __p)
1940b57cec5SDimitry Andric{
1950b57cec5SDimitry Andric    _LIBCPP_ASSERT(get() == nullptr,
1960b57cec5SDimitry Andric                   "Attempting to overwrite thread local data");
1970b57cec5SDimitry Andric    __libcpp_tls_set(__key_, __p);
1980b57cec5SDimitry Andric}
1990b57cec5SDimitry Andric
2000b57cec5SDimitry Andrictemplate<>
2010b57cec5SDimitry Andricstruct _LIBCPP_TEMPLATE_VIS hash<__thread_id>
2020b57cec5SDimitry Andric    : public unary_function<__thread_id, size_t>
2030b57cec5SDimitry Andric{
2040b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
2050b57cec5SDimitry Andric    size_t operator()(__thread_id __v) const _NOEXCEPT
2060b57cec5SDimitry Andric    {
2070b57cec5SDimitry Andric        return hash<__libcpp_thread_id>()(__v.__id_);
2080b57cec5SDimitry Andric    }
2090b57cec5SDimitry Andric};
2100b57cec5SDimitry Andric
2110b57cec5SDimitry Andrictemplate<class _CharT, class _Traits>
2120b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
2130b57cec5SDimitry Andricbasic_ostream<_CharT, _Traits>&
2140b57cec5SDimitry Andricoperator<<(basic_ostream<_CharT, _Traits>& __os, __thread_id __id)
2150b57cec5SDimitry Andric{return __os << __id.__id_;}
2160b57cec5SDimitry Andric
2170b57cec5SDimitry Andricclass _LIBCPP_TYPE_VIS thread
2180b57cec5SDimitry Andric{
2190b57cec5SDimitry Andric    __libcpp_thread_t __t_;
2200b57cec5SDimitry Andric
2210b57cec5SDimitry Andric    thread(const thread&);
2220b57cec5SDimitry Andric    thread& operator=(const thread&);
2230b57cec5SDimitry Andricpublic:
2240b57cec5SDimitry Andric    typedef __thread_id id;
2250b57cec5SDimitry Andric    typedef __libcpp_thread_t native_handle_type;
2260b57cec5SDimitry Andric
2270b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
2280b57cec5SDimitry Andric    thread() _NOEXCEPT : __t_(_LIBCPP_NULL_THREAD) {}
2290b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG
2300b57cec5SDimitry Andric    template <class _Fp, class ..._Args,
2310b57cec5SDimitry Andric              class = typename enable_if
2320b57cec5SDimitry Andric              <
2330b57cec5SDimitry Andric                   !is_same<typename __uncvref<_Fp>::type, thread>::value
2340b57cec5SDimitry Andric              >::type
2350b57cec5SDimitry Andric             >
2360b57cec5SDimitry Andric        _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
2370b57cec5SDimitry Andric        explicit thread(_Fp&& __f, _Args&&... __args);
2380b57cec5SDimitry Andric#else  // _LIBCPP_CXX03_LANG
2390b57cec5SDimitry Andric    template <class _Fp>
2400b57cec5SDimitry Andric    _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
2410b57cec5SDimitry Andric    explicit thread(_Fp __f);
2420b57cec5SDimitry Andric#endif
2430b57cec5SDimitry Andric    ~thread();
2440b57cec5SDimitry Andric
2450b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
2465ffd83dbSDimitry Andric    thread(thread&& __t) _NOEXCEPT : __t_(__t.__t_) {
2475ffd83dbSDimitry Andric        __t.__t_ = _LIBCPP_NULL_THREAD;
2485ffd83dbSDimitry Andric    }
2495ffd83dbSDimitry Andric
2500b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
2515ffd83dbSDimitry Andric    thread& operator=(thread&& __t) _NOEXCEPT {
2525ffd83dbSDimitry Andric        if (!__libcpp_thread_isnull(&__t_))
2535ffd83dbSDimitry Andric            terminate();
2545ffd83dbSDimitry Andric        __t_ = __t.__t_;
2555ffd83dbSDimitry Andric        __t.__t_ = _LIBCPP_NULL_THREAD;
2565ffd83dbSDimitry Andric        return *this;
2575ffd83dbSDimitry Andric    }
2580b57cec5SDimitry Andric
2590b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
2600b57cec5SDimitry Andric    void swap(thread& __t) _NOEXCEPT {_VSTD::swap(__t_, __t.__t_);}
2610b57cec5SDimitry Andric
2620b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
2630b57cec5SDimitry Andric    bool joinable() const _NOEXCEPT {return !__libcpp_thread_isnull(&__t_);}
2640b57cec5SDimitry Andric    void join();
2650b57cec5SDimitry Andric    void detach();
2660b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
2670b57cec5SDimitry Andric    id get_id() const _NOEXCEPT {return __libcpp_thread_get_id(&__t_);}
2680b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
2690b57cec5SDimitry Andric    native_handle_type native_handle() _NOEXCEPT {return __t_;}
2700b57cec5SDimitry Andric
2710b57cec5SDimitry Andric    static unsigned hardware_concurrency() _NOEXCEPT;
2720b57cec5SDimitry Andric};
2730b57cec5SDimitry Andric
2740b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG
2750b57cec5SDimitry Andric
2760b57cec5SDimitry Andrictemplate <class _TSp, class _Fp, class ..._Args, size_t ..._Indices>
2770b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
2780b57cec5SDimitry Andricvoid
2790b57cec5SDimitry Andric__thread_execute(tuple<_TSp, _Fp, _Args...>& __t, __tuple_indices<_Indices...>)
2800b57cec5SDimitry Andric{
281e8d8bef9SDimitry Andric    _VSTD::__invoke(_VSTD::move(_VSTD::get<1>(__t)), _VSTD::move(_VSTD::get<_Indices>(__t))...);
2820b57cec5SDimitry Andric}
2830b57cec5SDimitry Andric
2840b57cec5SDimitry Andrictemplate <class _Fp>
285480093f4SDimitry Andric_LIBCPP_INLINE_VISIBILITY
2860b57cec5SDimitry Andricvoid* __thread_proxy(void* __vp)
2870b57cec5SDimitry Andric{
288e8d8bef9SDimitry Andric    // _Fp = tuple< unique_ptr<__thread_struct>, Functor, Args...>
289e8d8bef9SDimitry Andric    unique_ptr<_Fp> __p(static_cast<_Fp*>(__vp));
290e8d8bef9SDimitry Andric    __thread_local_data().set_pointer(_VSTD::get<0>(*__p.get()).release());
2910b57cec5SDimitry Andric    typedef typename __make_tuple_indices<tuple_size<_Fp>::value, 2>::type _Index;
292e8d8bef9SDimitry Andric    _VSTD::__thread_execute(*__p.get(), _Index());
2930b57cec5SDimitry Andric    return nullptr;
2940b57cec5SDimitry Andric}
2950b57cec5SDimitry Andric
2960b57cec5SDimitry Andrictemplate <class _Fp, class ..._Args,
2970b57cec5SDimitry Andric          class
2980b57cec5SDimitry Andric         >
2990b57cec5SDimitry Andricthread::thread(_Fp&& __f, _Args&&... __args)
3000b57cec5SDimitry Andric{
3010b57cec5SDimitry Andric    typedef unique_ptr<__thread_struct> _TSPtr;
3020b57cec5SDimitry Andric    _TSPtr __tsp(new __thread_struct);
3030b57cec5SDimitry Andric    typedef tuple<_TSPtr, typename decay<_Fp>::type, typename decay<_Args>::type...> _Gp;
304e8d8bef9SDimitry Andric    unique_ptr<_Gp> __p(
305e8d8bef9SDimitry Andric            new _Gp(_VSTD::move(__tsp),
306e8d8bef9SDimitry Andric                    _VSTD::__decay_copy(_VSTD::forward<_Fp>(__f)),
307e8d8bef9SDimitry Andric                    _VSTD::__decay_copy(_VSTD::forward<_Args>(__args))...));
308e8d8bef9SDimitry Andric    int __ec = _VSTD::__libcpp_thread_create(&__t_, &__thread_proxy<_Gp>, __p.get());
3090b57cec5SDimitry Andric    if (__ec == 0)
3100b57cec5SDimitry Andric        __p.release();
3110b57cec5SDimitry Andric    else
3120b57cec5SDimitry Andric        __throw_system_error(__ec, "thread constructor failed");
3130b57cec5SDimitry Andric}
3140b57cec5SDimitry Andric
3150b57cec5SDimitry Andric#else  // _LIBCPP_CXX03_LANG
3160b57cec5SDimitry Andric
3170b57cec5SDimitry Andrictemplate <class _Fp>
3180b57cec5SDimitry Andricstruct __thread_invoke_pair {
3190b57cec5SDimitry Andric    // This type is used to pass memory for thread local storage and a functor
3200b57cec5SDimitry Andric    // to a newly created thread because std::pair doesn't work with
3210b57cec5SDimitry Andric    // std::unique_ptr in C++03.
3220b57cec5SDimitry Andric    __thread_invoke_pair(_Fp& __f) : __tsp_(new __thread_struct), __fn_(__f) {}
3230b57cec5SDimitry Andric    unique_ptr<__thread_struct> __tsp_;
3240b57cec5SDimitry Andric    _Fp __fn_;
3250b57cec5SDimitry Andric};
3260b57cec5SDimitry Andric
3270b57cec5SDimitry Andrictemplate <class _Fp>
3280b57cec5SDimitry Andricvoid* __thread_proxy_cxx03(void* __vp)
3290b57cec5SDimitry Andric{
330e8d8bef9SDimitry Andric    unique_ptr<_Fp> __p(static_cast<_Fp*>(__vp));
3310b57cec5SDimitry Andric    __thread_local_data().set_pointer(__p->__tsp_.release());
3320b57cec5SDimitry Andric    (__p->__fn_)();
3330b57cec5SDimitry Andric    return nullptr;
3340b57cec5SDimitry Andric}
3350b57cec5SDimitry Andric
3360b57cec5SDimitry Andrictemplate <class _Fp>
3370b57cec5SDimitry Andricthread::thread(_Fp __f)
3380b57cec5SDimitry Andric{
3390b57cec5SDimitry Andric
3400b57cec5SDimitry Andric    typedef __thread_invoke_pair<_Fp> _InvokePair;
341e8d8bef9SDimitry Andric    typedef unique_ptr<_InvokePair> _PairPtr;
3420b57cec5SDimitry Andric    _PairPtr __pp(new _InvokePair(__f));
343e8d8bef9SDimitry Andric    int __ec = _VSTD::__libcpp_thread_create(&__t_, &__thread_proxy_cxx03<_InvokePair>, __pp.get());
3440b57cec5SDimitry Andric    if (__ec == 0)
3450b57cec5SDimitry Andric        __pp.release();
3460b57cec5SDimitry Andric    else
3470b57cec5SDimitry Andric        __throw_system_error(__ec, "thread constructor failed");
3480b57cec5SDimitry Andric}
3490b57cec5SDimitry Andric
3500b57cec5SDimitry Andric#endif // _LIBCPP_CXX03_LANG
3510b57cec5SDimitry Andric
3520b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
3530b57cec5SDimitry Andricvoid swap(thread& __x, thread& __y) _NOEXCEPT {__x.swap(__y);}
3540b57cec5SDimitry Andric
3550b57cec5SDimitry Andricnamespace this_thread
3560b57cec5SDimitry Andric{
3570b57cec5SDimitry Andric
3580b57cec5SDimitry Andric_LIBCPP_FUNC_VIS void sleep_for(const chrono::nanoseconds& __ns);
3590b57cec5SDimitry Andric
3600b57cec5SDimitry Andrictemplate <class _Rep, class _Period>
3610b57cec5SDimitry Andricvoid
3620b57cec5SDimitry Andricsleep_for(const chrono::duration<_Rep, _Period>& __d)
3630b57cec5SDimitry Andric{
364e8d8bef9SDimitry Andric    if (__d > chrono::duration<_Rep, _Period>::zero())
3650b57cec5SDimitry Andric    {
366fe6060f1SDimitry Andric        // The standard guarantees a 64bit signed integer resolution for nanoseconds,
367fe6060f1SDimitry Andric        // so use INT64_MAX / 1e9 as cut-off point. Use a constant to avoid <climits>
368fe6060f1SDimitry Andric        // and issues with long double folding on PowerPC with GCC.
369fe6060f1SDimitry Andric        _LIBCPP_CONSTEXPR chrono::duration<long double> _Max =
370fe6060f1SDimitry Andric            chrono::duration<long double>(9223372036.0L);
371e8d8bef9SDimitry Andric        chrono::nanoseconds __ns;
3720b57cec5SDimitry Andric        if (__d < _Max)
3730b57cec5SDimitry Andric        {
374e8d8bef9SDimitry Andric            __ns = chrono::duration_cast<chrono::nanoseconds>(__d);
3750b57cec5SDimitry Andric            if (__ns < __d)
3760b57cec5SDimitry Andric                ++__ns;
3770b57cec5SDimitry Andric        }
3780b57cec5SDimitry Andric        else
379e8d8bef9SDimitry Andric            __ns = chrono::nanoseconds::max();
380e8d8bef9SDimitry Andric        this_thread::sleep_for(__ns);
3810b57cec5SDimitry Andric    }
3820b57cec5SDimitry Andric}
3830b57cec5SDimitry Andric
3840b57cec5SDimitry Andrictemplate <class _Clock, class _Duration>
3850b57cec5SDimitry Andricvoid
3860b57cec5SDimitry Andricsleep_until(const chrono::time_point<_Clock, _Duration>& __t)
3870b57cec5SDimitry Andric{
3880b57cec5SDimitry Andric    mutex __mut;
3890b57cec5SDimitry Andric    condition_variable __cv;
3900b57cec5SDimitry Andric    unique_lock<mutex> __lk(__mut);
3910b57cec5SDimitry Andric    while (_Clock::now() < __t)
3920b57cec5SDimitry Andric        __cv.wait_until(__lk, __t);
3930b57cec5SDimitry Andric}
3940b57cec5SDimitry Andric
3950b57cec5SDimitry Andrictemplate <class _Duration>
3960b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
3970b57cec5SDimitry Andricvoid
3980b57cec5SDimitry Andricsleep_until(const chrono::time_point<chrono::steady_clock, _Duration>& __t)
3990b57cec5SDimitry Andric{
400e8d8bef9SDimitry Andric    this_thread::sleep_for(__t - chrono::steady_clock::now());
4010b57cec5SDimitry Andric}
4020b57cec5SDimitry Andric
4030b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
4040b57cec5SDimitry Andricvoid yield() _NOEXCEPT {__libcpp_thread_yield();}
4050b57cec5SDimitry Andric
4060b57cec5SDimitry Andric}  // this_thread
4070b57cec5SDimitry Andric
4080b57cec5SDimitry Andric_LIBCPP_END_NAMESPACE_STD
4090b57cec5SDimitry Andric
4100b57cec5SDimitry Andric#endif // !_LIBCPP_HAS_NO_THREADS
4110b57cec5SDimitry Andric
4120b57cec5SDimitry Andric_LIBCPP_POP_MACROS
4130b57cec5SDimitry Andric
4140b57cec5SDimitry Andric#endif // _LIBCPP_THREAD
415