sched_policy: Add support for /proc/<tid>/timerslack_ns over PR_SET_TIMERSLACK_PID

The PR_SET_TIMERSLACK_PID number has collided with upstream
changes a number of times, and thus the number is not consistent
between AOSP common kernel versions.

In 4.6+, the upstream kernel added equivalent functionaity via
the /proc/<tid>/timerslack_ns entry.

This patch changes the sched_policy logic to support
/proc/<tid>/timerslack_ns if its available, falling back to the
older PR_SET_TIMERSLACK_PID method if not.

NOTE: Eventually PR_SET_TIMERSLACK_PID usage will need to be
removed as it is likely to conflict with valid future upstream
PR_* entries.

Also add missing O_CLOEXEC to other open calls in this file.

Change-Id: Iec0b8a62de0dc8bdd57b60df82bd4d31c5d64709
Signed-off-by: John Stultz <john.stultz@linaro.org>
This commit is contained in:
John Stultz 2016-07-01 17:45:06 -07:00 committed by Elliott Hughes
parent 345754313e
commit 2f13f0a48a
1 changed files with 25 additions and 5 deletions

View File

@ -160,7 +160,7 @@ static int getSchedulerGroup(int tid, char* buf, size_t bufLen)
FILE *fp;
snprintf(pathBuf, sizeof(pathBuf), "/proc/%d/cgroup", tid);
if (!(fp = fopen(pathBuf, "r"))) {
if (!(fp = fopen(pathBuf, "re"))) {
return -1;
}
@ -292,6 +292,27 @@ int set_cpuset_policy(int tid, SchedPolicy policy)
#endif
}
static void set_timerslack_ns(int tid, unsigned long long slack) {
char buf[64];
/* v4.6+ kernels support the /proc/<tid>/timerslack_ns interface. */
snprintf(buf, sizeof(buf), "/proc/%d/timerslack_ns", tid);
int fd = open(buf, O_WRONLY | O_CLOEXEC);
if (fd != -1) {
int len = snprintf(buf, sizeof(buf), "%llu", slack);
if (write(fd, buf, len) != len) {
SLOGE("set_timerslack_ns write failed: %s\n", strerror(errno));
}
close(fd);
return;
}
/* If the above fails, try the old common.git PR_SET_TIMERSLACK_PID. */
if (prctl(PR_SET_TIMERSLACK_PID, slack, tid) == -1) {
SLOGE("set_timerslack_ns prctl failed: %s\n", strerror(errno));
}
}
int set_sched_policy(int tid, SchedPolicy policy)
{
if (tid == 0) {
@ -304,12 +325,11 @@ int set_sched_policy(int tid, SchedPolicy policy)
char statfile[64];
char statline[1024];
char thread_name[255];
int fd;
snprintf(statfile, sizeof(statfile), "/proc/%d/stat", tid);
memset(thread_name, 0, sizeof(thread_name));
fd = open(statfile, O_RDONLY);
int fd = open(statfile, O_RDONLY | O_CLOEXEC);
if (fd >= 0) {
int rc = read(fd, statline, 1023);
close(fd);
@ -372,8 +392,8 @@ int set_sched_policy(int tid, SchedPolicy policy)
&param);
}
prctl(PR_SET_TIMERSLACK_PID,
policy == SP_BACKGROUND ? TIMER_SLACK_BG : TIMER_SLACK_FG, tid);
set_timerslack_ns(tid, policy == SP_BACKGROUND ?
TIMER_SLACK_BG : TIMER_SLACK_FG);
return 0;
}