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() {
return false;
#if !defined(OS_ANDROID)
// When thread priority can't be increased, run all threads with a normal
// priority to avoid priority inversions on shutdown (TaskScheduler increases
// background threads priority to normal on shutdown while resolving remaining
// shutdown blocking tasks).
// When thread priority can't be increased to NORMAL, run all threads with a
// NORMAL priority to avoid priority inversions on shutdown (TaskScheduler
// increases BACKGROUND threads priority to NORMAL on shutdown while resolving
// remaining shutdown blocking tasks).
//
// This is ignored on Android, because it doesn't have a clean shutdown phase.
if (!PlatformThread::CanIncreaseCurrentThreadPriority())
if (!PlatformThread::CanIncreaseThreadPriority(ThreadPriority::NORMAL))
return false;
#endif // defined(OS_ANDROID)
......
......@@ -196,9 +196,9 @@ class BASE_EXPORT PlatformThread {
// and |thread_handle| is invalidated after this call.
static void Detach(PlatformThreadHandle thread_handle);
// Returns true if SetCurrentThreadPriority() can be used to increase the
// priority of the current thread.
static bool CanIncreaseCurrentThreadPriority();
// Returns true if SetCurrentThreadPriority() should be able to increase the
// priority of a thread to |priority|.
static bool CanIncreaseThreadPriority(ThreadPriority priority);
// Toggles the current thread's priority at runtime.
//
......
......@@ -31,7 +31,7 @@ void PlatformThread::SetName(const std::string& name) {
}
// static
bool PlatformThread::CanIncreaseCurrentThreadPriority() {
bool PlatformThread::CanIncreaseThreadPriority(ThreadPriority priority) {
return false;
}
......
......@@ -148,7 +148,7 @@ void SetPriorityRealtimeAudio() {
} // anonymous namespace
// static
bool PlatformThread::CanIncreaseCurrentThreadPriority() {
bool PlatformThread::CanIncreaseThreadPriority(ThreadPriority priority) {
return true;
}
......
......@@ -240,10 +240,13 @@ void PlatformThread::Detach(PlatformThreadHandle thread_handle) {
#if !defined(OS_MACOSX) && !defined(OS_FUCHSIA)
// static
bool PlatformThread::CanIncreaseCurrentThreadPriority() {
bool PlatformThread::CanIncreaseThreadPriority(ThreadPriority priority) {
#if defined(OS_NACL)
return false;
#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
// who have CAP_SYS_NICE permission also can raise the thread priority, but
// libcap.so would be needed to check the capability.
......
......@@ -220,88 +220,69 @@ TEST(PlatformThreadTest, FunctionTimesTen) {
namespace {
constexpr ThreadPriority kAllThreadPriorities[] = {
ThreadPriority::REALTIME_AUDIO, ThreadPriority::DISPLAY,
ThreadPriority::NORMAL, ThreadPriority::BACKGROUND};
bool CanIncreaseThreadPriorityWrapper(ThreadPriority priority) {
#if defined(OS_ANDROID)
// 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 {
public:
explicit ThreadPriorityTestThread() = default;
explicit ThreadPriorityTestThread(ThreadPriority from, ThreadPriority to)
: from_(from), to_(to) {}
~ThreadPriorityTestThread() override = default;
private:
void RunTest() override {
#if !defined(OS_ANDROID)
// TODO(fdoray): PlatformThread::CanIncreaseCurrentThreadPriority()
// 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
if (PlatformThread::CanIncreaseCurrentThreadPriority()) {
#endif
// On platforms that support increasing thread priority, test transition
// 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)
EXPECT_EQ(PlatformThread::GetCurrentThreadPriority(),
ThreadPriority::NORMAL);
PlatformThread::SetCurrentThreadPriority(from_);
EXPECT_EQ(PlatformThread::GetCurrentThreadPriority(), from_);
PlatformThread::SetCurrentThreadPriority(to_);
if (static_cast<int>(to_) <= static_cast<int>(from_) ||
CanIncreaseThreadPriorityWrapper(to_)) {
EXPECT_EQ(PlatformThread::GetCurrentThreadPriority(), to_);
} else {
// On platforms that don't support increasing thread priority, the only
// 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());
EXPECT_NE(PlatformThread::GetCurrentThreadPriority(), to_);
}
#endif // !defined(OS_ANDROID)
}
const ThreadPriority from_;
const ThreadPriority to_;
DISALLOW_COPY_AND_ASSIGN(ThreadPriorityTestThread);
};
void TestSetCurrentThreadPriority() {
ThreadPriorityTestThread thread;
PlatformThreadHandle handle;
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());
constexpr ThreadPriority kAllThreadPriorities[] = {
ThreadPriority::REALTIME_AUDIO, ThreadPriority::DISPLAY,
ThreadPriority::NORMAL, ThreadPriority::BACKGROUND};
for (auto from : kAllThreadPriorities) {
if (static_cast<int>(from) <= static_cast<int>(ThreadPriority::NORMAL) ||
CanIncreaseThreadPriorityWrapper(from)) {
for (auto to : kAllThreadPriorities) {
ThreadPriorityTestThread thread(from, to);
PlatformThreadHandle handle;
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
......
......@@ -271,7 +271,7 @@ void PlatformThread::Detach(PlatformThreadHandle thread_handle) {
}
// static
bool PlatformThread::CanIncreaseCurrentThreadPriority() {
bool PlatformThread::CanIncreaseThreadPriority(ThreadPriority priority) {
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