106c3fb27SDimitry Andric // -*- C++ -*-
206c3fb27SDimitry Andric //===----------------------------------------------------------------------===//
306c3fb27SDimitry Andric //
406c3fb27SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
506c3fb27SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
606c3fb27SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
706c3fb27SDimitry Andric //
806c3fb27SDimitry Andric //===----------------------------------------------------------------------===//
906c3fb27SDimitry Andric 
1006c3fb27SDimitry Andric #ifndef _LIBCPP___THREAD_THIS_THREAD_H
1106c3fb27SDimitry Andric #define _LIBCPP___THREAD_THIS_THREAD_H
1206c3fb27SDimitry Andric 
1306c3fb27SDimitry Andric #include <__chrono/steady_clock.h>
1406c3fb27SDimitry Andric #include <__chrono/time_point.h>
1506c3fb27SDimitry Andric #include <__condition_variable/condition_variable.h>
1606c3fb27SDimitry Andric #include <__config>
1706c3fb27SDimitry Andric #include <__mutex/mutex.h>
1806c3fb27SDimitry Andric #include <__mutex/unique_lock.h>
1906c3fb27SDimitry Andric #include <__threading_support>
2006c3fb27SDimitry Andric 
2106c3fb27SDimitry Andric #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
2206c3fb27SDimitry Andric #  pragma GCC system_header
2306c3fb27SDimitry Andric #endif
2406c3fb27SDimitry Andric 
2506c3fb27SDimitry Andric _LIBCPP_PUSH_MACROS
2606c3fb27SDimitry Andric #include <__undef_macros>
2706c3fb27SDimitry Andric 
2806c3fb27SDimitry Andric _LIBCPP_BEGIN_NAMESPACE_STD
2906c3fb27SDimitry Andric 
30*cb14a3feSDimitry Andric namespace this_thread {
3106c3fb27SDimitry Andric 
3206c3fb27SDimitry Andric _LIBCPP_EXPORTED_FROM_ABI void sleep_for(const chrono::nanoseconds& __ns);
3306c3fb27SDimitry Andric 
3406c3fb27SDimitry Andric template <class _Rep, class _Period>
sleep_for(const chrono::duration<_Rep,_Period> & __d)35*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI void sleep_for(const chrono::duration<_Rep, _Period>& __d) {
36*cb14a3feSDimitry Andric   if (__d > chrono::duration<_Rep, _Period>::zero()) {
3706c3fb27SDimitry Andric     // The standard guarantees a 64bit signed integer resolution for nanoseconds,
3806c3fb27SDimitry Andric     // so use INT64_MAX / 1e9 as cut-off point. Use a constant to avoid <climits>
3906c3fb27SDimitry Andric     // and issues with long double folding on PowerPC with GCC.
40*cb14a3feSDimitry Andric     _LIBCPP_CONSTEXPR chrono::duration<long double> __max = chrono::duration<long double>(9223372036.0L);
4106c3fb27SDimitry Andric     chrono::nanoseconds __ns;
42*cb14a3feSDimitry Andric     if (__d < __max) {
4306c3fb27SDimitry Andric       __ns = chrono::duration_cast<chrono::nanoseconds>(__d);
4406c3fb27SDimitry Andric       if (__ns < __d)
4506c3fb27SDimitry Andric         ++__ns;
46*cb14a3feSDimitry Andric     } else
4706c3fb27SDimitry Andric       __ns = chrono::nanoseconds::max();
4806c3fb27SDimitry Andric     this_thread::sleep_for(__ns);
4906c3fb27SDimitry Andric   }
5006c3fb27SDimitry Andric }
5106c3fb27SDimitry Andric 
5206c3fb27SDimitry Andric template <class _Clock, class _Duration>
sleep_until(const chrono::time_point<_Clock,_Duration> & __t)53*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI void sleep_until(const chrono::time_point<_Clock, _Duration>& __t) {
5406c3fb27SDimitry Andric   mutex __mut;
5506c3fb27SDimitry Andric   condition_variable __cv;
5606c3fb27SDimitry Andric   unique_lock<mutex> __lk(__mut);
5706c3fb27SDimitry Andric   while (_Clock::now() < __t)
5806c3fb27SDimitry Andric     __cv.wait_until(__lk, __t);
5906c3fb27SDimitry Andric }
6006c3fb27SDimitry Andric 
6106c3fb27SDimitry Andric template <class _Duration>
sleep_until(const chrono::time_point<chrono::steady_clock,_Duration> & __t)62*cb14a3feSDimitry Andric inline _LIBCPP_HIDE_FROM_ABI void sleep_until(const chrono::time_point<chrono::steady_clock, _Duration>& __t) {
6306c3fb27SDimitry Andric   this_thread::sleep_for(__t - chrono::steady_clock::now());
6406c3fb27SDimitry Andric }
6506c3fb27SDimitry Andric 
yield()66*cb14a3feSDimitry Andric inline _LIBCPP_HIDE_FROM_ABI void yield() _NOEXCEPT { __libcpp_thread_yield(); }
6706c3fb27SDimitry Andric 
6806c3fb27SDimitry Andric } // namespace this_thread
6906c3fb27SDimitry Andric 
7006c3fb27SDimitry Andric _LIBCPP_END_NAMESPACE_STD
7106c3fb27SDimitry Andric 
7206c3fb27SDimitry Andric _LIBCPP_POP_MACROS
7306c3fb27SDimitry Andric 
7406c3fb27SDimitry Andric #endif // _LIBCPP___THREAD_THIS_THREAD_H
75