1*b1e83836Smrg // std::this_thread::sleep_for/until declarations -*- C++ -*-
2*b1e83836Smrg
3*b1e83836Smrg // Copyright (C) 2008-2022 Free Software Foundation, Inc.
4*b1e83836Smrg //
5*b1e83836Smrg // This file is part of the GNU ISO C++ Library. This library is free
6*b1e83836Smrg // software; you can redistribute it and/or modify it under the
7*b1e83836Smrg // terms of the GNU General Public License as published by the
8*b1e83836Smrg // Free Software Foundation; either version 3, or (at your option)
9*b1e83836Smrg // any later version.
10*b1e83836Smrg
11*b1e83836Smrg // This library is distributed in the hope that it will be useful,
12*b1e83836Smrg // but WITHOUT ANY WARRANTY; without even the implied warranty of
13*b1e83836Smrg // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14*b1e83836Smrg // GNU General Public License for more details.
15*b1e83836Smrg
16*b1e83836Smrg // Under Section 7 of GPL version 3, you are granted additional
17*b1e83836Smrg // permissions described in the GCC Runtime Library Exception, version
18*b1e83836Smrg // 3.1, as published by the Free Software Foundation.
19*b1e83836Smrg
20*b1e83836Smrg // You should have received a copy of the GNU General Public License and
21*b1e83836Smrg // a copy of the GCC Runtime Library Exception along with this program;
22*b1e83836Smrg // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
23*b1e83836Smrg // <http://www.gnu.org/licenses/>.
24*b1e83836Smrg
25*b1e83836Smrg /** @file bits/this_thread_sleep.h
26*b1e83836Smrg * This is an internal header file, included by other library headers.
27*b1e83836Smrg * Do not attempt to use it directly. @headername{thread}
28*b1e83836Smrg */
29*b1e83836Smrg
30*b1e83836Smrg #ifndef _GLIBCXX_THIS_THREAD_SLEEP_H
31*b1e83836Smrg #define _GLIBCXX_THIS_THREAD_SLEEP_H 1
32*b1e83836Smrg
33*b1e83836Smrg #pragma GCC system_header
34*b1e83836Smrg
35*b1e83836Smrg #if __cplusplus >= 201103L
36*b1e83836Smrg #include <bits/chrono.h> // std::chrono::*
37*b1e83836Smrg
38*b1e83836Smrg #ifdef _GLIBCXX_USE_NANOSLEEP
39*b1e83836Smrg # include <cerrno> // errno, EINTR
40*b1e83836Smrg # include <time.h> // nanosleep
41*b1e83836Smrg #endif
42*b1e83836Smrg
_GLIBCXX_VISIBILITY(default)43*b1e83836Smrg namespace std _GLIBCXX_VISIBILITY(default)
44*b1e83836Smrg {
45*b1e83836Smrg _GLIBCXX_BEGIN_NAMESPACE_VERSION
46*b1e83836Smrg
47*b1e83836Smrg /** @addtogroup threads
48*b1e83836Smrg * @{
49*b1e83836Smrg */
50*b1e83836Smrg
51*b1e83836Smrg /** @namespace std::this_thread
52*b1e83836Smrg * @brief ISO C++ 2011 namespace for interacting with the current thread
53*b1e83836Smrg *
54*b1e83836Smrg * C++11 30.3.2 [thread.thread.this] Namespace this_thread.
55*b1e83836Smrg */
56*b1e83836Smrg namespace this_thread
57*b1e83836Smrg {
58*b1e83836Smrg #ifndef _GLIBCXX_NO_SLEEP
59*b1e83836Smrg
60*b1e83836Smrg #ifndef _GLIBCXX_USE_NANOSLEEP
61*b1e83836Smrg void
62*b1e83836Smrg __sleep_for(chrono::seconds, chrono::nanoseconds);
63*b1e83836Smrg #endif
64*b1e83836Smrg
65*b1e83836Smrg /// this_thread::sleep_for
66*b1e83836Smrg template<typename _Rep, typename _Period>
67*b1e83836Smrg inline void
68*b1e83836Smrg sleep_for(const chrono::duration<_Rep, _Period>& __rtime)
69*b1e83836Smrg {
70*b1e83836Smrg if (__rtime <= __rtime.zero())
71*b1e83836Smrg return;
72*b1e83836Smrg auto __s = chrono::duration_cast<chrono::seconds>(__rtime);
73*b1e83836Smrg auto __ns = chrono::duration_cast<chrono::nanoseconds>(__rtime - __s);
74*b1e83836Smrg #ifdef _GLIBCXX_USE_NANOSLEEP
75*b1e83836Smrg struct ::timespec __ts =
76*b1e83836Smrg {
77*b1e83836Smrg static_cast<std::time_t>(__s.count()),
78*b1e83836Smrg static_cast<long>(__ns.count())
79*b1e83836Smrg };
80*b1e83836Smrg while (::nanosleep(&__ts, &__ts) == -1 && errno == EINTR)
81*b1e83836Smrg { }
82*b1e83836Smrg #else
83*b1e83836Smrg __sleep_for(__s, __ns);
84*b1e83836Smrg #endif
85*b1e83836Smrg }
86*b1e83836Smrg
87*b1e83836Smrg /// this_thread::sleep_until
88*b1e83836Smrg template<typename _Clock, typename _Duration>
89*b1e83836Smrg inline void
90*b1e83836Smrg sleep_until(const chrono::time_point<_Clock, _Duration>& __atime)
91*b1e83836Smrg {
92*b1e83836Smrg #if __cplusplus > 201703L
93*b1e83836Smrg static_assert(chrono::is_clock_v<_Clock>);
94*b1e83836Smrg #endif
95*b1e83836Smrg auto __now = _Clock::now();
96*b1e83836Smrg if (_Clock::is_steady)
97*b1e83836Smrg {
98*b1e83836Smrg if (__now < __atime)
99*b1e83836Smrg sleep_for(__atime - __now);
100*b1e83836Smrg return;
101*b1e83836Smrg }
102*b1e83836Smrg while (__now < __atime)
103*b1e83836Smrg {
104*b1e83836Smrg sleep_for(__atime - __now);
105*b1e83836Smrg __now = _Clock::now();
106*b1e83836Smrg }
107*b1e83836Smrg }
108*b1e83836Smrg #endif // ! NO_SLEEP
109*b1e83836Smrg } // namespace this_thread
110*b1e83836Smrg
111*b1e83836Smrg /// @}
112*b1e83836Smrg
113*b1e83836Smrg _GLIBCXX_END_NAMESPACE_VERSION
114*b1e83836Smrg } // namespace
115*b1e83836Smrg #endif // C++11
116*b1e83836Smrg
117*b1e83836Smrg #endif // _GLIBCXX_THIS_THREAD_SLEEP_H
118