diff options
author | André Goddard Rosa <andre.goddard@gmail.com> | 2010-05-19 23:17:16 -0300 |
---|---|---|
committer | André Goddard Rosa <andre.goddard@gmail.com> | 2010-05-19 23:17:16 -0300 |
commit | 78c1c04ced772298be8bdb5a94b6ce491bb9b3e1 (patch) | |
tree | 31881f9114a2e6975f262200685d39141a144013 /libc/bionic | |
parent | 1297428e89ead45849068989d334d8b7eae2f602 (diff) | |
download | bionic-78c1c04ced772298be8bdb5a94b6ce491bb9b3e1.zip bionic-78c1c04ced772298be8bdb5a94b6ce491bb9b3e1.tar.gz bionic-78c1c04ced772298be8bdb5a94b6ce491bb9b3e1.tar.bz2 |
pthread: introduce pthread_setname_np() as a mean to give names to threads
... so that each cloned process at the kernel level can be named
independently. Tools like 'top' can display the CPU/memory statistics
for each process's thread if "Show Threads" mode is on.
With this function in place, we can convert dalvik/Thread.c setThreadName()
function over this function. This feature ought to be provided by the
underlying C library and not coded directly in Dalvik.
Change-Id: Ifa997665dbaa114e0b126f8c667708be9a4137fd
Signed-off-by: André Goddard Rosa <andre.goddard@gmail.com>
Diffstat (limited to 'libc/bionic')
-rw-r--r-- | libc/bionic/pthread.c | 54 |
1 files changed, 54 insertions, 0 deletions
diff --git a/libc/bionic/pthread.c b/libc/bionic/pthread.c index 7d4056d..666a6b8 100644 --- a/libc/bionic/pthread.c +++ b/libc/bionic/pthread.c @@ -43,6 +43,9 @@ #include <memory.h> #include <assert.h> #include <malloc.h> +#include <sys/prctl.h> +#include <sys/stat.h> +#include <fcntl.h> extern int __pthread_clone(int (*fn)(void*), void *child_stack, int flags, void *arg); extern void _exit_with_stack_teardown(void * stackBase, int stackSize, int retCode); @@ -1721,3 +1724,54 @@ int pthread_once( pthread_once_t* once_control, void (*init_routine)(void) ) } return 0; } + +/* This value is not exported by kernel headers, so hardcode it here */ +#define MAX_TASK_COMM_LEN 16 +#define TASK_COMM_FMT "/proc/self/task/%u/comm" + +int pthread_setname_np(pthread_t thid, const char *thname) +{ + size_t thname_len; + int saved_errno, ret; + + if (thid == 0 || thname == NULL) + return EINVAL; + + thname_len = strlen(thname); + if (thname_len >= MAX_TASK_COMM_LEN) + return ERANGE; + + saved_errno = errno; + if (thid == pthread_self()) + { + ret = prctl(PR_SET_NAME, (unsigned long)thname, 0, 0, 0) ? errno : 0; + } + else + { + /* Have to change another thread's name */ + pthread_internal_t *thread = (pthread_internal_t *)thid; + char comm_name[sizeof(TASK_COMM_FMT) + 8]; + ssize_t n; + int fd; + + snprintf(comm_name, sizeof(comm_name), TASK_COMM_FMT, (unsigned int)thread->kernel_id); + fd = open(comm_name, O_RDWR); + if (fd == -1) + { + ret = errno; + goto exit; + } + n = TEMP_FAILURE_RETRY(write(fd, thname, thname_len)); + close(fd); + + if (n < 0) + ret = errno; + else if ((size_t)n != thname_len) + ret = EIO; + else + ret = 0; + } +exit: + errno = saved_errno; + return ret; +} |