blob: b6f6766dccac463b68d5e8e8c909fb42417ae93e [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
11#include <memory>
12#include <algorithm>
13#include "webrtc/base/cpu_time.h"
14#include "webrtc/base/platform_thread.h"
15#include "webrtc/base/timeutils.h"
16#include "webrtc/test/gtest.h"
17#include "webrtc/system_wrappers/include/cpu_info.h"
ilnik78f2d212017-02-28 02:24:10 -080018#include "webrtc/system_wrappers/include/sleep.h"
ilnik531100d2017-02-21 03:33:24 -080019
20namespace {
21const int kAllowedErrorMillisecs = 30;
22const int kProcessingTimeMillisecs = 300;
ilnik78f2d212017-02-28 02:24:10 -080023const int kWorkingThreads = 2;
ilnik531100d2017-02-21 03:33:24 -080024
ilnik78f2d212017-02-28 02:24:10 -080025// Consumes approximately kProcessingTimeMillisecs of CPU time in single thread.
ilnik531100d2017-02-21 03:33:24 -080026bool WorkingFunction(void* counter_pointer) {
27 int64_t* counter = reinterpret_cast<int64_t*>(counter_pointer);
28 *counter = 0;
ilnik78f2d212017-02-28 02:24:10 -080029 int64_t stop_cpu_time =
30 rtc::GetThreadCpuTimeNanos() +
31 kProcessingTimeMillisecs * rtc::kNumNanosecsPerMillisec;
32 while (rtc::GetThreadCpuTimeNanos() < stop_cpu_time) {
ilnik531100d2017-02-21 03:33:24 -080033 (*counter)++;
34 }
35 return false;
36}
37} // namespace
38
39namespace rtc {
40
ilnik78f2d212017-02-28 02:24:10 -080041TEST(CpuTimeTest, TwoThreads) {
42 int64_t process_start_time_nanos = GetProcessCpuTimeNanos();
43 int64_t thread_start_time_nanos = GetThreadCpuTimeNanos();
ilnik531100d2017-02-21 03:33:24 -080044 int64_t counter1;
45 int64_t counter2;
46 PlatformThread thread1(WorkingFunction, reinterpret_cast<void*>(&counter1),
47 "Thread1");
48 PlatformThread thread2(WorkingFunction, reinterpret_cast<void*>(&counter2),
49 "Thread2");
50 thread1.Start();
51 thread2.Start();
52 thread1.Stop();
53 thread2.Stop();
54
55 EXPECT_GE(counter1, 0);
56 EXPECT_GE(counter2, 0);
ilnik78f2d212017-02-28 02:24:10 -080057 int64_t process_duration_nanos =
58 GetProcessCpuTimeNanos() - process_start_time_nanos;
59 int64_t thread_duration_nanos =
60 GetThreadCpuTimeNanos() - thread_start_time_nanos;
61 // This thread did almost nothing.
62 // Therefore GetThreadCpuTime is not a wall clock.
63 EXPECT_LE(thread_duration_nanos,
64 kAllowedErrorMillisecs * kNumNanosecsPerMillisec);
ilnik3e530d22017-03-09 00:41:31 -080065 // Total process time is at least twice working threads' CPU time.
ilnik78f2d212017-02-28 02:24:10 -080066 // Therefore process and thread times are correctly related.
ilnik3e530d22017-03-09 00:41:31 -080067 EXPECT_GE(
ilnik78f2d212017-02-28 02:24:10 -080068 process_duration_nanos,
ilnik3e530d22017-03-09 00:41:31 -080069 kWorkingThreads * (kProcessingTimeMillisecs - kAllowedErrorMillisecs)
70 * kNumNanosecsPerMillisec);
ilnik531100d2017-02-21 03:33:24 -080071}
72
ilnik78f2d212017-02-28 02:24:10 -080073TEST(CpuTimeTest, Sleeping) {
74 int64_t process_start_time_nanos = GetProcessCpuTimeNanos();
75 webrtc::SleepMs(kProcessingTimeMillisecs);
76 int64_t process_duration_nanos =
77 GetProcessCpuTimeNanos() - process_start_time_nanos;
78 // Sleeping should not introduce any additional CPU time.
79 // Therefore GetProcessCpuTime is not a wall clock.
80 EXPECT_LE(process_duration_nanos,
81 kWorkingThreads * kAllowedErrorMillisecs * kNumNanosecsPerMillisec);
ilnik531100d2017-02-21 03:33:24 -080082}
83
84} // namespace rtc