• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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 
11 #include "rtc_base/cpu_time.h"
12 
13 #include "rtc_base/platform_thread.h"
14 #include "rtc_base/time_utils.h"
15 #include "system_wrappers/include/sleep.h"
16 #include "test/gtest.h"
17 
18 // 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 
27 namespace {
28 const int kAllowedErrorMillisecs = 30;
29 const int kProcessingTimeMillisecs = 500;
30 const int kWorkingThreads = 2;
31 
32 // Consumes approximately kProcessingTimeMillisecs of CPU time in single thread.
WorkingFunction(int64_t * counter)33 void WorkingFunction(int64_t* counter) {
34   *counter = 0;
35   int64_t stop_cpu_time =
36       rtc::GetThreadCpuTimeNanos() +
37       kProcessingTimeMillisecs * rtc::kNumNanosecsPerMillisec;
38   while (rtc::GetThreadCpuTimeNanos() < stop_cpu_time) {
39     (*counter)++;
40   }
41 }
42 }  // namespace
43 
44 namespace rtc {
45 
46 // A minimal test which can be run on instrumented builds, so that they're at
47 // least exercising the code to check for memory leaks/etc.
TEST(CpuTimeTest,BasicTest)48 TEST(CpuTimeTest, BasicTest) {
49   int64_t process_start_time_nanos = GetProcessCpuTimeNanos();
50   int64_t thread_start_time_nanos = GetThreadCpuTimeNanos();
51   int64_t process_duration_nanos =
52       GetProcessCpuTimeNanos() - process_start_time_nanos;
53   int64_t thread_duration_nanos =
54       GetThreadCpuTimeNanos() - thread_start_time_nanos;
55   EXPECT_GE(process_duration_nanos, 0);
56   EXPECT_GE(thread_duration_nanos, 0);
57 }
58 
TEST(CpuTimeTest,MAYBE_TEST (TwoThreads))59 TEST(CpuTimeTest, MAYBE_TEST(TwoThreads)) {
60   int64_t process_start_time_nanos = GetProcessCpuTimeNanos();
61   int64_t thread_start_time_nanos = GetThreadCpuTimeNanos();
62   int64_t counter1;
63   int64_t counter2;
64   auto thread1 = PlatformThread::SpawnJoinable(
65       [&counter1] { WorkingFunction(&counter1); }, "Thread1");
66   auto thread2 = PlatformThread::SpawnJoinable(
67       [&counter2] { WorkingFunction(&counter2); }, "Thread2");
68   thread1.Finalize();
69   thread2.Finalize();
70 
71   EXPECT_GE(counter1, 0);
72   EXPECT_GE(counter2, 0);
73   int64_t process_duration_nanos =
74       GetProcessCpuTimeNanos() - process_start_time_nanos;
75   int64_t thread_duration_nanos =
76       GetThreadCpuTimeNanos() - thread_start_time_nanos;
77   // This thread did almost nothing. Definetly less work than kProcessingTime.
78   // Therefore GetThreadCpuTime is not a wall clock.
79   EXPECT_LE(thread_duration_nanos,
80             (kProcessingTimeMillisecs - kAllowedErrorMillisecs) *
81                 kNumNanosecsPerMillisec);
82   // Total process time is at least twice working threads' CPU time.
83   // Therefore process and thread times are correctly related.
84   EXPECT_GE(process_duration_nanos,
85             kWorkingThreads *
86                 (kProcessingTimeMillisecs - kAllowedErrorMillisecs) *
87                 kNumNanosecsPerMillisec);
88 }
89 
TEST(CpuTimeTest,MAYBE_TEST (Sleeping))90 TEST(CpuTimeTest, MAYBE_TEST(Sleeping)) {
91   int64_t process_start_time_nanos = GetProcessCpuTimeNanos();
92   webrtc::SleepMs(kProcessingTimeMillisecs);
93   int64_t process_duration_nanos =
94       GetProcessCpuTimeNanos() - process_start_time_nanos;
95   // Sleeping should not introduce any additional CPU time.
96   // Therefore GetProcessCpuTime is not a wall clock.
97   EXPECT_LE(process_duration_nanos,
98             (kProcessingTimeMillisecs - kAllowedErrorMillisecs) *
99                 kNumNanosecsPerMillisec);
100 }
101 
102 }  // namespace rtc
103