diff options
Diffstat (limited to 'libcutils')
-rw-r--r-- | libcutils/Android.bp | 10 | ||||
-rw-r--r-- | libcutils/include/cutils/sched_policy.h | 17 | ||||
-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; |