blob: b5e0f67c001c1384513fc67c0be0d7704002bb3a [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.
ilnik531100d2017-02-21 03:33:24 -080033bool WorkingFunction(void* counter_pointer) {
34 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 }
42 return false;
43}
44} // namespace
45
46namespace rtc {
47
deadbeef7311b242017-05-01 10:43:39 -070048// A minimal test which can be run on instrumented builds, so that they're at
49// least exercising the code to check for memory leaks/etc.
50TEST(CpuTimeTest, BasicTest) {
51 int64_t process_start_time_nanos = GetProcessCpuTimeNanos();
52 int64_t thread_start_time_nanos = GetThreadCpuTimeNanos();
53 int64_t process_duration_nanos =
54 GetProcessCpuTimeNanos() - process_start_time_nanos;
55 int64_t thread_duration_nanos =
56 GetThreadCpuTimeNanos() - thread_start_time_nanos;
57 EXPECT_GE(process_duration_nanos, 0);
58 EXPECT_GE(thread_duration_nanos, 0);
59}
60
61TEST(CpuTimeTest, MAYBE_TEST(TwoThreads)) {
ilnik78f2d212017-02-28 02:24:10 -080062 int64_t process_start_time_nanos = GetProcessCpuTimeNanos();
63 int64_t thread_start_time_nanos = GetThreadCpuTimeNanos();
ilnik531100d2017-02-21 03:33:24 -080064 int64_t counter1;
65 int64_t counter2;
66 PlatformThread thread1(WorkingFunction, reinterpret_cast<void*>(&counter1),
67 "Thread1");
68 PlatformThread thread2(WorkingFunction, reinterpret_cast<void*>(&counter2),
69 "Thread2");
70 thread1.Start();
71 thread2.Start();
72 thread1.Stop();
73 thread2.Stop();
74
75 EXPECT_GE(counter1, 0);
76 EXPECT_GE(counter2, 0);
ilnik78f2d212017-02-28 02:24:10 -080077 int64_t process_duration_nanos =
78 GetProcessCpuTimeNanos() - process_start_time_nanos;
79 int64_t thread_duration_nanos =
80 GetThreadCpuTimeNanos() - thread_start_time_nanos;
81 // This thread did almost nothing.
82 // Therefore GetThreadCpuTime is not a wall clock.
83 EXPECT_LE(thread_duration_nanos,
84 kAllowedErrorMillisecs * kNumNanosecsPerMillisec);
ilnik3e530d22017-03-09 00:41:31 -080085 // Total process time is at least twice working threads' CPU time.
ilnik78f2d212017-02-28 02:24:10 -080086 // Therefore process and thread times are correctly related.
Yves Gerey665174f2018-06-19 15:03:05 +020087 EXPECT_GE(process_duration_nanos,
88 kWorkingThreads *
89 (kProcessingTimeMillisecs - kAllowedErrorMillisecs) *
90 kNumNanosecsPerMillisec);
ilnik531100d2017-02-21 03:33:24 -080091}
92
deadbeef7311b242017-05-01 10:43:39 -070093TEST(CpuTimeTest, MAYBE_TEST(Sleeping)) {
ilnik78f2d212017-02-28 02:24:10 -080094 int64_t process_start_time_nanos = GetProcessCpuTimeNanos();
95 webrtc::SleepMs(kProcessingTimeMillisecs);
96 int64_t process_duration_nanos =
97 GetProcessCpuTimeNanos() - process_start_time_nanos;
98 // Sleeping should not introduce any additional CPU time.
99 // Therefore GetProcessCpuTime is not a wall clock.
100 EXPECT_LE(process_duration_nanos,
101 kWorkingThreads * kAllowedErrorMillisecs * kNumNanosecsPerMillisec);
ilnik531100d2017-02-21 03:33:24 -0800102}
103
104} // namespace rtc