From 649b976a00c1295e4c1bd2f8c317376f31e9858a Mon Sep 17 00:00:00 2001 From: Mathias Agopian Date: Thu, 7 Mar 2013 15:32:47 -0800 Subject: [PATCH 1/2] limit number of extra binder threads in SF to 4 it should be enough and it makes debugging easier. Bug: 6609290 Change-Id: I2341e20cfcfde184fe1ed9b925215f8fa3481ced --- cmds/surfaceflinger/main_surfaceflinger.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmds/surfaceflinger/main_surfaceflinger.cpp b/cmds/surfaceflinger/main_surfaceflinger.cpp index 28e58e4b9..ce7fde0b6 100644 --- a/cmds/surfaceflinger/main_surfaceflinger.cpp +++ b/cmds/surfaceflinger/main_surfaceflinger.cpp @@ -20,9 +20,9 @@ using namespace android; int main(int argc, char** argv) { - SurfaceFlinger::publishAndJoinThreadPool(true); // When SF is launched in its own process, limit the number of // binder threads to 4. ProcessState::self()->setThreadPoolMaxThreadCount(4); + SurfaceFlinger::publishAndJoinThreadPool(true); return 0; } From e3e43b384e0603e5883b501cdb169641fab8fea2 Mon Sep 17 00:00:00 2001 From: Mathias Agopian Date: Thu, 7 Mar 2013 15:34:28 -0800 Subject: [PATCH 2/2] rename binder services main thread to Binder_* When a binder service's main thread joins the thread pool it retains its name (whatever the exec name was), which is very confusing in systrace. we now rename that thread just like its friends in the thread pool. Change-Id: Ibb3b6ff07304b247cfc6fb1694e72350c579513e --- include/binder/BinderService.h | 9 ++++++-- include/binder/ProcessState.h | 2 ++ include/utils/AndroidThreads.h | 3 +++ libs/binder/ProcessState.cpp | 19 +++++++++++----- libs/utils/Threads.cpp | 40 +++++++++++++++++++--------------- 5 files changed, 48 insertions(+), 25 deletions(-) diff --git a/include/binder/BinderService.h b/include/binder/BinderService.h index 646026841..5ac36d901 100644 --- a/include/binder/BinderService.h +++ b/include/binder/BinderService.h @@ -36,13 +36,18 @@ class BinderService public: static status_t publish(bool allowIsolated = false) { sp sm(defaultServiceManager()); - return sm->addService(String16(SERVICE::getServiceName()), new SERVICE(), allowIsolated); + return sm->addService( + String16(SERVICE::getServiceName()), + new SERVICE(), allowIsolated); } static void publishAndJoinThreadPool(bool allowIsolated = false) { sp sm(defaultServiceManager()); - sm->addService(String16(SERVICE::getServiceName()), new SERVICE(), allowIsolated); + sm->addService( + String16(SERVICE::getServiceName()), + new SERVICE(), allowIsolated); ProcessState::self()->startThreadPool(); + ProcessState::self()->giveThreadPoolName(); IPCThreadState::self()->joinThreadPool(); } diff --git a/include/binder/ProcessState.h b/include/binder/ProcessState.h index 8caf1afed..e63a0d0b2 100644 --- a/include/binder/ProcessState.h +++ b/include/binder/ProcessState.h @@ -71,6 +71,7 @@ public: void spawnPooledThread(bool isMain); status_t setThreadPoolMaxThreadCount(size_t maxThreads); + void giveThreadPoolName(); private: friend class IPCThreadState; @@ -80,6 +81,7 @@ private: ProcessState(const ProcessState& o); ProcessState& operator=(const ProcessState& o); + String8 makeBinderThreadName(); struct handle_entry { IBinder* binder; diff --git a/include/utils/AndroidThreads.h b/include/utils/AndroidThreads.h index f67648fd6..4eee14d7e 100644 --- a/include/utils/AndroidThreads.h +++ b/include/utils/AndroidThreads.h @@ -56,6 +56,9 @@ extern int androidCreateRawThreadEtc(android_thread_func_t entryFunction, size_t threadStackSize, android_thread_id_t *threadId); +// set the same of the running thread +extern void androidSetThreadName(const char* name); + // Used by the Java Runtime to control how threads are created, so that // they can be proper and lovely Java threads. typedef int (*android_create_thread_fn)(android_thread_func_t entryFunction, diff --git a/libs/binder/ProcessState.cpp b/libs/binder/ProcessState.cpp index d95fd6fa9..294e1d489 100644 --- a/libs/binder/ProcessState.cpp +++ b/libs/binder/ProcessState.cpp @@ -283,15 +283,20 @@ void ProcessState::setArgV0(const char* txt) } } +String8 ProcessState::makeBinderThreadName() { + int32_t s = android_atomic_add(1, &mThreadPoolSeq); + String8 name; + name.appendFormat("Binder_%X", s); + return name; +} + void ProcessState::spawnPooledThread(bool isMain) { if (mThreadPoolStarted) { - int32_t s = android_atomic_add(1, &mThreadPoolSeq); - char buf[16]; - snprintf(buf, sizeof(buf), "Binder_%X", s); - ALOGV("Spawning new pooled thread, name=%s\n", buf); + String8 name = makeBinderThreadName(); + ALOGV("Spawning new pooled thread, name=%s\n", name.string()); sp t = new PoolThread(isMain); - t->run(buf); + t->run(name.string()); } } @@ -304,6 +309,10 @@ status_t ProcessState::setThreadPoolMaxThreadCount(size_t maxThreads) { return result; } +void ProcessState::giveThreadPoolName() { + androidSetThreadName( makeBinderThreadName().string() ); +} + static int open_driver() { int fd = open("/dev/binder", O_RDWR); diff --git a/libs/utils/Threads.cpp b/libs/utils/Threads.cpp index a25a81fbe..eb964978e 100644 --- a/libs/utils/Threads.cpp +++ b/libs/utils/Threads.cpp @@ -109,30 +109,34 @@ struct thread_data_t { } if (name) { -#if defined(HAVE_PRCTL) - // Mac OS doesn't have this, and we build libutil for the host too - int hasAt = 0; - int hasDot = 0; - char *s = name; - while (*s) { - if (*s == '.') hasDot = 1; - else if (*s == '@') hasAt = 1; - s++; - } - int len = s - name; - if (len < 15 || hasAt || !hasDot) { - s = name; - } else { - s = name + len - 15; - } - prctl(PR_SET_NAME, (unsigned long) s, 0, 0, 0); -#endif + androidSetThreadName(name); free(name); } return f(u); } }; +void androidSetThreadName(const char* name) { +#if defined(HAVE_PRCTL) + // Mac OS doesn't have this, and we build libutil for the host too + int hasAt = 0; + int hasDot = 0; + const char *s = name; + while (*s) { + if (*s == '.') hasDot = 1; + else if (*s == '@') hasAt = 1; + s++; + } + int len = s - name; + if (len < 15 || hasAt || !hasDot) { + s = name; + } else { + s = name + len - 15; + } + prctl(PR_SET_NAME, (unsigned long) s, 0, 0, 0); +#endif +} + int androidCreateRawThreadEtc(android_thread_func_t entryFunction, void *userData, const char* threadName,