xref: /openbsd/gnu/llvm/libcxx/include/thread (revision 4bdff4be)
146035553Spatrick// -*- C++ -*-
2*4bdff4beSrobert//===----------------------------------------------------------------------===//
346035553Spatrick//
446035553Spatrick// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
546035553Spatrick// See https://llvm.org/LICENSE.txt for license information.
646035553Spatrick// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
746035553Spatrick//
846035553Spatrick//===----------------------------------------------------------------------===//
946035553Spatrick
1046035553Spatrick#ifndef _LIBCPP_THREAD
1146035553Spatrick#define _LIBCPP_THREAD
1246035553Spatrick
1346035553Spatrick/*
1446035553Spatrick
1546035553Spatrick    thread synopsis
1646035553Spatrick
1746035553Spatricknamespace std
1846035553Spatrick{
1946035553Spatrick
2046035553Spatrickclass thread
2146035553Spatrick{
2246035553Spatrickpublic:
2346035553Spatrick    class id;
2446035553Spatrick    typedef pthread_t native_handle_type;
2546035553Spatrick
2646035553Spatrick    thread() noexcept;
2746035553Spatrick    template <class F, class ...Args> explicit thread(F&& f, Args&&... args);
2846035553Spatrick    ~thread();
2946035553Spatrick
3046035553Spatrick    thread(const thread&) = delete;
3146035553Spatrick    thread(thread&& t) noexcept;
3246035553Spatrick
3346035553Spatrick    thread& operator=(const thread&) = delete;
3446035553Spatrick    thread& operator=(thread&& t) noexcept;
3546035553Spatrick
3646035553Spatrick    void swap(thread& t) noexcept;
3746035553Spatrick
3846035553Spatrick    bool joinable() const noexcept;
3946035553Spatrick    void join();
4046035553Spatrick    void detach();
4146035553Spatrick    id get_id() const noexcept;
4246035553Spatrick    native_handle_type native_handle();
4346035553Spatrick
4446035553Spatrick    static unsigned hardware_concurrency() noexcept;
4546035553Spatrick};
4646035553Spatrick
4746035553Spatrickvoid swap(thread& x, thread& y) noexcept;
4846035553Spatrick
4946035553Spatrickclass thread::id
5046035553Spatrick{
5146035553Spatrickpublic:
5246035553Spatrick    id() noexcept;
5346035553Spatrick};
5446035553Spatrick
5546035553Spatrickbool operator==(thread::id x, thread::id y) noexcept;
56*4bdff4beSrobertbool operator!=(thread::id x, thread::id y) noexcept;             // removed in C++20
57*4bdff4beSrobertbool operator< (thread::id x, thread::id y) noexcept;             // removed in C++20
58*4bdff4beSrobertbool operator<=(thread::id x, thread::id y) noexcept;             // removed in C++20
59*4bdff4beSrobertbool operator> (thread::id x, thread::id y) noexcept;             // removed in C++20
60*4bdff4beSrobertbool operator>=(thread::id x, thread::id y) noexcept;             // removed in C++20
61*4bdff4beSrobertstrong_ordering operator<=>(thread::id x, thread::id y) noexcept; // C++20
6246035553Spatrick
6346035553Spatricktemplate<class charT, class traits>
6446035553Spatrickbasic_ostream<charT, traits>&
6546035553Spatrickoperator<<(basic_ostream<charT, traits>& out, thread::id id);
6646035553Spatrick
6746035553Spatricknamespace this_thread
6846035553Spatrick{
6946035553Spatrick
7046035553Spatrickthread::id get_id() noexcept;
7146035553Spatrick
7246035553Spatrickvoid yield() noexcept;
7346035553Spatrick
7446035553Spatricktemplate <class Clock, class Duration>
7546035553Spatrickvoid sleep_until(const chrono::time_point<Clock, Duration>& abs_time);
7646035553Spatrick
7746035553Spatricktemplate <class Rep, class Period>
7846035553Spatrickvoid sleep_for(const chrono::duration<Rep, Period>& rel_time);
7946035553Spatrick
8046035553Spatrick}  // this_thread
8146035553Spatrick
8246035553Spatrick}  // std
8346035553Spatrick
8446035553Spatrick*/
8546035553Spatrick
86*4bdff4beSrobert#include <__assert> // all public C++ headers provide the assertion handler
8746035553Spatrick#include <__config>
88*4bdff4beSrobert#include <__functional/hash.h>
89*4bdff4beSrobert#include <__memory/unique_ptr.h>
9076d0caaeSpatrick#include <__mutex_base>
91*4bdff4beSrobert#include <__thread/poll_with_backoff.h>
92*4bdff4beSrobert#include <__thread/timed_backoff_policy.h>
9376d0caaeSpatrick#include <__threading_support>
9476d0caaeSpatrick#include <__utility/forward.h>
9546035553Spatrick#include <cstddef>
9676d0caaeSpatrick#include <iosfwd>
9746035553Spatrick#include <system_error>
9846035553Spatrick#include <tuple>
9976d0caaeSpatrick#include <type_traits>
100*4bdff4beSrobert#include <version>
101*4bdff4beSrobert
102*4bdff4beSrobert// standard-mandated includes
103*4bdff4beSrobert
104*4bdff4beSrobert// [thread.syn]
105*4bdff4beSrobert#include <compare>
10646035553Spatrick
10746035553Spatrick#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
10846035553Spatrick#  pragma GCC system_header
10946035553Spatrick#endif
11046035553Spatrick
11146035553Spatrick_LIBCPP_PUSH_MACROS
11246035553Spatrick#include <__undef_macros>
11346035553Spatrick
11446035553Spatrick#ifdef _LIBCPP_HAS_NO_THREADS
115*4bdff4beSrobert# error "<thread> is not supported since libc++ has been configured without support for threads."
116*4bdff4beSrobert#endif
11746035553Spatrick
11846035553Spatrick_LIBCPP_BEGIN_NAMESPACE_STD
11946035553Spatrick
12046035553Spatricktemplate <class _Tp> class __thread_specific_ptr;
12146035553Spatrickclass _LIBCPP_TYPE_VIS __thread_struct;
12246035553Spatrickclass _LIBCPP_HIDDEN __thread_struct_imp;
12346035553Spatrickclass __assoc_sub_state;
12446035553Spatrick
12546035553Spatrick_LIBCPP_FUNC_VIS __thread_specific_ptr<__thread_struct>& __thread_local_data();
12646035553Spatrick
12746035553Spatrickclass _LIBCPP_TYPE_VIS __thread_struct
12846035553Spatrick{
12946035553Spatrick    __thread_struct_imp* __p_;
13046035553Spatrick
13146035553Spatrick    __thread_struct(const __thread_struct&);
13246035553Spatrick    __thread_struct& operator=(const __thread_struct&);
13346035553Spatrickpublic:
13446035553Spatrick    __thread_struct();
13546035553Spatrick    ~__thread_struct();
13646035553Spatrick
13746035553Spatrick    void notify_all_at_thread_exit(condition_variable*, mutex*);
13846035553Spatrick    void __make_ready_at_thread_exit(__assoc_sub_state*);
13946035553Spatrick};
14046035553Spatrick
14146035553Spatricktemplate <class _Tp>
14246035553Spatrickclass __thread_specific_ptr
14346035553Spatrick{
14446035553Spatrick    __libcpp_tls_key __key_;
14546035553Spatrick
14646035553Spatrick     // Only __thread_local_data() may construct a __thread_specific_ptr
14746035553Spatrick     // and only with _Tp == __thread_struct.
14846035553Spatrick    static_assert((is_same<_Tp, __thread_struct>::value), "");
14946035553Spatrick    __thread_specific_ptr();
15046035553Spatrick    friend _LIBCPP_FUNC_VIS __thread_specific_ptr<__thread_struct>& __thread_local_data();
15146035553Spatrick
15246035553Spatrick    __thread_specific_ptr(const __thread_specific_ptr&);
15346035553Spatrick    __thread_specific_ptr& operator=(const __thread_specific_ptr&);
15446035553Spatrick
15546035553Spatrick    _LIBCPP_HIDDEN static void _LIBCPP_TLS_DESTRUCTOR_CC __at_thread_exit(void*);
15646035553Spatrick
15746035553Spatrickpublic:
15846035553Spatrick    typedef _Tp* pointer;
15946035553Spatrick
16046035553Spatrick    ~__thread_specific_ptr();
16146035553Spatrick
16246035553Spatrick    _LIBCPP_INLINE_VISIBILITY
16346035553Spatrick    pointer get() const {return static_cast<_Tp*>(__libcpp_tls_get(__key_));}
16446035553Spatrick    _LIBCPP_INLINE_VISIBILITY
16546035553Spatrick    pointer operator*() const {return *get();}
16646035553Spatrick    _LIBCPP_INLINE_VISIBILITY
16746035553Spatrick    pointer operator->() const {return get();}
16846035553Spatrick    void set_pointer(pointer __p);
16946035553Spatrick};
17046035553Spatrick
17146035553Spatricktemplate <class _Tp>
17246035553Spatrickvoid _LIBCPP_TLS_DESTRUCTOR_CC
17346035553Spatrick__thread_specific_ptr<_Tp>::__at_thread_exit(void* __p)
17446035553Spatrick{
17546035553Spatrick    delete static_cast<pointer>(__p);
17646035553Spatrick}
17746035553Spatrick
17846035553Spatricktemplate <class _Tp>
17946035553Spatrick__thread_specific_ptr<_Tp>::__thread_specific_ptr()
18046035553Spatrick{
18146035553Spatrick  int __ec =
18246035553Spatrick      __libcpp_tls_create(&__key_, &__thread_specific_ptr::__at_thread_exit);
18346035553Spatrick  if (__ec)
18446035553Spatrick    __throw_system_error(__ec, "__thread_specific_ptr construction failed");
18546035553Spatrick}
18646035553Spatrick
18746035553Spatricktemplate <class _Tp>
18846035553Spatrick__thread_specific_ptr<_Tp>::~__thread_specific_ptr()
18946035553Spatrick{
19046035553Spatrick    // __thread_specific_ptr is only created with a static storage duration
19146035553Spatrick    // so this destructor is only invoked during program termination. Invoking
19246035553Spatrick    // pthread_key_delete(__key_) may prevent other threads from deleting their
19346035553Spatrick    // thread local data. For this reason we leak the key.
19446035553Spatrick}
19546035553Spatrick
19646035553Spatricktemplate <class _Tp>
19746035553Spatrickvoid
19846035553Spatrick__thread_specific_ptr<_Tp>::set_pointer(pointer __p)
19946035553Spatrick{
20046035553Spatrick    _LIBCPP_ASSERT(get() == nullptr,
20146035553Spatrick                   "Attempting to overwrite thread local data");
202*4bdff4beSrobert    std::__libcpp_tls_set(__key_, __p);
20346035553Spatrick}
20446035553Spatrick
20546035553Spatricktemplate<>
20646035553Spatrickstruct _LIBCPP_TEMPLATE_VIS hash<__thread_id>
207*4bdff4beSrobert    : public __unary_function<__thread_id, size_t>
20846035553Spatrick{
20946035553Spatrick    _LIBCPP_INLINE_VISIBILITY
21046035553Spatrick    size_t operator()(__thread_id __v) const _NOEXCEPT
21146035553Spatrick    {
21246035553Spatrick        return hash<__libcpp_thread_id>()(__v.__id_);
21346035553Spatrick    }
21446035553Spatrick};
21546035553Spatrick
21646035553Spatricktemplate<class _CharT, class _Traits>
21746035553Spatrick_LIBCPP_INLINE_VISIBILITY
21846035553Spatrickbasic_ostream<_CharT, _Traits>&
21946035553Spatrickoperator<<(basic_ostream<_CharT, _Traits>& __os, __thread_id __id)
22046035553Spatrick{return __os << __id.__id_;}
22146035553Spatrick
22246035553Spatrickclass _LIBCPP_TYPE_VIS thread
22346035553Spatrick{
22446035553Spatrick    __libcpp_thread_t __t_;
22546035553Spatrick
22646035553Spatrick    thread(const thread&);
22746035553Spatrick    thread& operator=(const thread&);
22846035553Spatrickpublic:
22946035553Spatrick    typedef __thread_id id;
23046035553Spatrick    typedef __libcpp_thread_t native_handle_type;
23146035553Spatrick
23246035553Spatrick    _LIBCPP_INLINE_VISIBILITY
23346035553Spatrick    thread() _NOEXCEPT : __t_(_LIBCPP_NULL_THREAD) {}
23446035553Spatrick#ifndef _LIBCPP_CXX03_LANG
23546035553Spatrick    template <class _Fp, class ..._Args,
236*4bdff4beSrobert              class = __enable_if_t<!is_same<__remove_cvref_t<_Fp>, thread>::value> >
23746035553Spatrick        _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
23846035553Spatrick        explicit thread(_Fp&& __f, _Args&&... __args);
23946035553Spatrick#else  // _LIBCPP_CXX03_LANG
24046035553Spatrick    template <class _Fp>
24146035553Spatrick    _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
24246035553Spatrick    explicit thread(_Fp __f);
24346035553Spatrick#endif
24446035553Spatrick    ~thread();
24546035553Spatrick
24646035553Spatrick    _LIBCPP_INLINE_VISIBILITY
247037e7968Spatrick    thread(thread&& __t) _NOEXCEPT : __t_(__t.__t_) {
248037e7968Spatrick        __t.__t_ = _LIBCPP_NULL_THREAD;
249037e7968Spatrick    }
250037e7968Spatrick
25146035553Spatrick    _LIBCPP_INLINE_VISIBILITY
252037e7968Spatrick    thread& operator=(thread&& __t) _NOEXCEPT {
253037e7968Spatrick        if (!__libcpp_thread_isnull(&__t_))
254037e7968Spatrick            terminate();
255037e7968Spatrick        __t_ = __t.__t_;
256037e7968Spatrick        __t.__t_ = _LIBCPP_NULL_THREAD;
257037e7968Spatrick        return *this;
258037e7968Spatrick    }
25946035553Spatrick
26046035553Spatrick    _LIBCPP_INLINE_VISIBILITY
26146035553Spatrick    void swap(thread& __t) _NOEXCEPT {_VSTD::swap(__t_, __t.__t_);}
26246035553Spatrick
26346035553Spatrick    _LIBCPP_INLINE_VISIBILITY
26446035553Spatrick    bool joinable() const _NOEXCEPT {return !__libcpp_thread_isnull(&__t_);}
26546035553Spatrick    void join();
26646035553Spatrick    void detach();
26746035553Spatrick    _LIBCPP_INLINE_VISIBILITY
26846035553Spatrick    id get_id() const _NOEXCEPT {return __libcpp_thread_get_id(&__t_);}
26946035553Spatrick    _LIBCPP_INLINE_VISIBILITY
27046035553Spatrick    native_handle_type native_handle() _NOEXCEPT {return __t_;}
27146035553Spatrick
27246035553Spatrick    static unsigned hardware_concurrency() _NOEXCEPT;
27346035553Spatrick};
27446035553Spatrick
27546035553Spatrick#ifndef _LIBCPP_CXX03_LANG
27646035553Spatrick
27746035553Spatricktemplate <class _TSp, class _Fp, class ..._Args, size_t ..._Indices>
27846035553Spatrickinline _LIBCPP_INLINE_VISIBILITY
27946035553Spatrickvoid
28046035553Spatrick__thread_execute(tuple<_TSp, _Fp, _Args...>& __t, __tuple_indices<_Indices...>)
28146035553Spatrick{
28276d0caaeSpatrick    _VSTD::__invoke(_VSTD::move(_VSTD::get<1>(__t)), _VSTD::move(_VSTD::get<_Indices>(__t))...);
28346035553Spatrick}
28446035553Spatrick
28546035553Spatricktemplate <class _Fp>
28646035553Spatrick_LIBCPP_INLINE_VISIBILITY
28746035553Spatrickvoid* __thread_proxy(void* __vp)
28846035553Spatrick{
28976d0caaeSpatrick    // _Fp = tuple< unique_ptr<__thread_struct>, Functor, Args...>
29076d0caaeSpatrick    unique_ptr<_Fp> __p(static_cast<_Fp*>(__vp));
29176d0caaeSpatrick    __thread_local_data().set_pointer(_VSTD::get<0>(*__p.get()).release());
29246035553Spatrick    typedef typename __make_tuple_indices<tuple_size<_Fp>::value, 2>::type _Index;
29376d0caaeSpatrick    _VSTD::__thread_execute(*__p.get(), _Index());
29446035553Spatrick    return nullptr;
29546035553Spatrick}
29646035553Spatrick
29746035553Spatricktemplate <class _Fp, class ..._Args,
29846035553Spatrick          class
29946035553Spatrick         >
30046035553Spatrickthread::thread(_Fp&& __f, _Args&&... __args)
30146035553Spatrick{
30246035553Spatrick    typedef unique_ptr<__thread_struct> _TSPtr;
30346035553Spatrick    _TSPtr __tsp(new __thread_struct);
30446035553Spatrick    typedef tuple<_TSPtr, typename decay<_Fp>::type, typename decay<_Args>::type...> _Gp;
30576d0caaeSpatrick    unique_ptr<_Gp> __p(
30676d0caaeSpatrick            new _Gp(_VSTD::move(__tsp),
307*4bdff4beSrobert                    _VSTD::forward<_Fp>(__f),
308*4bdff4beSrobert                    _VSTD::forward<_Args>(__args)...));
30976d0caaeSpatrick    int __ec = _VSTD::__libcpp_thread_create(&__t_, &__thread_proxy<_Gp>, __p.get());
31046035553Spatrick    if (__ec == 0)
31146035553Spatrick        __p.release();
31246035553Spatrick    else
31346035553Spatrick        __throw_system_error(__ec, "thread constructor failed");
31446035553Spatrick}
31546035553Spatrick
31646035553Spatrick#else  // _LIBCPP_CXX03_LANG
31746035553Spatrick
31846035553Spatricktemplate <class _Fp>
31946035553Spatrickstruct __thread_invoke_pair {
32046035553Spatrick    // This type is used to pass memory for thread local storage and a functor
32146035553Spatrick    // to a newly created thread because std::pair doesn't work with
32246035553Spatrick    // std::unique_ptr in C++03.
32346035553Spatrick    __thread_invoke_pair(_Fp& __f) : __tsp_(new __thread_struct), __fn_(__f) {}
32446035553Spatrick    unique_ptr<__thread_struct> __tsp_;
32546035553Spatrick    _Fp __fn_;
32646035553Spatrick};
32746035553Spatrick
32846035553Spatricktemplate <class _Fp>
329*4bdff4beSrobert_LIBCPP_HIDE_FROM_ABI void* __thread_proxy_cxx03(void* __vp)
33046035553Spatrick{
33176d0caaeSpatrick    unique_ptr<_Fp> __p(static_cast<_Fp*>(__vp));
33246035553Spatrick    __thread_local_data().set_pointer(__p->__tsp_.release());
33346035553Spatrick    (__p->__fn_)();
33446035553Spatrick    return nullptr;
33546035553Spatrick}
33646035553Spatrick
33746035553Spatricktemplate <class _Fp>
33846035553Spatrickthread::thread(_Fp __f)
33946035553Spatrick{
34046035553Spatrick
34146035553Spatrick    typedef __thread_invoke_pair<_Fp> _InvokePair;
34276d0caaeSpatrick    typedef unique_ptr<_InvokePair> _PairPtr;
34346035553Spatrick    _PairPtr __pp(new _InvokePair(__f));
34476d0caaeSpatrick    int __ec = _VSTD::__libcpp_thread_create(&__t_, &__thread_proxy_cxx03<_InvokePair>, __pp.get());
34546035553Spatrick    if (__ec == 0)
34646035553Spatrick        __pp.release();
34746035553Spatrick    else
34846035553Spatrick        __throw_system_error(__ec, "thread constructor failed");
34946035553Spatrick}
35046035553Spatrick
35146035553Spatrick#endif // _LIBCPP_CXX03_LANG
35246035553Spatrick
35346035553Spatrickinline _LIBCPP_INLINE_VISIBILITY
35446035553Spatrickvoid swap(thread& __x, thread& __y) _NOEXCEPT {__x.swap(__y);}
35546035553Spatrick
35646035553Spatricknamespace this_thread
35746035553Spatrick{
35846035553Spatrick
35946035553Spatrick_LIBCPP_FUNC_VIS void sleep_for(const chrono::nanoseconds& __ns);
36046035553Spatrick
36146035553Spatricktemplate <class _Rep, class _Period>
362*4bdff4beSrobert_LIBCPP_HIDE_FROM_ABI void
36346035553Spatricksleep_for(const chrono::duration<_Rep, _Period>& __d)
36446035553Spatrick{
36576d0caaeSpatrick    if (__d > chrono::duration<_Rep, _Period>::zero())
36646035553Spatrick    {
36776d0caaeSpatrick        // The standard guarantees a 64bit signed integer resolution for nanoseconds,
36876d0caaeSpatrick        // so use INT64_MAX / 1e9 as cut-off point. Use a constant to avoid <climits>
36976d0caaeSpatrick        // and issues with long double folding on PowerPC with GCC.
37076d0caaeSpatrick        _LIBCPP_CONSTEXPR chrono::duration<long double> _Max =
37176d0caaeSpatrick            chrono::duration<long double>(9223372036.0L);
37276d0caaeSpatrick        chrono::nanoseconds __ns;
37346035553Spatrick        if (__d < _Max)
37446035553Spatrick        {
37576d0caaeSpatrick            __ns = chrono::duration_cast<chrono::nanoseconds>(__d);
37646035553Spatrick            if (__ns < __d)
37746035553Spatrick                ++__ns;
37846035553Spatrick        }
37946035553Spatrick        else
38076d0caaeSpatrick            __ns = chrono::nanoseconds::max();
38176d0caaeSpatrick        this_thread::sleep_for(__ns);
38246035553Spatrick    }
38346035553Spatrick}
38446035553Spatrick
38546035553Spatricktemplate <class _Clock, class _Duration>
386*4bdff4beSrobert_LIBCPP_HIDE_FROM_ABI void
38746035553Spatricksleep_until(const chrono::time_point<_Clock, _Duration>& __t)
38846035553Spatrick{
38946035553Spatrick    mutex __mut;
39046035553Spatrick    condition_variable __cv;
39146035553Spatrick    unique_lock<mutex> __lk(__mut);
39246035553Spatrick    while (_Clock::now() < __t)
39346035553Spatrick        __cv.wait_until(__lk, __t);
39446035553Spatrick}
39546035553Spatrick
39646035553Spatricktemplate <class _Duration>
39746035553Spatrickinline _LIBCPP_INLINE_VISIBILITY
39846035553Spatrickvoid
39946035553Spatricksleep_until(const chrono::time_point<chrono::steady_clock, _Duration>& __t)
40046035553Spatrick{
40176d0caaeSpatrick    this_thread::sleep_for(__t - chrono::steady_clock::now());
40246035553Spatrick}
40346035553Spatrick
40446035553Spatrickinline _LIBCPP_INLINE_VISIBILITY
40546035553Spatrickvoid yield() _NOEXCEPT {__libcpp_thread_yield();}
40646035553Spatrick
407*4bdff4beSrobert} // namespace this_thread
40846035553Spatrick
40946035553Spatrick_LIBCPP_END_NAMESPACE_STD
41046035553Spatrick
41146035553Spatrick_LIBCPP_POP_MACROS
41246035553Spatrick
413*4bdff4beSrobert#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 17
414*4bdff4beSrobert#  include <chrono>
415*4bdff4beSrobert#endif
416*4bdff4beSrobert
417*4bdff4beSrobert#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
418*4bdff4beSrobert#  include <functional>
419*4bdff4beSrobert#endif
420*4bdff4beSrobert
42146035553Spatrick#endif // _LIBCPP_THREAD
422