summaryrefslogtreecommitdiffstats
path: root/libcutils
diff options
context:
space:
mode:
Diffstat (limited to 'libcutils')
-rw-r--r--libcutils/Android.bp10
-rw-r--r--libcutils/include/cutils/sched_policy.h17
-rw-r--r--libcutils/sched_policy.cpp (renamed from libcutils/sched_policy.c)173
3 files changed, 126 insertions, 74 deletions
diff --git a/libcutils/Android.bp b/libcutils/Android.bp
index 8ba7452ef..cf3119590 100644
--- a/libcutils/Android.bp
+++ b/libcutils/Android.bp
@@ -60,7 +60,7 @@ cc_library {
"native_handle.c",
"open_memstream.c",
"record_stream.c",
- "sched_policy.c",
+ "sched_policy.cpp",
"sockets.cpp",
"strdup16to8.c",
"strdup8to16.c",
@@ -141,14 +141,6 @@ cc_library {
header_libs: ["libcutils_headers"],
export_header_lib_headers: ["libcutils_headers"],
- product_variables: {
- cpusets: {
- cflags: ["-DUSE_CPUSETS"],
- },
- schedboost: {
- cflags: ["-DUSE_SCHEDBOOST"],
- },
- },
cflags: [
"-Werror",
"-Wall",
diff --git a/libcutils/include/cutils/sched_policy.h b/libcutils/include/cutils/sched_policy.h
index 591bd4478..15391d981 100644
--- a/libcutils/include/cutils/sched_policy.h
+++ b/libcutils/include/cutils/sched_policy.h
@@ -17,10 +17,27 @@
#ifndef __CUTILS_SCHED_POLICY_H
#define __CUTILS_SCHED_POLICY_H
+#include <stdbool.h>
+
#ifdef __cplusplus
extern "C" {
#endif
+/*
+ * Check if Linux kernel enables CPUSETS feature.
+ *
+ * Return value: 1 if Linux kernel CONFIG_CPUSETS=y; 0 otherwise.
+ */
+extern bool cpusets_enabled();
+
+/*
+ * Check if Linux kernel enables SCHEDTUNE feature (only available in Android
+ * common kernel or Linaro LSK, not in mainline Linux as of v4.9)
+ *
+ * Return value: 1 if Linux kernel CONFIG_SCHEDTUNE=y; 0 otherwise.
+ */
+extern bool schedboost_enabled();
+
/* Keep in sync with THREAD_GROUP_* in frameworks/base/core/java/android/os/Process.java */
typedef enum {
SP_DEFAULT = -1,
diff --git a/libcutils/sched_policy.c b/libcutils/sched_policy.cpp
index 5c5f3a563..7e3ad593e 100644
--- a/libcutils/sched_policy.c
+++ b/libcutils/sched_policy.cpp
@@ -58,13 +58,11 @@ static int __sys_supports_timerslack = -1;
static int bg_cgroup_fd = -1;
static int fg_cgroup_fd = -1;
-#ifdef USE_CPUSETS
// File descriptors open to /dev/cpuset/../tasks, setup by initialize, or -1 on error
static int system_bg_cpuset_fd = -1;
static int bg_cpuset_fd = -1;
static int fg_cpuset_fd = -1;
static int ta_cpuset_fd = -1; // special cpuset for top app
-#endif
// File descriptors open to /dev/stune/../tasks, setup by initialize, or -1 on error
static int bg_schedboost_fd = -1;
@@ -106,8 +104,53 @@ static int add_tid_to_cgroup(int tid, int fd)
return 0;
}
-static void __initialize(void) {
- char* filename;
+/*
+ If CONFIG_CPUSETS for Linux kernel is set, "tasks" can be found under
+ /dev/cpuset mounted in init.rc; otherwise, that file does not exist
+ even though the directory, /dev/cpuset, is still created (by init.rc).
+
+ A couple of other candidates (under cpuset mount directory):
+ notify_on_release
+ release_agent
+
+ Yet another way to decide if cpuset is enabled is to parse
+ /proc/self/status and search for lines begin with "Mems_allowed".
+
+ If CONFIG_PROC_PID_CPUSET is set, the existence "/proc/self/cpuset" can
+ be used to decide if CONFIG_CPUSETS is set, so we don't have a dependency
+ on where init.rc mounts cpuset. That's why we'd better require this
+ configuration be set if CONFIG_CPUSETS is set.
+
+ With runtime check using the following function, build time
+ variables like ENABLE_CPUSETS (used in Android.mk) or cpusets (used
+ in Android.bp) are not needed.
+ */
+
+bool cpusets_enabled() {
+ static bool enabled = (access("/dev/cpuset/tasks", F_OK) == 0);
+
+ return enabled;
+}
+
+/*
+ Similar to CONFIG_CPUSETS above, but with a different configuration
+ CONFIG_SCHEDTUNE that's in Android common Linux kernel and Linaro
+ Stable Kernel (LSK), but not in mainline Linux as of v4.9.
+
+ With runtime check using the following function, build time
+ variables like ENABLE_SCHEDBOOST (used in Android.mk) or schedboost
+ (used in Android.bp) are not needed.
+
+ */
+
+bool schedboost_enabled() {
+ static bool enabled = (access("/dev/stune/tasks", F_OK) == 0);
+
+ return enabled;
+}
+
+static void __initialize() {
+ const char* filename;
if (!access("/dev/cpuctl/tasks", W_OK)) {
__sys_supports_schedgroups = 1;
@@ -126,28 +169,28 @@ static void __initialize(void) {
__sys_supports_schedgroups = 0;
}
-#ifdef USE_CPUSETS
- if (!access("/dev/cpuset/tasks", W_OK)) {
-
- filename = "/dev/cpuset/foreground/tasks";
- fg_cpuset_fd = open(filename, O_WRONLY | O_CLOEXEC);
- filename = "/dev/cpuset/background/tasks";
- bg_cpuset_fd = open(filename, O_WRONLY | O_CLOEXEC);
- filename = "/dev/cpuset/system-background/tasks";
- system_bg_cpuset_fd = open(filename, O_WRONLY | O_CLOEXEC);
- filename = "/dev/cpuset/top-app/tasks";
- ta_cpuset_fd = open(filename, O_WRONLY | O_CLOEXEC);
-
-#ifdef USE_SCHEDBOOST
- filename = "/dev/stune/top-app/tasks";
- ta_schedboost_fd = open(filename, O_WRONLY | O_CLOEXEC);
- filename = "/dev/stune/foreground/tasks";
- fg_schedboost_fd = open(filename, O_WRONLY | O_CLOEXEC);
- filename = "/dev/stune/background/tasks";
- bg_schedboost_fd = open(filename, O_WRONLY | O_CLOEXEC);
-#endif
+ if (cpusets_enabled()) {
+ if (!access("/dev/cpuset/tasks", W_OK)) {
+
+ filename = "/dev/cpuset/foreground/tasks";
+ fg_cpuset_fd = open(filename, O_WRONLY | O_CLOEXEC);
+ filename = "/dev/cpuset/background/tasks";
+ bg_cpuset_fd = open(filename, O_WRONLY | O_CLOEXEC);
+ filename = "/dev/cpuset/system-background/tasks";
+ system_bg_cpuset_fd = open(filename, O_WRONLY | O_CLOEXEC);
+ filename = "/dev/cpuset/top-app/tasks";
+ ta_cpuset_fd = open(filename, O_WRONLY | O_CLOEXEC);
+
+ if (schedboost_enabled()) {
+ filename = "/dev/stune/top-app/tasks";
+ ta_schedboost_fd = open(filename, O_WRONLY | O_CLOEXEC);
+ filename = "/dev/stune/foreground/tasks";
+ fg_schedboost_fd = open(filename, O_WRONLY | O_CLOEXEC);
+ filename = "/dev/stune/background/tasks";
+ bg_schedboost_fd = open(filename, O_WRONLY | O_CLOEXEC);
+ }
+ }
}
-#endif
char buf[64];
snprintf(buf, sizeof(buf), "/proc/%d/timerslack_ns", getpid());
@@ -235,33 +278,34 @@ int get_sched_policy(int tid, SchedPolicy *policy)
if (__sys_supports_schedgroups) {
char grpBuf[32];
-#ifdef USE_CPUSETS
- if (getCGroupSubsys(tid, "cpuset", grpBuf, sizeof(grpBuf)) < 0)
- return -1;
- if (grpBuf[0] == '\0') {
- *policy = SP_FOREGROUND;
- } else if (!strcmp(grpBuf, "foreground")) {
- *policy = SP_FOREGROUND;
- } else if (!strcmp(grpBuf, "background")) {
- *policy = SP_BACKGROUND;
- } else if (!strcmp(grpBuf, "top-app")) {
- *policy = SP_TOP_APP;
- } else {
- errno = ERANGE;
- return -1;
- }
-#else
- if (getCGroupSubsys(tid, "cpu", grpBuf, sizeof(grpBuf)) < 0)
- return -1;
- if (grpBuf[0] == '\0') {
- *policy = SP_FOREGROUND;
- } else if (!strcmp(grpBuf, "bg_non_interactive")) {
- *policy = SP_BACKGROUND;
+
+ if (cpusets_enabled()) {
+ if (getCGroupSubsys(tid, "cpuset", grpBuf, sizeof(grpBuf)) < 0)
+ return -1;
+ if (grpBuf[0] == '\0') {
+ *policy = SP_FOREGROUND;
+ } else if (!strcmp(grpBuf, "foreground")) {
+ *policy = SP_FOREGROUND;
+ } else if (!strcmp(grpBuf, "background")) {
+ *policy = SP_BACKGROUND;
+ } else if (!strcmp(grpBuf, "top-app")) {
+ *policy = SP_TOP_APP;
+ } else {
+ errno = ERANGE;
+ return -1;
+ }
} else {
- errno = ERANGE;
- return -1;
+ if (getCGroupSubsys(tid, "cpu", grpBuf, sizeof(grpBuf)) < 0)
+ return -1;
+ if (grpBuf[0] == '\0') {
+ *policy = SP_FOREGROUND;
+ } else if (!strcmp(grpBuf, "bg_non_interactive")) {
+ *policy = SP_BACKGROUND;
+ } else {
+ errno = ERANGE;
+ return -1;
+ }
}
-#endif
} else {
int rc = sched_getscheduler(tid);
if (rc < 0)
@@ -281,9 +325,10 @@ int get_sched_policy(int tid, SchedPolicy *policy)
int set_cpuset_policy(int tid, SchedPolicy policy)
{
// in the absence of cpusets, use the old sched policy
-#ifndef USE_CPUSETS
- return set_sched_policy(tid, policy);
-#else
+ if (!cpusets_enabled()) {
+ return set_sched_policy(tid, policy);
+ }
+
if (tid == 0) {
tid = gettid();
}
@@ -320,15 +365,14 @@ int set_cpuset_policy(int tid, SchedPolicy policy)
return -errno;
}
-#ifdef USE_SCHEDBOOST
- if (boost_fd > 0 && add_tid_to_cgroup(tid, boost_fd) != 0) {
- if (errno != ESRCH && errno != ENOENT)
- return -errno;
+ if (schedboost_enabled()) {
+ if (boost_fd > 0 && add_tid_to_cgroup(tid, boost_fd) != 0) {
+ if (errno != ESRCH && errno != ENOENT)
+ return -errno;
+ }
}
-#endif
return 0;
-#endif
}
static void set_timerslack_ns(int tid, unsigned long long slack) {
@@ -420,18 +464,17 @@ int set_sched_policy(int tid, SchedPolicy policy)
break;
}
-
if (add_tid_to_cgroup(tid, fd) != 0) {
if (errno != ESRCH && errno != ENOENT)
return -errno;
}
-#ifdef USE_SCHEDBOOST
- if (boost_fd > 0 && add_tid_to_cgroup(tid, boost_fd) != 0) {
- if (errno != ESRCH && errno != ENOENT)
- return -errno;
+ if (schedboost_enabled()) {
+ if (boost_fd > 0 && add_tid_to_cgroup(tid, boost_fd) != 0) {
+ if (errno != ESRCH && errno != ENOENT)
+ return -errno;
+ }
}
-#endif
} else {
struct sched_param param;