blob: 79f0a4036fc4b06987f0bdcdf00376f206432315 [file] [log] [blame]
ilnik531100d2017-02-21 03:33:24 -08001/*
2 * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020011#include "rtc_base/cpu_time.h"
Yves Gerey3e707812018-11-28 16:47:49 +010012
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020013#include "rtc_base/platform_thread.h"
Steve Anton10542f22019-01-11 09:11:00 -080014#include "rtc_base/time_utils.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020015#include "system_wrappers/include/sleep.h"
16#include "test/gtest.h"
ilnik531100d2017-02-21 03:33:24 -080017
deadbeef7311b242017-05-01 10:43:39 -070018// Only run these tests on non-instrumented builds, because timing on
19// instrumented builds is unreliable, causing the test to be flaky.
20#if defined(THREAD_SANITIZER) || defined(MEMORY_SANITIZER) || \
21 defined(ADDRESS_SANITIZER)
22#define MAYBE_TEST(test_name) DISABLED_##test_name
23#else
24#define MAYBE_TEST(test_name) test_name
25#endif
26
ilnik531100d2017-02-21 03:33:24 -080027namespace {
28const int kAllowedErrorMillisecs = 30;
29const int kProcessingTimeMillisecs = 300;
ilnik78f2d212017-02-28 02:24:10 -080030const int kWorkingThreads = 2;
ilnik531100d2017-02-21 03:33:24 -080031
ilnik78f2d212017-02-28 02:24:10 -080032// Consumes approximately kProcessingTimeMillisecs of CPU time in single thread.
Niels Möller4731f002019-05-03 09:34:24 +020033void WorkingFunction(void* counter_pointer) {
ilnik531100d2017-02-21 03:33:24 -080034 int64_t* counter = reinterpret_cast<int64_t*>(counter_pointer);
35 *counter = 0;
ilnik78f2d212017-02-28 02:24:10 -080036 int64_t stop_cpu_time =
37 rtc::GetThreadCpuTimeNanos() +
38 kProcessingTimeMillisecs * rtc::kNumNanosecsPerMillisec;
39 while (rtc::GetThreadCpuTimeNanos() < stop_cpu_time) {
ilnik531100d2017-02-21 03:33:24 -080040 (*counter)++;
41 }
ilnik531100d2017-02-21 03:33:24 -080042}
43} // namespace
44
45namespace rtc {
46
deadbeef7311b242017-05-01 10:43:39 -070047// A minimal test which can be run on instrumented builds, so that they're at
48// least exercising the code to check for memory leaks/etc.
49TEST(CpuTimeTest, BasicTest) {
50 int64_t process_start_time_nanos = GetProcessCpuTimeNanos();
51 int64_t thread_start_time_nanos = GetThreadCpuTimeNanos();
52 int64_t process_duration_nanos =
53 GetProcessCpuTimeNanos() - process_start_time_nanos;
54 int64_t thread_duration_nanos =
55 GetThreadCpuTimeNanos() - thread_start_time_nanos;
56 EXPECT_GE(process_duration_nanos, 0);
57 EXPECT_GE(thread_duration_nanos, 0);
58}
59
60TEST(CpuTimeTest, MAYBE_TEST(TwoThreads)) {
ilnik78f2d212017-02-28 02:24:10 -080061 int64_t process_start_time_nanos = GetProcessCpuTimeNanos();
62 int64_t thread_start_time_nanos = GetThreadCpuTimeNanos();
ilnik531100d2017-02-21 03:33:24 -080063 int64_t counter1;
64 int64_t counter2;
65 PlatformThread thread1(WorkingFunction, reinterpret_cast<void*>(&counter1),
66 "Thread1");
67 PlatformThread thread2(WorkingFunction, reinterpret_cast<void*>(&counter2),
68 "Thread2");
69 thread1.Start();
70 thread2.Start();
71 thread1.Stop();
72 thread2.Stop();
73
74 EXPECT_GE(counter1, 0);
75 EXPECT_GE(counter2, 0);
ilnik78f2d212017-02-28 02:24:10 -080076 int64_t process_duration_nanos =
77 GetProcessCpuTimeNanos() - process_start_time_nanos;
78 int64_t thread_duration_nanos =
79 GetThreadCpuTimeNanos() - thread_start_time_nanos;
80 // This thread did almost nothing.
81 // Therefore GetThreadCpuTime is not a wall clock.
82 EXPECT_LE(thread_duration_nanos,
83 kAllowedErrorMillisecs * kNumNanosecsPerMillisec);
ilnik3e530d22017-03-09 00:41:31 -080084 // Total process time is at least twice working threads' CPU time.
ilnik78f2d212017-02-28 02:24:10 -080085 // Therefore process and thread times are correctly related.
Yves Gerey665174f2018-06-19 15:03:05 +020086 EXPECT_GE(process_duration_nanos,
87 kWorkingThreads *
88 (kProcessingTimeMillisecs - kAllowedErrorMillisecs) *
89 kNumNanosecsPerMillisec);
ilnik531100d2017-02-21 03:33:24 -080090}
91
deadbeef7311b242017-05-01 10:43:39 -070092TEST(CpuTimeTest, MAYBE_TEST(Sleeping)) {
ilnik78f2d212017-02-28 02:24:10 -080093 int64_t process_start_time_nanos = GetProcessCpuTimeNanos();
94 webrtc::SleepMs(kProcessingTimeMillisecs);
95 int64_t process_duration_nanos =
96 GetProcessCpuTimeNanos() - process_start_time_nanos;
97 // Sleeping should not introduce any additional CPU time.
98 // Therefore GetProcessCpuTime is not a wall clock.
99 EXPECT_LE(process_duration_nanos,
100 kWorkingThreads * kAllowedErrorMillisecs * kNumNanosecsPerMillisec);
ilnik531100d2017-02-21 03:33:24 -0800101}
102
103} // namespace rtc