From d401fc4cda170309a13b6021626eb7ab18658f1c Mon Sep 17 00:00:00 2001 From: fangting Date: Mon, 4 Jul 2022 15:57:17 +0800 Subject: [PATCH] =?UTF-8?q?pthread=5Fgetname=5Fnp.c=E6=8E=A5=E5=8F=A3?= =?UTF-8?q?=E8=A1=A5=E5=85=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: fangting --- libc-test/src/functional/pthread_getname_np.c | 49 +++++++++++++++++++ .../src/functional/test_src_functional.gni | 1 + musl_src.gni | 2 + porting/linux/user/include/pthread.h | 1 + .../user/src/thread/pthread_getname_np.c | 29 +++++++++++ 5 files changed, 82 insertions(+) create mode 100644 libc-test/src/functional/pthread_getname_np.c create mode 100644 porting/linux/user/src/thread/pthread_getname_np.c diff --git a/libc-test/src/functional/pthread_getname_np.c b/libc-test/src/functional/pthread_getname_np.c new file mode 100644 index 00000000..19a46c61 --- /dev/null +++ b/libc-test/src/functional/pthread_getname_np.c @@ -0,0 +1,49 @@ +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include + +#define NAMELEN 16 + +#define errExitEN(en, msg) \ + do { errno = en; perror(msg); exit(EXIT_FAILURE); \ + } while (0) + +static void *threadfunc(void *parm) +{ + sleep(5); // allow main program to set the thread name + return NULL; +} + +int main(int argc, char **argv) +{ + pthread_t thread; + int rc; + char thread_name[NAMELEN]; + char set_thread_name[] = "THREADFOO"; + char default_name[] = "pthread_getname_np"; + + rc = pthread_getname_np(pthread_self(), thread_name, NAMELEN); + if (rc != 0) errExitEN(rc, "pthread_getname_np failed"); + if(strcmp(thread_name, default_name) != 0) perror("pthread name comparison failed"); + + rc = pthread_create(&thread, NULL, threadfunc, NULL); + if (rc != 0) errExitEN(rc, "pthread_create failed"); + + rc = pthread_setname_np(thread, (argc > 1) ? argv[1] : set_thread_name); + if (rc != 0) errExitEN(rc, "pthread_setname_np failed"); + + sleep(2); + + rc = pthread_getname_np(thread, thread_name, (argc > 2) ? atoi(argv[1]) : NAMELEN); + if (rc != 0) errExitEN(rc, "pthread_getname_np failed"); + if(strcmp(thread_name, set_thread_name) != 0) perror("pthread name comparison failed"); + + rc = pthread_join(thread, NULL); + if (rc != 0) errExitEN(rc, "pthread_join failed"); + + exit(EXIT_SUCCESS); +} \ No newline at end of file diff --git a/libc-test/src/functional/test_src_functional.gni b/libc-test/src/functional/test_src_functional.gni index a6173354..85d07543 100644 --- a/libc-test/src/functional/test_src_functional.gni +++ b/libc-test/src/functional/test_src_functional.gni @@ -29,6 +29,7 @@ functional_list = [ "pthread_mutex_pi", "pthread_robust", "pthread_tsd", + "pthread_getname_np", "qsort", "random", "search_hsearch", diff --git a/musl_src.gni b/musl_src.gni index 7f1b005a..958bb000 100644 --- a/musl_src.gni +++ b/musl_src.gni @@ -1293,6 +1293,7 @@ musl_src_file = [ "src/thread/pthread_getattr_np.c", "src/thread/pthread_getconcurrency.c", "src/thread/pthread_getcpuclockid.c", + "src/thread/pthread_getname_np.c", "src/thread/pthread_getschedparam.c", "src/thread/pthread_getspecific.c", "src/thread/pthread_join.c", @@ -1939,6 +1940,7 @@ musl_src_porting_file = [ "src/time/strftime.c", "src/time/strptime.c", "src/time/time_impl.h", + "src/thread/pthread_getname_np.c", ] musl_inc_hook_files = [ diff --git a/porting/linux/user/include/pthread.h b/porting/linux/user/include/pthread.h index ea983328..45184fce 100644 --- a/porting/linux/user/include/pthread.h +++ b/porting/linux/user/include/pthread.h @@ -395,6 +395,7 @@ int pthread_getaffinity_np(pthread_t, size_t, struct cpu_set_t *); int pthread_setaffinity_np(pthread_t, size_t, const struct cpu_set_t *); int pthread_getattr_np(pthread_t, pthread_attr_t *); int pthread_setname_np(pthread_t, const char *); +int pthread_getname_np(pthread_t, char *, size_t); int pthread_getattr_default_np(pthread_attr_t *); int pthread_setattr_default_np(const pthread_attr_t *); int pthread_tryjoin_np(pthread_t, void **); diff --git a/porting/linux/user/src/thread/pthread_getname_np.c b/porting/linux/user/src/thread/pthread_getname_np.c new file mode 100644 index 00000000..5d99673a --- /dev/null +++ b/porting/linux/user/src/thread/pthread_getname_np.c @@ -0,0 +1,29 @@ +#define _GNU_SOURCE +#include +#include +#include + +#include "pthread_impl.h" + +int pthread_getname_np(pthread_t thread, char *name, size_t len) +{ + int fd, cs, status = 0; + char f[sizeof "/proc/self/task//comm" + 3*sizeof(int)]; + + if (len < 16) return ERANGE; + + if (thread == pthread_self()) + return prctl(PR_GET_NAME, (unsigned long)name, 0UL, 0UL, 0UL) ? errno : 0; + + snprintf(f, sizeof f, "/proc/self/task/%d/comm", thread->tid); + pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs); + if ((fd = open(f, O_RDONLY|O_CLOEXEC)) < 0 || (len = read(fd, name, len)) < 0) status = errno; + else name[len-1] = 0; + /* remove trailing new line only if successful*/ + /*It seems that Linux indeed always adds a newline, so removing it + unconditionally seems fine.*/ + + if (fd >= 0) close(fd); + pthread_setcancelstate(cs, 0); + return status; +} \ No newline at end of file -- GitLab