Skip to content

Commit

Permalink
More fixes to Binder perf regression from Eclair
Browse files Browse the repository at this point in the history
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 <unfinished ...>
[pid  1556] <... ioctl resumed> , 0x45399cd0) = 0
[pid  1556] write(22, "1556", 4)        = 4
[pid  1556] ioctl(21, 0xc0186201 <unfinished ...>
[pid  1555] <... ioctl resumed> , 0x45299cd0) = 0
[pid  1555] write(22, "1555", 4)        = 4
[pid  1555] ioctl(21, 0xc0186201 <unfinished ...>
[pid  1554] <... ioctl resumed> , 0x45199cd0) = 0
[pid  1554] write(22, "1554", 4)        = 4

BUG=2660235

Change-Id: Ia9f9e1d5b792eaebc9560f89931faf6df0cf9c0d
  • Loading branch information
bradfitz committed May 7, 2010
1 parent 253e27a commit e43c248
Showing 1 changed file with 47 additions and 32 deletions.
79 changes: 47 additions & 32 deletions libcutils/sched_policy.c
Expand Up @@ -22,6 +22,7 @@
#include <string.h> #include <string.h>
#include <errno.h> #include <errno.h>
#include <fcntl.h> #include <fcntl.h>
#include <pthread.h>


#define LOG_TAG "SchedPolicy" #define LOG_TAG "SchedPolicy"
#include "cutils/log.h" #include "cutils/log.h"
Expand All @@ -42,15 +43,28 @@


#define POLICY_DEBUG 0 #define POLICY_DEBUG 0


static pthread_once_t the_once = PTHREAD_ONCE_INIT;

static int __sys_supports_schedgroups = -1; static int __sys_supports_schedgroups = -1;


/* Add tid to the group defined by dev_path ("/dev/cpuctl/.../tasks") */ // File descriptors open to /dev/cpuctl/../tasks, setup by initialize, or -1 on error.
static int add_tid_to_cgroup(int tid, const char *dev_path) 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; int fd;
if ((fd = open(dev_path, O_WRONLY)) < 0) {
SLOGE("add_tid_to_cgroup failed to open '%s' (%s)\n", dev_path, if (policy == SP_BACKGROUND) {
strerror(errno)); 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; return -1;
} }


Expand All @@ -65,30 +79,38 @@ static int add_tid_to_cgroup(int tid, const char *dev_path)
} }


if (write(fd, ptr, end - ptr) < 0) { if (write(fd, ptr, end - ptr) < 0) {
close(fd); /*
/* * If the thread is in the process of exiting,
* If the thread is in the process of exiting, * don't flag an error
* don't flag an error */
*/ if (errno == ESRCH)
if (errno == ESRCH) return 0;
return 0; SLOGW("add_tid_to_cgroup failed to write '%s' (%s); background=%d\n",
SLOGW("add_tid_to_cgroup failed to write '%s' to '%s' (%s)\n", ptr, strerror(errno), policy == SP_BACKGROUND ? 1 : 0);
ptr, dev_path, strerror(errno));
return -1; return -1;
} }


close(fd);
return 0; return 0;
} }


static inline void initialize() static void __initialize(void) {
{ char* filename;
if (__sys_supports_schedgroups < 0) { if (!access("/dev/cpuctl/tasks", F_OK)) {
if (!access("/dev/cpuctl/tasks", F_OK)) { __sys_supports_schedgroups = 1;
__sys_supports_schedgroups = 1;
} else { filename = "/dev/cpuctl/tasks";
__sys_supports_schedgroups = 0; 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;
} }
} }


Expand Down Expand Up @@ -166,7 +188,7 @@ static int getSchedulerGroup(int tid, char* buf, size_t bufLen)


int get_sched_policy(int tid, SchedPolicy *policy) int get_sched_policy(int tid, SchedPolicy *policy)
{ {
initialize(); pthread_once(&the_once, __initialize);


if (__sys_supports_schedgroups) { if (__sys_supports_schedgroups) {
char grpBuf[32]; char grpBuf[32];
Expand Down Expand Up @@ -198,7 +220,7 @@ int get_sched_policy(int tid, SchedPolicy *policy)


int set_sched_policy(int tid, SchedPolicy policy) int set_sched_policy(int tid, SchedPolicy policy)
{ {
initialize(); pthread_once(&the_once, __initialize);


#if POLICY_DEBUG #if POLICY_DEBUG
char statfile[64]; char statfile[64];
Expand Down Expand Up @@ -233,14 +255,7 @@ int set_sched_policy(int tid, SchedPolicy policy)
#endif #endif


if (__sys_supports_schedgroups) { if (__sys_supports_schedgroups) {
const char *dev_path; if (add_tid_to_cgroup(tid, policy)) {
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 (errno != ESRCH && errno != ENOENT) if (errno != ESRCH && errno != ENOENT)
return -errno; return -errno;
} }
Expand Down

0 comments on commit e43c248

Please sign in to comment.