2 * Copyright 2004-present Facebook, Inc.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
18 #include <glog/logging.h>
20 #include <folly/io/async/test/TimeUtil.h>
21 #include <folly/portability/GTest.h>
22 #include <folly/portability/Unistd.h>
24 using folly::TimePoint;
25 using namespace std::literals::chrono_literals;
26 using std::chrono::duration_cast;
27 using std::chrono::milliseconds;
28 using std::chrono::nanoseconds;
29 using std::chrono::steady_clock;
31 // Define a PrintTo() function for std::chrono::nanoseconds so that these
32 // will be printed nicely on EXPECT*() failures.
33 // Define this in std::chrono so that argument-dependent lookup works.
36 static inline void PrintTo(nanoseconds ns, ::std::ostream* os) {
37 *os << ns.count() << "ns";
43 void runThread(nanoseconds duration, nanoseconds* timeWaiting) {
46 // Loop consuming CPU until the duration has expired.
49 if (now.getTimeStart() - start.getTimeStart() > duration) {
51 // Report how long we spent waiting to be scheduled on the CPU.
52 *timeWaiting = (now.getTimeWaiting() - start.getTimeWaiting());
53 VLOG(1) << "thread " << start.getTid() << ": elapsed "
54 << duration_cast<milliseconds>(
55 now.getTimeStart() - start.getTimeStart())
57 << "ms, time waiting: "
58 << duration_cast<milliseconds>(*timeWaiting).count() << "ms";
64 // Test to make sure that TimePoint computes sane values for time
65 // spent waiting on CPU.
66 TEST(TimeUtil, getTimeWaiting) {
69 // Run twice as many threads as CPU cores, to ensure that some of
70 // them should be waiting sometime.
71 auto numThreads = sysconf(_SC_NPROCESSORS_CONF) * 2;
73 std::vector<std::thread> threads;
74 std::vector<nanoseconds> timeWaiting;
75 timeWaiting.resize(numThreads, 0ns);
77 auto start = steady_clock::now();
78 for (int n = 0; n < numThreads; ++n) {
79 threads.emplace_back(runThread, 1s, &timeWaiting[n]);
82 for (auto& thread : threads) {
85 auto end = steady_clock::now();
87 auto timeSpent = end - start;
89 for (int n = 0; n < numThreads; ++n) {
90 max = std::max(max, timeWaiting[n]);
91 // No thread could possibly have been waiting for longer than
92 // the test actually took to run.
93 EXPECT_LT(timeWaiting[n], timeSpent);
95 // Make sure that at least one thread spent some time waiting