Commit eb1903ca authored by Francois Doray's avatar Francois Doray Committed by Commit Bot

[Base] Change CanIncreaseCurrentThreadPriority() to CanIncreaseThreadPriority(ThreadPriority).

The function is renamed from CanIncreaseCurrentThreadPriority() to
CanIncreaseThreadPriority() so it's clear that it doesn't return a
per-thread value.

Also, a ThreadPriority argument is added to allow implementations to
return a different value depending on the target priority. On Linux
for example, a priority increase should succeed if the target priority
is within the range allowed by RLIMIT_NICE.

This is a no-op CL from an execution point of view.

Bug: 816389
Change-Id: I98cb640527cc2cccb85db45395210e41d6bc5f64
Reviewed-on: https://chromium-review.googlesource.com/1187506
Commit-Queue: François Doray <fdoray@chromium.org>
Reviewed-by: default avatarGabriel Charette <gab@chromium.org>
Cr-Commit-Position: refs/heads/master@{#589432}
parent a5e2774c
...@@ -28,13 +28,13 @@ bool CanUseBackgroundPriorityForSchedulerWorker() { ...@@ -28,13 +28,13 @@ bool CanUseBackgroundPriorityForSchedulerWorker() {
return false; return false;
#if !defined(OS_ANDROID) #if !defined(OS_ANDROID)
// When thread priority can't be increased, run all threads with a normal // When thread priority can't be increased to NORMAL, run all threads with a
// priority to avoid priority inversions on shutdown (TaskScheduler increases // NORMAL priority to avoid priority inversions on shutdown (TaskScheduler
// background threads priority to normal on shutdown while resolving remaining // increases BACKGROUND threads priority to NORMAL on shutdown while resolving
// shutdown blocking tasks). // remaining shutdown blocking tasks).
// //
// This is ignored on Android, because it doesn't have a clean shutdown phase. // This is ignored on Android, because it doesn't have a clean shutdown phase.
if (!PlatformThread::CanIncreaseCurrentThreadPriority()) if (!PlatformThread::CanIncreaseThreadPriority(ThreadPriority::NORMAL))
return false; return false;
#endif // defined(OS_ANDROID) #endif // defined(OS_ANDROID)
......
...@@ -196,9 +196,9 @@ class BASE_EXPORT PlatformThread { ...@@ -196,9 +196,9 @@ class BASE_EXPORT PlatformThread {
// and |thread_handle| is invalidated after this call. // and |thread_handle| is invalidated after this call.
static void Detach(PlatformThreadHandle thread_handle); static void Detach(PlatformThreadHandle thread_handle);
// Returns true if SetCurrentThreadPriority() can be used to increase the // Returns true if SetCurrentThreadPriority() should be able to increase the
// priority of the current thread. // priority of a thread to |priority|.
static bool CanIncreaseCurrentThreadPriority(); static bool CanIncreaseThreadPriority(ThreadPriority priority);
// Toggles the current thread's priority at runtime. // Toggles the current thread's priority at runtime.
// //
......
...@@ -31,7 +31,7 @@ void PlatformThread::SetName(const std::string& name) { ...@@ -31,7 +31,7 @@ void PlatformThread::SetName(const std::string& name) {
} }
// static // static
bool PlatformThread::CanIncreaseCurrentThreadPriority() { bool PlatformThread::CanIncreaseThreadPriority(ThreadPriority priority) {
return false; return false;
} }
......
...@@ -148,7 +148,7 @@ void SetPriorityRealtimeAudio() { ...@@ -148,7 +148,7 @@ void SetPriorityRealtimeAudio() {
} // anonymous namespace } // anonymous namespace
// static // static
bool PlatformThread::CanIncreaseCurrentThreadPriority() { bool PlatformThread::CanIncreaseThreadPriority(ThreadPriority priority) {
return true; return true;
} }
......
...@@ -240,10 +240,13 @@ void PlatformThread::Detach(PlatformThreadHandle thread_handle) { ...@@ -240,10 +240,13 @@ void PlatformThread::Detach(PlatformThreadHandle thread_handle) {
#if !defined(OS_MACOSX) && !defined(OS_FUCHSIA) #if !defined(OS_MACOSX) && !defined(OS_FUCHSIA)
// static // static
bool PlatformThread::CanIncreaseCurrentThreadPriority() { bool PlatformThread::CanIncreaseThreadPriority(ThreadPriority priority) {
#if defined(OS_NACL) #if defined(OS_NACL)
return false; return false;
#else #else
// TODO(fdoray): Also check if the target priority is within the range allowed
// by RLIMIT_NICE. https://crbug.com/816389
// Only root can raise thread priority on POSIX environment. On Linux, users // Only root can raise thread priority on POSIX environment. On Linux, users
// who have CAP_SYS_NICE permission also can raise the thread priority, but // who have CAP_SYS_NICE permission also can raise the thread priority, but
// libcap.so would be needed to check the capability. // libcap.so would be needed to check the capability.
......
...@@ -220,88 +220,69 @@ TEST(PlatformThreadTest, FunctionTimesTen) { ...@@ -220,88 +220,69 @@ TEST(PlatformThreadTest, FunctionTimesTen) {
namespace { namespace {
constexpr ThreadPriority kAllThreadPriorities[] = { bool CanIncreaseThreadPriorityWrapper(ThreadPriority priority) {
ThreadPriority::REALTIME_AUDIO, ThreadPriority::DISPLAY, #if defined(OS_ANDROID)
ThreadPriority::NORMAL, ThreadPriority::BACKGROUND}; // TODO(fdoray): PlatformThread::CanIncreaseThreadPriority(...) incorrectly
// returns false on Android. There should be a cross-POSIX implementation of
// this method that checks RLIMIT_NICE to determine whether it is possible
// to increase thread priority. https://crbug.com/872820
return true;
#else
return PlatformThread::CanIncreaseThreadPriority(priority);
#endif
}
class ThreadPriorityTestThread : public FunctionTestThread { class ThreadPriorityTestThread : public FunctionTestThread {
public: public:
explicit ThreadPriorityTestThread() = default; explicit ThreadPriorityTestThread(ThreadPriority from, ThreadPriority to)
: from_(from), to_(to) {}
~ThreadPriorityTestThread() override = default; ~ThreadPriorityTestThread() override = default;
private: private:
void RunTest() override { void RunTest() override {
#if !defined(OS_ANDROID) EXPECT_EQ(PlatformThread::GetCurrentThreadPriority(),
// TODO(fdoray): PlatformThread::CanIncreaseCurrentThreadPriority() ThreadPriority::NORMAL);
// incorrectly returns false on Android. There should be a cross-POSIX PlatformThread::SetCurrentThreadPriority(from_);
// implementation of this method that checks RLIMIT_NICE to determine EXPECT_EQ(PlatformThread::GetCurrentThreadPriority(), from_);
// whether it is possible to increase thread priority. PlatformThread::SetCurrentThreadPriority(to_);
// https://crbug.com/872820
if (PlatformThread::CanIncreaseCurrentThreadPriority()) { if (static_cast<int>(to_) <= static_cast<int>(from_) ||
#endif CanIncreaseThreadPriorityWrapper(to_)) {
// On platforms that support increasing thread priority, test transition EXPECT_EQ(PlatformThread::GetCurrentThreadPriority(), to_);
// between every possible pair of priorities.
for (auto first_priority : kAllThreadPriorities) {
for (auto second_priority : kAllThreadPriorities) {
PlatformThread::SetCurrentThreadPriority(first_priority);
EXPECT_EQ(first_priority, PlatformThread::GetCurrentThreadPriority());
PlatformThread::SetCurrentThreadPriority(second_priority);
EXPECT_EQ(second_priority,
PlatformThread::GetCurrentThreadPriority());
}
}
#if !defined(OS_ANDROID)
} else { } else {
// On platforms that don't support increasing thread priority, the only EXPECT_NE(PlatformThread::GetCurrentThreadPriority(), to_);
// valid transition is NORMAL -> BACKGROUND (it isn't possible to get a
// thread running with a higher priority than NORMAL).
EXPECT_EQ(ThreadPriority::NORMAL,
PlatformThread::GetCurrentThreadPriority());
// Verify that transition to DISPLAY or REALTIME_AUDIO is impossible.
PlatformThread::SetCurrentThreadPriority(ThreadPriority::DISPLAY);
EXPECT_EQ(ThreadPriority::NORMAL,
PlatformThread::GetCurrentThreadPriority());
PlatformThread::SetCurrentThreadPriority(ThreadPriority::REALTIME_AUDIO);
EXPECT_EQ(ThreadPriority::NORMAL,
PlatformThread::GetCurrentThreadPriority());
// Verify that transition to BACKGROUND is possible.
PlatformThread::SetCurrentThreadPriority(ThreadPriority::BACKGROUND);
EXPECT_EQ(ThreadPriority::BACKGROUND,
PlatformThread::GetCurrentThreadPriority());
// Verify that transition to NORMAL, DISPLAY or REALTIME_AUDIO is
// impossible.
PlatformThread::SetCurrentThreadPriority(ThreadPriority::NORMAL);
EXPECT_EQ(ThreadPriority::BACKGROUND,
PlatformThread::GetCurrentThreadPriority());
PlatformThread::SetCurrentThreadPriority(ThreadPriority::DISPLAY);
EXPECT_EQ(ThreadPriority::BACKGROUND,
PlatformThread::GetCurrentThreadPriority());
PlatformThread::SetCurrentThreadPriority(ThreadPriority::REALTIME_AUDIO);
EXPECT_EQ(ThreadPriority::BACKGROUND,
PlatformThread::GetCurrentThreadPriority());
} }
#endif // !defined(OS_ANDROID)
} }
const ThreadPriority from_;
const ThreadPriority to_;
DISALLOW_COPY_AND_ASSIGN(ThreadPriorityTestThread); DISALLOW_COPY_AND_ASSIGN(ThreadPriorityTestThread);
}; };
void TestSetCurrentThreadPriority() { void TestSetCurrentThreadPriority() {
ThreadPriorityTestThread thread; constexpr ThreadPriority kAllThreadPriorities[] = {
PlatformThreadHandle handle; ThreadPriority::REALTIME_AUDIO, ThreadPriority::DISPLAY,
ThreadPriority::NORMAL, ThreadPriority::BACKGROUND};
ASSERT_FALSE(thread.IsRunning());
ASSERT_TRUE(PlatformThread::Create(0, &thread, &handle)); for (auto from : kAllThreadPriorities) {
thread.WaitForTerminationReady(); if (static_cast<int>(from) <= static_cast<int>(ThreadPriority::NORMAL) ||
ASSERT_TRUE(thread.IsRunning()); CanIncreaseThreadPriorityWrapper(from)) {
for (auto to : kAllThreadPriorities) {
thread.MarkForTermination(); ThreadPriorityTestThread thread(from, to);
PlatformThread::Join(handle); PlatformThreadHandle handle;
ASSERT_FALSE(thread.IsRunning());
ASSERT_FALSE(thread.IsRunning());
ASSERT_TRUE(PlatformThread::Create(0, &thread, &handle));
thread.WaitForTerminationReady();
ASSERT_TRUE(thread.IsRunning());
thread.MarkForTermination();
PlatformThread::Join(handle);
ASSERT_FALSE(thread.IsRunning());
}
}
}
} }
} // namespace } // namespace
......
...@@ -271,7 +271,7 @@ void PlatformThread::Detach(PlatformThreadHandle thread_handle) { ...@@ -271,7 +271,7 @@ void PlatformThread::Detach(PlatformThreadHandle thread_handle) {
} }
// static // static
bool PlatformThread::CanIncreaseCurrentThreadPriority() { bool PlatformThread::CanIncreaseThreadPriority(ThreadPriority priority) {
return true; return true;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment