[M94 Dev][Tizen] Fix for errors for generating ninja files
[platform/framework/web/chromium-efl.git] / base / cpu_affinity_posix_unittest.cc
1 // Copyright 2020 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "base/cpu_affinity_posix.h"
6
7 #include <sched.h>
8
9 #include <string>
10
11 #include "base/synchronization/waitable_event.h"
12 #include "base/system/sys_info.h"
13 #include "base/threading/platform_thread.h"
14 #include "base/threading/thread.h"
15 #include "build/build_config.h"
16 #include "testing/gtest/include/gtest/gtest.h"
17
18 namespace base {
19
20 namespace {
21
22 class TestThread : public PlatformThread::Delegate {
23  public:
24   TestThread()
25       : termination_ready_(WaitableEvent::ResetPolicy::MANUAL,
26                            WaitableEvent::InitialState::NOT_SIGNALED),
27         terminate_thread_(WaitableEvent::ResetPolicy::MANUAL,
28                           WaitableEvent::InitialState::NOT_SIGNALED) {}
29   TestThread(const TestThread&) = delete;
30   TestThread& operator=(const TestThread&) = delete;
31   ~TestThread() override {
32     EXPECT_TRUE(terminate_thread_.IsSignaled())
33         << "Need to mark thread for termination and join the underlying thread "
34         << "before destroying a FunctionTestThread as it owns the "
35         << "WaitableEvent blocking the underlying thread's main.";
36   }
37
38   // Grabs |thread_id_|, signals |termination_ready_|, and then waits for
39   // |terminate_thread_| to be signaled before exiting.
40   void ThreadMain() override {
41     thread_id_ = PlatformThread::CurrentId();
42     EXPECT_NE(thread_id_, kInvalidThreadId);
43
44     // Make sure that the thread ID is the same across calls.
45     EXPECT_EQ(thread_id_, PlatformThread::CurrentId());
46
47     termination_ready_.Signal();
48     terminate_thread_.Wait();
49
50     done_ = true;
51   }
52
53   PlatformThreadId thread_id() const {
54     EXPECT_TRUE(termination_ready_.IsSignaled()) << "Thread ID still unknown";
55     return thread_id_;
56   }
57
58   bool IsRunning() const { return termination_ready_.IsSignaled() && !done_; }
59
60   // Blocks until this thread is started and ready to be terminated.
61   void WaitForTerminationReady() { termination_ready_.Wait(); }
62
63   // Marks this thread for termination (callers must then join this thread to be
64   // guaranteed of termination).
65   void MarkForTermination() { terminate_thread_.Signal(); }
66
67  private:
68   PlatformThreadId thread_id_ = kInvalidThreadId;
69
70   mutable WaitableEvent termination_ready_;
71   WaitableEvent terminate_thread_;
72   bool done_ = false;
73 };
74
75 }  // namespace
76
77 #if defined(OS_ANDROID)
78 #define MAYBE_SetThreadCpuAffinityMode SetThreadCpuAffinityMode
79 #else
80 // The test only considers Android device hardware models at the moment. Some
81 // CrOS devices on the waterfall have asymmetric CPUs that aren't covered. The
82 // linux-trusty-rel bot also fails to sched_setaffinity().
83 #define MAYBE_SetThreadCpuAffinityMode DISABLED_SetThreadCpuAffinityMode
84 #endif
85 TEST(CpuAffinityTest, MAYBE_SetThreadCpuAffinityMode) {
86   // This test currently only supports Nexus 5x and Pixel devices as big.LITTLE
87   // devices. For other devices, we assume that the cores are symmetric. This is
88   // currently the case for the devices on our waterfalls.
89   std::string device_model = SysInfo::HardwareModelName();
90   int expected_total_cores = SysInfo::SysInfo::NumberOfProcessors();
91   int expected_little_cores = expected_total_cores;
92   if (device_model == "Nexus 5X" || device_model == "Pixel 2" ||
93       device_model == "Pixel 2 XL" || device_model == "Pixel 3" ||
94       device_model == "Pixel 3 XL" || device_model == "Pixel 4" ||
95       device_model == "Pixel 4 XL") {
96     expected_little_cores = 4;
97     EXPECT_LT(expected_little_cores, expected_total_cores);
98   } else if (device_model == "Pixel" || device_model == "Pixel XL") {
99     expected_little_cores = 2;
100     EXPECT_LT(expected_little_cores, expected_total_cores);
101   } else if (device_model == "Pixel 3a" || device_model == "Pixel 3a XL") {
102     expected_little_cores = 6;
103     EXPECT_LT(expected_little_cores, expected_total_cores);
104   } else if (device_model == "Nexus 5" || device_model == "Nexus 7") {
105     // On our Nexus 5 and Nexus 7 bots, something else in the system seems to
106     // set affinity for the test process, making these tests flaky
107     // (crbug.com/1113964).
108     return;
109   }
110
111   TestThread thread;
112   PlatformThreadHandle handle;
113   ASSERT_TRUE(PlatformThread::Create(0, &thread, &handle));
114   thread.WaitForTerminationReady();
115   ASSERT_TRUE(thread.IsRunning());
116
117   PlatformThreadId thread_id = thread.thread_id();
118   cpu_set_t set;
119
120   EXPECT_TRUE(
121       SetThreadCpuAffinityMode(thread_id, CpuAffinityMode::kLittleCoresOnly));
122   EXPECT_EQ(sched_getaffinity(thread_id, sizeof(set), &set), 0);
123
124   EXPECT_EQ(CPU_COUNT(&set), expected_little_cores);
125
126   EXPECT_TRUE(SetThreadCpuAffinityMode(thread_id, CpuAffinityMode::kDefault));
127   EXPECT_EQ(sched_getaffinity(thread_id, sizeof(set), &set), 0);
128
129   EXPECT_EQ(CPU_COUNT(&set), expected_total_cores);
130
131   thread.MarkForTermination();
132   PlatformThread::Join(handle);
133   ASSERT_FALSE(thread.IsRunning());
134 }
135
136 }  // namespace base