xref: /llvm-project/libcxx/include/__thread/this_thread.h (revision c6f3b7bcd0596d30f8dabecdfb9e44f9a07b6e4c)
1cea42859SHui // -*- C++ -*-
2cea42859SHui //===----------------------------------------------------------------------===//
3cea42859SHui //
4cea42859SHui // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5cea42859SHui // See https://llvm.org/LICENSE.txt for license information.
6cea42859SHui // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7cea42859SHui //
8cea42859SHui //===----------------------------------------------------------------------===//
9cea42859SHui 
10cea42859SHui #ifndef _LIBCPP___THREAD_THIS_THREAD_H
11cea42859SHui #define _LIBCPP___THREAD_THIS_THREAD_H
12cea42859SHui 
1309e3a360SLouis Dionne #include <__chrono/duration.h>
14cea42859SHui #include <__chrono/steady_clock.h>
15cea42859SHui #include <__chrono/time_point.h>
16cea42859SHui #include <__condition_variable/condition_variable.h>
17cea42859SHui #include <__config>
18cea42859SHui #include <__mutex/mutex.h>
19cea42859SHui #include <__mutex/unique_lock.h>
207162fd75SLouis Dionne #include <__thread/support.h>
21cea42859SHui 
22cea42859SHui #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
23cea42859SHui #  pragma GCC system_header
24cea42859SHui #endif
25cea42859SHui 
26cea42859SHui _LIBCPP_PUSH_MACROS
27cea42859SHui #include <__undef_macros>
28cea42859SHui 
29cea42859SHui _LIBCPP_BEGIN_NAMESPACE_STD
30cea42859SHui 
319783f28cSLouis Dionne namespace this_thread {
32cea42859SHui 
33*c6f3b7bcSNikolas Klauser #if _LIBCPP_HAS_THREADS
3487d56c59SLouis Dionne 
35cea42859SHui _LIBCPP_EXPORTED_FROM_ABI void sleep_for(const chrono::nanoseconds& __ns);
36cea42859SHui 
37cea42859SHui template <class _Rep, class _Period>
389783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI void sleep_for(const chrono::duration<_Rep, _Period>& __d) {
399783f28cSLouis Dionne   if (__d > chrono::duration<_Rep, _Period>::zero()) {
40cea42859SHui     // The standard guarantees a 64bit signed integer resolution for nanoseconds,
41cea42859SHui     // so use INT64_MAX / 1e9 as cut-off point. Use a constant to avoid <climits>
42cea42859SHui     // and issues with long double folding on PowerPC with GCC.
439783f28cSLouis Dionne     _LIBCPP_CONSTEXPR chrono::duration<long double> __max = chrono::duration<long double>(9223372036.0L);
44cea42859SHui     chrono::nanoseconds __ns;
459783f28cSLouis Dionne     if (__d < __max) {
46cea42859SHui       __ns = chrono::duration_cast<chrono::nanoseconds>(__d);
47cea42859SHui       if (__ns < __d)
48cea42859SHui         ++__ns;
499783f28cSLouis Dionne     } else
50cea42859SHui       __ns = chrono::nanoseconds::max();
51cea42859SHui     this_thread::sleep_for(__ns);
52cea42859SHui   }
53cea42859SHui }
54cea42859SHui 
55cea42859SHui template <class _Clock, class _Duration>
569783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI void sleep_until(const chrono::time_point<_Clock, _Duration>& __t) {
57cea42859SHui   mutex __mut;
58cea42859SHui   condition_variable __cv;
59cea42859SHui   unique_lock<mutex> __lk(__mut);
60cea42859SHui   while (_Clock::now() < __t)
61cea42859SHui     __cv.wait_until(__lk, __t);
62cea42859SHui }
63cea42859SHui 
64cea42859SHui template <class _Duration>
659783f28cSLouis Dionne inline _LIBCPP_HIDE_FROM_ABI void sleep_until(const chrono::time_point<chrono::steady_clock, _Duration>& __t) {
66cea42859SHui   this_thread::sleep_for(__t - chrono::steady_clock::now());
67cea42859SHui }
68cea42859SHui 
699783f28cSLouis Dionne inline _LIBCPP_HIDE_FROM_ABI void yield() _NOEXCEPT { __libcpp_thread_yield(); }
70cea42859SHui 
71*c6f3b7bcSNikolas Klauser #endif // _LIBCPP_HAS_THREADS
7287d56c59SLouis Dionne 
73cea42859SHui } // namespace this_thread
74cea42859SHui 
75cea42859SHui _LIBCPP_END_NAMESPACE_STD
76cea42859SHui 
77cea42859SHui _LIBCPP_POP_MACROS
78cea42859SHui 
79cea42859SHui #endif // _LIBCPP___THREAD_THIS_THREAD_H
80