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> 19*0fca6ea1SDimitry Andric #include <__thread/support.h> 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 30cb14a3feSDimitry 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> 35cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI void sleep_for(const chrono::duration<_Rep, _Period>& __d) { 36cb14a3feSDimitry 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. 40cb14a3feSDimitry Andric _LIBCPP_CONSTEXPR chrono::duration<long double> __max = chrono::duration<long double>(9223372036.0L); 4106c3fb27SDimitry Andric chrono::nanoseconds __ns; 42cb14a3feSDimitry Andric if (__d < __max) { 4306c3fb27SDimitry Andric __ns = chrono::duration_cast<chrono::nanoseconds>(__d); 4406c3fb27SDimitry Andric if (__ns < __d) 4506c3fb27SDimitry Andric ++__ns; 46cb14a3feSDimitry 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> 53cb14a3feSDimitry 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> 62cb14a3feSDimitry 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 66cb14a3feSDimitry 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