Refine set_sched_policy behavior
If a thread priority is greater than or equal to
ANDROID_PRIORITY_BACKGROUND, and the new priority is less than
ANDROID_PRIORITY_BACKGROUND, set the sched policy to its parent process.
Bug: 139521784
Bug: 18249098
Test: functionality verified
Change-Id: Id0632cb53825cd7d342610713e100c651994d78f
diff --git a/palette_android.cc b/palette_android.cc
index e2d0036..cb13720 100644
--- a/palette_android.cc
+++ b/palette_android.cc
@@ -29,9 +29,10 @@
#include <android-base/logging.h>
#include <android-base/macros.h>
#include <cutils/ashmem.h>
-#include <cutils/sched_policy.h>
#include <cutils/trace.h>
#include <log/event_tag_map.h>
+#include <processgroup/processgroup.h>
+#include <processgroup/sched_policy.h>
#include <tombstoned/tombstoned.h>
#include <utils/Thread.h>
@@ -66,18 +67,21 @@
return PaletteStatus::kInvalidArgument;
}
int new_nice = kNiceValues[managed_priority - art::palette::kMinManagedThreadPriority];
+ int curr_nice = getpriority(PRIO_PROCESS, tid);
- // TODO: b/18249098 The code below is broken. It uses getpriority() as a proxy for whether a
- // thread is already in the SP_FOREGROUND cgroup. This is not necessarily true for background
- // processes, where all threads are in the SP_BACKGROUND cgroup. This means that callers will
- // have to call setPriority twice to do what they want :
- //
- // Thread.setPriority(Thread.MIN_PRIORITY); // no-op wrt to cgroups
- // Thread.setPriority(Thread.MAX_PRIORITY); // will actually change cgroups.
+ if (curr_nice == new_nice) {
+ return PaletteStatus::kOkay;
+ }
+
if (new_nice >= ANDROID_PRIORITY_BACKGROUND) {
- set_sched_policy(tid, SP_BACKGROUND);
- } else if (getpriority(PRIO_PROCESS, tid) >= ANDROID_PRIORITY_BACKGROUND) {
- set_sched_policy(tid, SP_FOREGROUND);
+ SetTaskProfiles(tid, {"SCHED_SP_BACKGROUND"}, true);
+ } else if (curr_nice >= ANDROID_PRIORITY_BACKGROUND) {
+ SchedPolicy policy;
+ // Change to the sched policy group of the process.
+ if (get_sched_policy(getpid(), &policy) != 0) {
+ policy = SP_FOREGROUND;
+ }
+ SetTaskProfiles(tid, {get_sched_policy_profile_name(policy)}, true);
}
if (setpriority(PRIO_PROCESS, tid, new_nice) != 0) {