From e43c248316d0faa7bdc23de823b068c2aa3520ab Mon Sep 17 00:00:00 2001 From: Brad Fitzpatrick Date: Fri, 7 May 2010 12:06:05 -0700 Subject: [PATCH] More fixes to Binder perf regression from Eclair Re-use the file descriptor to change the cgroups. There's a fast path in the kernel for the case where the value's already uncahnged. Also, this is okay because the kernel ignores the write offset. This is essentially a ioctl-ish/datagram interface, despite being a fd we're writing to. This reduces Dalvik->Dalvik void/void Binder calls on Sapphire from ~1.2 to ~0.8 ms. This is a bit slower than the ~0.7 ms we get avoiding the write altogether. strace confirms: [pid 1557] ioctl(21, 0xc0186201 [pid 1556] <... ioctl resumed> , 0x45399cd0) = 0 [pid 1556] write(22, "1556", 4) = 4 [pid 1556] ioctl(21, 0xc0186201 [pid 1555] <... ioctl resumed> , 0x45299cd0) = 0 [pid 1555] write(22, "1555", 4) = 4 [pid 1555] ioctl(21, 0xc0186201 [pid 1554] <... ioctl resumed> , 0x45199cd0) = 0 [pid 1554] write(22, "1554", 4) = 4 BUG=2660235 Change-Id: Ia9f9e1d5b792eaebc9560f89931faf6df0cf9c0d --- libcutils/sched_policy.c | 79 ++++++++++++++++++++++++---------------- 1 file changed, 47 insertions(+), 32 deletions(-) diff --git a/libcutils/sched_policy.c b/libcutils/sched_policy.c index 6d2727ba4..78e094376 100644 --- a/libcutils/sched_policy.c +++ b/libcutils/sched_policy.c @@ -22,6 +22,7 @@ #include #include #include +#include #define LOG_TAG "SchedPolicy" #include "cutils/log.h" @@ -42,15 +43,28 @@ #define POLICY_DEBUG 0 +static pthread_once_t the_once = PTHREAD_ONCE_INIT; + static int __sys_supports_schedgroups = -1; -/* Add tid to the group defined by dev_path ("/dev/cpuctl/.../tasks") */ -static int add_tid_to_cgroup(int tid, const char *dev_path) +// File descriptors open to /dev/cpuctl/../tasks, setup by initialize, or -1 on error. +static int normal_cgroup_fd = -1; +static int bg_cgroup_fd = -1; + +/* Add tid to the scheduling group defined by the policy */ +static int add_tid_to_cgroup(int tid, SchedPolicy policy) { int fd; - if ((fd = open(dev_path, O_WRONLY)) < 0) { - SLOGE("add_tid_to_cgroup failed to open '%s' (%s)\n", dev_path, - strerror(errno)); + + if (policy == SP_BACKGROUND) { + fd = bg_cgroup_fd; + } else { + fd = normal_cgroup_fd; + } + + if (fd < 0) { + SLOGE("add_tid_to_cgroup failed; background=%d\n", + policy == SP_BACKGROUND ? 1 : 0); return -1; } @@ -65,30 +79,38 @@ static int add_tid_to_cgroup(int tid, const char *dev_path) } if (write(fd, ptr, end - ptr) < 0) { - close(fd); - /* - * If the thread is in the process of exiting, - * don't flag an error - */ - if (errno == ESRCH) - return 0; - SLOGW("add_tid_to_cgroup failed to write '%s' to '%s' (%s)\n", - ptr, dev_path, strerror(errno)); + /* + * If the thread is in the process of exiting, + * don't flag an error + */ + if (errno == ESRCH) + return 0; + SLOGW("add_tid_to_cgroup failed to write '%s' (%s); background=%d\n", + ptr, strerror(errno), policy == SP_BACKGROUND ? 1 : 0); return -1; } - close(fd); return 0; } -static inline void initialize() -{ - if (__sys_supports_schedgroups < 0) { - if (!access("/dev/cpuctl/tasks", F_OK)) { - __sys_supports_schedgroups = 1; - } else { - __sys_supports_schedgroups = 0; +static void __initialize(void) { + char* filename; + if (!access("/dev/cpuctl/tasks", F_OK)) { + __sys_supports_schedgroups = 1; + + filename = "/dev/cpuctl/tasks"; + normal_cgroup_fd = open(filename, O_WRONLY); + if (normal_cgroup_fd < 0) { + SLOGE("open of %s failed: %s\n", filename, strerror(errno)); } + + filename = "/dev/cpuctl/bg_non_interactive/tasks"; + bg_cgroup_fd = open(filename, O_WRONLY); + if (bg_cgroup_fd < 0) { + SLOGE("open of %s failed: %s\n", filename, strerror(errno)); + } + } else { + __sys_supports_schedgroups = 0; } } @@ -166,7 +188,7 @@ static int getSchedulerGroup(int tid, char* buf, size_t bufLen) int get_sched_policy(int tid, SchedPolicy *policy) { - initialize(); + pthread_once(&the_once, __initialize); if (__sys_supports_schedgroups) { char grpBuf[32]; @@ -198,7 +220,7 @@ int get_sched_policy(int tid, SchedPolicy *policy) int set_sched_policy(int tid, SchedPolicy policy) { - initialize(); + pthread_once(&the_once, __initialize); #if POLICY_DEBUG char statfile[64]; @@ -233,14 +255,7 @@ int set_sched_policy(int tid, SchedPolicy policy) #endif if (__sys_supports_schedgroups) { - const char *dev_path; - if (policy == SP_BACKGROUND) { - dev_path = "/dev/cpuctl/bg_non_interactive/tasks"; - } else { - dev_path = "/dev/cpuctl/tasks"; - } - - if (add_tid_to_cgroup(tid, dev_path)) { + if (add_tid_to_cgroup(tid, policy)) { if (errno != ESRCH && errno != ENOENT) return -errno; }