Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "base/compiler_specific.h" | 5 #include "base/compiler_specific.h" |
| 6 #include "base/macros.h" | 6 #include "base/macros.h" |
| 7 #include "base/synchronization/waitable_event.h" | 7 #include "base/synchronization/waitable_event.h" |
| 8 #include "base/threading/platform_thread.h" | 8 #include "base/threading/platform_thread.h" |
| 9 #include "testing/gtest/include/gtest/gtest.h" | 9 #include "testing/gtest/include/gtest/gtest.h" |
| 10 | 10 |
| 11 #if defined(OS_WIN) | 11 #if defined(OS_POSIX) |
| 12 #include <sys/types.h> | |
| 13 #include <unistd.h> | |
| 14 #elif defined(OS_WIN) | |
| 12 #include <windows.h> | 15 #include <windows.h> |
| 13 #endif | 16 #endif |
| 14 | 17 |
| 15 namespace base { | 18 namespace base { |
| 16 | 19 |
| 17 // Trivial tests that thread runs and doesn't crash on create and join --------- | 20 // Trivial tests that thread runs and doesn't crash on create and join --------- |
| 18 | 21 |
| 19 class TrivialThread : public PlatformThread::Delegate { | 22 class TrivialThread : public PlatformThread::Delegate { |
| 20 public: | 23 public: |
| 21 TrivialThread() : did_run_(false) {} | 24 TrivialThread() : did_run_(false) {} |
| (...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 163 for (size_t n = 0; n < arraysize(thread); n++) | 166 for (size_t n = 0; n < arraysize(thread); n++) |
| 164 ASSERT_FALSE(thread[n].IsRunning()); | 167 ASSERT_FALSE(thread[n].IsRunning()); |
| 165 | 168 |
| 166 // Make sure that the thread ID is the same across calls. | 169 // Make sure that the thread ID is the same across calls. |
| 167 EXPECT_EQ(main_thread_id, PlatformThread::CurrentId()); | 170 EXPECT_EQ(main_thread_id, PlatformThread::CurrentId()); |
| 168 } | 171 } |
| 169 | 172 |
| 170 namespace { | 173 namespace { |
| 171 | 174 |
| 172 const ThreadPriority kThreadPriorityTestValues[] = { | 175 const ThreadPriority kThreadPriorityTestValues[] = { |
| 173 // Disable non-normal priority toggling on POSIX as it appears to be broken | 176 // The order should be higher to lower to cover as much cases as possible on |
| 174 // (http://crbug.com/468793). This is prefered to disabling the tests altogether | 177 // Linux trybots running without CAP_SYS_NICE permission. |
| 175 // on POSIX as it at least provides coverage for running this code under | 178 #if !defined(OS_ANDROID) |
| 176 // "normal" priority. | 179 // PlatformThread::GetCurrentThreadPriority() on Android does not support |
| 177 #if !defined(OS_POSIX) | 180 // REALTIME_AUDIO case. See http://crbug.com/505474. |
| 181 ThreadPriority::REALTIME_AUDIO, | |
| 182 #endif | |
| 178 ThreadPriority::DISPLAY, | 183 ThreadPriority::DISPLAY, |
| 179 ThreadPriority::REALTIME_AUDIO, | 184 // This redundant BACKGROUND priority is to test backgrounding from other |
| 180 // Keep BACKGROUND second to last to test backgrounding from other | 185 // priorities, and unbackgrounding. |
| 181 // priorities. | |
| 182 ThreadPriority::BACKGROUND, | 186 ThreadPriority::BACKGROUND, |
| 183 #endif // !defined(OS_POSIX) | 187 ThreadPriority::NORMAL, |
| 184 // Keep NORMAL last to test unbackgrounding. | 188 ThreadPriority::BACKGROUND}; |
| 185 ThreadPriority::NORMAL | 189 |
| 186 }; | 190 bool IsBumpingPriorityAllowed() { |
| 191 #if defined(OS_POSIX) | |
| 192 // Only root can raise thread priority on POSIX environment. On Linux, users | |
| 193 // who have CAP_SYS_NICE permission also can raise the thread priority, but | |
| 194 // libcap.so would be needed to check the capability. | |
| 195 return geteuid() == 0; | |
| 196 #else | |
| 197 return true; | |
| 198 #endif | |
| 199 } | |
| 187 | 200 |
| 188 } // namespace | 201 } // namespace |
| 189 | 202 |
| 190 // Test changing another thread's priority. | 203 #if defined(OS_MACOSX) |
| 191 // NOTE: This test is partially disabled on POSIX, see note above and | 204 // PlatformThread::GetCurrentThreadPriority() is not implemented on OS X. |
| 192 // http://crbug.com/468793. | 205 #define MAYBE_ThreadPriorityCurrentThread DISABLED_ThreadPriorityCurrentThread |
| 193 TEST(PlatformThreadTest, ThreadPriorityOtherThread) { | 206 #else |
| 194 PlatformThreadHandle current_handle(PlatformThread::CurrentHandle()); | 207 #define MAYBE_ThreadPriorityCurrentThread ThreadPriorityCurrentThread |
| 195 | 208 #endif |
| 196 // Confirm that the current thread's priority is as expected. | |
| 197 EXPECT_EQ(ThreadPriority::NORMAL, | |
| 198 PlatformThread::GetThreadPriority(current_handle)); | |
| 199 | |
| 200 // Create a test thread. | |
| 201 FunctionTestThread thread; | |
| 202 PlatformThreadHandle handle; | |
| 203 ASSERT_TRUE(PlatformThread::Create(0, &thread, &handle)); | |
| 204 thread.WaitForThreadStart(); | |
| 205 EXPECT_NE(thread.thread_id(), kInvalidThreadId); | |
| 206 EXPECT_NE(thread.thread_id(), PlatformThread::CurrentId()); | |
| 207 | |
| 208 // New threads should get normal priority by default. | |
| 209 EXPECT_EQ(ThreadPriority::NORMAL, PlatformThread::GetThreadPriority(handle)); | |
| 210 | |
| 211 // Toggle each supported priority on the test thread and confirm it only | |
| 212 // affects it (and not the current thread). | |
| 213 for (size_t i = 0; i < arraysize(kThreadPriorityTestValues); ++i) { | |
| 214 SCOPED_TRACE(i); | |
| 215 | |
| 216 // Alter and verify the test thread's priority. | |
| 217 PlatformThread::SetThreadPriority(handle, kThreadPriorityTestValues[i]); | |
| 218 EXPECT_EQ(kThreadPriorityTestValues[i], | |
| 219 PlatformThread::GetThreadPriority(handle)); | |
| 220 | |
| 221 // Make sure the current thread was otherwise unaffected. | |
| 222 EXPECT_EQ(ThreadPriority::NORMAL, | |
| 223 PlatformThread::GetThreadPriority(current_handle)); | |
| 224 } | |
| 225 | |
| 226 thread.MarkForTermination(); | |
| 227 PlatformThread::Join(handle); | |
| 228 } | |
| 229 | 209 |
| 230 // Test changing the current thread's priority (which has different semantics on | 210 // Test changing the current thread's priority (which has different semantics on |
| 231 // some platforms). | 211 // some platforms). |
| 232 // NOTE: This test is partially disabled on POSIX, see note above and | 212 TEST(PlatformThreadTest, MAYBE_ThreadPriorityCurrentThread) { |
| 233 // http://crbug.com/468793. | 213 // Confirm that the current thread's priority is as expected. |
| 234 TEST(PlatformThreadTest, ThreadPriorityCurrentThread) { | 214 EXPECT_EQ(ThreadPriority::NORMAL, PlatformThread::GetCurrentThreadPriority()); |
| 235 PlatformThreadHandle current_handle(PlatformThread::CurrentHandle()); | |
| 236 | 215 |
| 237 // Confirm that the current thread's priority is as expected. | 216 // Toggle each supported priority on the current thread and confirm it |
| 238 EXPECT_EQ(ThreadPriority::NORMAL, | 217 // affects it. |
| 239 PlatformThread::GetThreadPriority(current_handle)); | 218 const bool bumping_priority_allowed = IsBumpingPriorityAllowed(); |
| 240 | |
| 241 // Create a test thread for verification purposes only. | |
| 242 FunctionTestThread thread; | |
| 243 PlatformThreadHandle handle; | |
| 244 ASSERT_TRUE(PlatformThread::Create(0, &thread, &handle)); | |
| 245 thread.WaitForThreadStart(); | |
| 246 EXPECT_NE(thread.thread_id(), kInvalidThreadId); | |
| 247 EXPECT_NE(thread.thread_id(), PlatformThread::CurrentId()); | |
| 248 | |
| 249 // Confirm that the new thread's priority is as expected. | |
| 250 EXPECT_EQ(ThreadPriority::NORMAL, PlatformThread::GetThreadPriority(handle)); | |
| 251 | |
| 252 // Toggle each supported priority on the current thread and confirm it only | |
| 253 // affects it (and not the test thread). | |
| 254 for (size_t i = 0; i < arraysize(kThreadPriorityTestValues); ++i) { | 219 for (size_t i = 0; i < arraysize(kThreadPriorityTestValues); ++i) { |
| 255 SCOPED_TRACE(i); | 220 SCOPED_TRACE(i); |
| 221 if (!bumping_priority_allowed && | |
| 222 kThreadPriorityTestValues[i] > | |
| 223 PlatformThread::GetCurrentThreadPriority()) { | |
| 224 continue; | |
| 225 } | |
| 256 | 226 |
| 257 // Alter and verify the current thread's priority. | 227 // Alter and verify the current thread's priority. |
| 258 PlatformThread::SetThreadPriority(current_handle, | 228 PlatformThread::SetCurrentThreadPriority(kThreadPriorityTestValues[i]); |
| 259 kThreadPriorityTestValues[i]); | |
| 260 EXPECT_EQ(kThreadPriorityTestValues[i], | 229 EXPECT_EQ(kThreadPriorityTestValues[i], |
| 261 PlatformThread::GetThreadPriority(current_handle)); | 230 PlatformThread::GetCurrentThreadPriority()); |
| 262 | |
| 263 // Make sure the test thread was otherwise unaffected. | |
| 264 EXPECT_EQ(ThreadPriority::NORMAL, | |
| 265 PlatformThread::GetThreadPriority(handle)); | |
| 266 } | 231 } |
| 267 | 232 |
| 268 // Restore current thread priority for follow-up tests. | 233 // Restore current thread priority for follow-up tests. |
| 269 PlatformThread::SetThreadPriority(current_handle, ThreadPriority::NORMAL); | 234 PlatformThread::SetCurrentThreadPriority(ThreadPriority::NORMAL); |
|
Nico
2015/07/14 04:53:33
Is this not a bump in practice? (From background t
Takashi Toyoshima
2015/07/14 05:22:17
That's true. If this could be a serious issue, I'l
| |
| 270 | |
| 271 thread.MarkForTermination(); | |
| 272 PlatformThread::Join(handle); | |
| 273 } | 235 } |
| 274 | 236 |
| 275 } // namespace base | 237 } // namespace base |
| OLD | NEW |