diff options
author | The Android Open Source Project <initial-contribution@android.com> | 2010-06-03 14:39:20 -0700 |
---|---|---|
committer | The Android Open Source Project <initial-contribution@android.com> | 2010-06-03 14:39:20 -0700 |
commit | 7b6e6fa57240466c2728d553be136f800600dd71 (patch) | |
tree | 5744295128fa6b7b03377c8c7ab3c2df5af16cf5 | |
parent | 8e1ee7fd01986825074ececd39e8c2a5ebc907e0 (diff) | |
parent | f982f038329f7da7de5853c9d789ab138a4bcf16 (diff) | |
download | bionic-7b6e6fa57240466c2728d553be136f800600dd71.zip bionic-7b6e6fa57240466c2728d553be136f800600dd71.tar.gz bionic-7b6e6fa57240466c2728d553be136f800600dd71.tar.bz2 |
merge from open-source master
Change-Id: Ib7fc9c6f79f9b13e2175da137005d8968ea85eaf
-rw-r--r-- | libc/bionic/pthread.c | 54 | ||||
-rw-r--r-- | libc/include/pthread.h | 2 |
2 files changed, 56 insertions, 0 deletions
diff --git a/libc/bionic/pthread.c b/libc/bionic/pthread.c index ae44b06..e17e366 100644 --- a/libc/bionic/pthread.c +++ b/libc/bionic/pthread.c @@ -44,6 +44,9 @@ #include <assert.h> #include <malloc.h> #include <linux/futex.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); @@ -1879,3 +1882,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; +} diff --git a/libc/include/pthread.h b/libc/include/pthread.h index eb2d169..944bb68 100644 --- a/libc/include/pthread.h +++ b/libc/include/pthread.h @@ -231,6 +231,8 @@ int pthread_getcpuclockid(pthread_t tid, clockid_t *clockid); int pthread_once(pthread_once_t *once_control, void (*init_routine)(void)); +int pthread_setname_np(pthread_t thid, const char *thname); + typedef void (*__pthread_cleanup_func_t)(void*); typedef struct __pthread_cleanup_t { |