1*06c3fb27SDimitry Andric // -*- C++ -*- 2*06c3fb27SDimitry Andric //===----------------------------------------------------------------------===// 3*06c3fb27SDimitry Andric // 4*06c3fb27SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 5*06c3fb27SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 6*06c3fb27SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 7*06c3fb27SDimitry Andric // 8*06c3fb27SDimitry Andric //===----------------------------------------------------------------------===// 9*06c3fb27SDimitry Andric 10*06c3fb27SDimitry Andric #ifndef _LIBCPP___THREAD_THIS_THREAD_H 11*06c3fb27SDimitry Andric #define _LIBCPP___THREAD_THIS_THREAD_H 12*06c3fb27SDimitry Andric 13*06c3fb27SDimitry Andric #include <__chrono/steady_clock.h> 14*06c3fb27SDimitry Andric #include <__chrono/time_point.h> 15*06c3fb27SDimitry Andric #include <__condition_variable/condition_variable.h> 16*06c3fb27SDimitry Andric #include <__config> 17*06c3fb27SDimitry Andric #include <__mutex/mutex.h> 18*06c3fb27SDimitry Andric #include <__mutex/unique_lock.h> 19*06c3fb27SDimitry Andric #include <__threading_support> 20*06c3fb27SDimitry Andric 21*06c3fb27SDimitry Andric #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 22*06c3fb27SDimitry Andric # pragma GCC system_header 23*06c3fb27SDimitry Andric #endif 24*06c3fb27SDimitry Andric 25*06c3fb27SDimitry Andric _LIBCPP_PUSH_MACROS 26*06c3fb27SDimitry Andric #include <__undef_macros> 27*06c3fb27SDimitry Andric 28*06c3fb27SDimitry Andric _LIBCPP_BEGIN_NAMESPACE_STD 29*06c3fb27SDimitry Andric 30*06c3fb27SDimitry Andric namespace this_thread 31*06c3fb27SDimitry Andric { 32*06c3fb27SDimitry Andric 33*06c3fb27SDimitry Andric _LIBCPP_EXPORTED_FROM_ABI void sleep_for(const chrono::nanoseconds& __ns); 34*06c3fb27SDimitry Andric 35*06c3fb27SDimitry Andric template <class _Rep, class _Period> 36*06c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI void 37*06c3fb27SDimitry Andric sleep_for(const chrono::duration<_Rep, _Period>& __d) 38*06c3fb27SDimitry Andric { 39*06c3fb27SDimitry Andric if (__d > chrono::duration<_Rep, _Period>::zero()) 40*06c3fb27SDimitry Andric { 41*06c3fb27SDimitry Andric // The standard guarantees a 64bit signed integer resolution for nanoseconds, 42*06c3fb27SDimitry Andric // so use INT64_MAX / 1e9 as cut-off point. Use a constant to avoid <climits> 43*06c3fb27SDimitry Andric // and issues with long double folding on PowerPC with GCC. 44*06c3fb27SDimitry Andric _LIBCPP_CONSTEXPR chrono::duration<long double> __max = 45*06c3fb27SDimitry Andric chrono::duration<long double>(9223372036.0L); 46*06c3fb27SDimitry Andric chrono::nanoseconds __ns; 47*06c3fb27SDimitry Andric if (__d < __max) 48*06c3fb27SDimitry Andric { 49*06c3fb27SDimitry Andric __ns = chrono::duration_cast<chrono::nanoseconds>(__d); 50*06c3fb27SDimitry Andric if (__ns < __d) 51*06c3fb27SDimitry Andric ++__ns; 52*06c3fb27SDimitry Andric } 53*06c3fb27SDimitry Andric else 54*06c3fb27SDimitry Andric __ns = chrono::nanoseconds::max(); 55*06c3fb27SDimitry Andric this_thread::sleep_for(__ns); 56*06c3fb27SDimitry Andric } 57*06c3fb27SDimitry Andric } 58*06c3fb27SDimitry Andric 59*06c3fb27SDimitry Andric template <class _Clock, class _Duration> 60*06c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI void 61*06c3fb27SDimitry Andric sleep_until(const chrono::time_point<_Clock, _Duration>& __t) 62*06c3fb27SDimitry Andric { 63*06c3fb27SDimitry Andric mutex __mut; 64*06c3fb27SDimitry Andric condition_variable __cv; 65*06c3fb27SDimitry Andric unique_lock<mutex> __lk(__mut); 66*06c3fb27SDimitry Andric while (_Clock::now() < __t) 67*06c3fb27SDimitry Andric __cv.wait_until(__lk, __t); 68*06c3fb27SDimitry Andric } 69*06c3fb27SDimitry Andric 70*06c3fb27SDimitry Andric template <class _Duration> 71*06c3fb27SDimitry Andric inline _LIBCPP_INLINE_VISIBILITY 72*06c3fb27SDimitry Andric void 73*06c3fb27SDimitry Andric sleep_until(const chrono::time_point<chrono::steady_clock, _Duration>& __t) 74*06c3fb27SDimitry Andric { 75*06c3fb27SDimitry Andric this_thread::sleep_for(__t - chrono::steady_clock::now()); 76*06c3fb27SDimitry Andric } 77*06c3fb27SDimitry Andric 78*06c3fb27SDimitry Andric inline _LIBCPP_INLINE_VISIBILITY 79*06c3fb27SDimitry Andric void yield() _NOEXCEPT {__libcpp_thread_yield();} 80*06c3fb27SDimitry Andric 81*06c3fb27SDimitry Andric } // namespace this_thread 82*06c3fb27SDimitry Andric 83*06c3fb27SDimitry Andric _LIBCPP_END_NAMESPACE_STD 84*06c3fb27SDimitry Andric 85*06c3fb27SDimitry Andric _LIBCPP_POP_MACROS 86*06c3fb27SDimitry Andric 87*06c3fb27SDimitry Andric #endif // _LIBCPP___THREAD_THIS_THREAD_H 88