]> git.ipfire.org Git - thirdparty/gcc.git/blame - libstdc++-v3/testsuite/30_threads/future/members/poll.cc
Update copyright years.
[thirdparty/gcc.git] / libstdc++-v3 / testsuite / 30_threads / future / members / poll.cc
CommitLineData
a945c346 1// Copyright (C) 2020-2024 Free Software Foundation, Inc.
93fc4774
JW
2//
3// This file is part of the GNU ISO C++ Library. This library is free
4// software; you can redistribute it and/or modify it under the
5// terms of the GNU General Public License as published by the
6// Free Software Foundation; either version 3, or (at your option)
7// any later version.
8
9// This library is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12// GNU General Public License for more details.
13
14// You should have received a copy of the GNU General Public License along
15// with this library; see the file COPYING3. If not see
16// <http://www.gnu.org/licenses/>.
17
18// { dg-options "-O3" }
19// { dg-do run { target c++11 } }
8c4e33d2
JW
20// { dg-additional-options "-pthread" { target pthread } }
21// { dg-require-gthreads "" }
93fc4774
JW
22
23#include <future>
24#include <chrono>
25#include <iostream>
26#include <testsuite_hooks.h>
27
3651c1b5 28int iterations = 200;
93fc4774
JW
29
30using namespace std;
31
32template<typename Duration>
33double
34print(const char* desc, Duration dur)
35{
36 auto ns = chrono::duration_cast<chrono::nanoseconds>(dur).count();
37 double d = double(ns) / iterations;
38 cout << desc << ": " << ns << "ns for " << iterations
39 << " calls, avg " << d << "ns per call\n";
40 return d;
41}
42
43int main()
44{
45 promise<int> p;
46 future<int> f = p.get_future();
47
3651c1b5 48 start_over:
93fc4774
JW
49 auto start = chrono::high_resolution_clock::now();
50 for(int i = 0; i < iterations; i++)
51 f.wait_for(chrono::seconds(0));
52 auto stop = chrono::high_resolution_clock::now();
3651c1b5
AO
53
54 /* We've run too few iterations for the clock resolution.
55 Attempt to calibrate it. */
56 if (start == stop)
57 {
eadf009b
AO
58 /* After set_value, wait_for is faster, so use that for the
59 calibration to avoid zero at low clock resultions. */
60 promise<int> pc;
61 future<int> fc = pc.get_future();
62 pc.set_value(1);
63
3651c1b5
AO
64 /* Loop until the clock advances, so that start is right after a
65 time increment. */
66 do
67 start = chrono::high_resolution_clock::now();
68 while (start == stop);
69 int i = 0;
70 /* Now until the clock advances again, so that stop is right
71 after another time increment. */
72 do
73 {
eadf009b 74 fc.wait_for(chrono::seconds(0));
3651c1b5
AO
75 stop = chrono::high_resolution_clock::now();
76 i++;
77 }
78 while (start == stop);
79 /* Go for some 10 cycles, but if we're already past that and
80 still get into the calibration loop, double the iteration
81 count and try again. */
82 if (iterations < i * 10)
83 iterations = i * 10;
84 else
85 iterations *= 2;
86 goto start_over;
87 }
88
93fc4774
JW
89 double wait_for_0 = print("wait_for(0s)", stop - start);
90
91 start = chrono::high_resolution_clock::now();
92 for(int i = 0; i < iterations; i++)
8c4e33d2 93 f.wait_until(chrono::system_clock::time_point::min());
93fc4774 94 stop = chrono::high_resolution_clock::now();
8c4e33d2
JW
95 double wait_until_sys_min __attribute__((unused))
96 = print("wait_until(system_clock minimum)", stop - start);
93fc4774
JW
97
98 start = chrono::high_resolution_clock::now();
99 for(int i = 0; i < iterations; i++)
8c4e33d2 100 f.wait_until(chrono::steady_clock::time_point::min());
93fc4774 101 stop = chrono::high_resolution_clock::now();
8c4e33d2
JW
102 double wait_until_steady_min __attribute__((unused))
103 = print("wait_until(steady_clock minimum)", stop - start);
93fc4774
JW
104
105 start = chrono::high_resolution_clock::now();
106 for(int i = 0; i < iterations; i++)
8c4e33d2 107 f.wait_until(chrono::system_clock::time_point());
93fc4774 108 stop = chrono::high_resolution_clock::now();
8c4e33d2
JW
109 double wait_until_sys_epoch __attribute__((unused))
110 = print("wait_until(system_clock epoch)", stop - start);
93fc4774
JW
111
112 start = chrono::high_resolution_clock::now();
113 for(int i = 0; i < iterations; i++)
8c4e33d2 114 f.wait_until(chrono::steady_clock::time_point());
93fc4774 115 stop = chrono::high_resolution_clock::now();
8c4e33d2
JW
116 double wait_until_steady_epoch __attribute__((unused))
117 = print("wait_until(steady_clock epoch", stop - start);
93fc4774
JW
118
119 p.set_value(1);
120
121 start = chrono::high_resolution_clock::now();
122 for(int i = 0; i < iterations; i++)
123 f.wait_for(chrono::seconds(0));
124 stop = chrono::high_resolution_clock::now();
125 double ready = print("wait_for when ready", stop - start);
126
8c4e33d2 127 // Polling before ready with wait_for(0s) should be almost as fast as
93fc4774 128 // after the result is ready.
8c4e33d2
JW
129 VERIFY( wait_for_0 < (ready * 30) );
130
131 // Polling before ready using wait_until(min) should not be terribly slow.
132 VERIFY( wait_until_sys_min < (ready * 100) );
133 VERIFY( wait_until_steady_min < (ready * 100) );
93fc4774
JW
134
135 // The following two tests fail with GCC 11, see
136 // https://gcc.gnu.org/pipermail/libstdc++/2020-November/051422.html
137#if 0
8c4e33d2 138 // Polling before ready using wait_until(epoch) should not be terribly slow.
93fc4774
JW
139 VERIFY( wait_until_sys_epoch < (ready * 100) );
140 VERIFY( wait_until_steady_epoch < (ready * 100) );
141#endif
93fc4774 142}