diff options
| author | Florian Weimer <fweimer@redhat.com> | 2025-03-12 10:16:31 +0100 |
|---|---|---|
| committer | Florian Weimer <fweimer@redhat.com> | 2025-03-12 10:23:35 +0100 |
| commit | 74d463c50bb1096efef47022405c7db33f83fb5a (patch) | |
| tree | 7a61f4db59c8bd43d1213d6d137aff51fff0588d /nptl | |
| parent | d604f9c500570e80febfcc6a52b63a002b466f35 (diff) | |
| download | glibc-74d463c50bb1096efef47022405c7db33f83fb5a.tar.xz glibc-74d463c50bb1096efef47022405c7db33f83fb5a.zip | |
Linux: Add the pthread_gettid_np function (bug 27880)
Current Bionic has this function, with enhanced error checking
(the undefined case terminates the process).
Reviewed-by: Joseph Myers <josmyers@redhat.com>
Diffstat (limited to 'nptl')
| -rw-r--r-- | nptl/Makefile | 2 | ||||
| -rw-r--r-- | nptl/Versions | 3 | ||||
| -rw-r--r-- | nptl/pthread_gettid_np.c | 30 | ||||
| -rw-r--r-- | nptl/tst-pthread_gettid_np.c | 79 |
4 files changed, 114 insertions, 0 deletions
diff --git a/nptl/Makefile b/nptl/Makefile index f70d1e55bd..eca00936d7 100644 --- a/nptl/Makefile +++ b/nptl/Makefile @@ -124,6 +124,7 @@ routines = \ pthread_getname \ pthread_getschedparam \ pthread_getspecific \ + pthread_gettid_np \ pthread_join \ pthread_join_common \ pthread_key_create \ @@ -326,6 +327,7 @@ tests = \ tst-pthread-timedlock-lockloop \ tst-pthread_exit-nothreads \ tst-pthread_exit-nothreads-static \ + tst-pthread_gettid_np \ tst-robust-fork \ tst-robustpi1 \ tst-robustpi2 \ diff --git a/nptl/Versions b/nptl/Versions index 3221de89d1..ef55376dd9 100644 --- a/nptl/Versions +++ b/nptl/Versions @@ -378,6 +378,9 @@ libc { tss_get; tss_set; } + GLIBC_2.42 { + pthread_gettid_np; + } GLIBC_PRIVATE { __libc_alloca_cutoff; __lll_lock_wake_private; diff --git a/nptl/pthread_gettid_np.c b/nptl/pthread_gettid_np.c new file mode 100644 index 0000000000..bf3a12cd52 --- /dev/null +++ b/nptl/pthread_gettid_np.c @@ -0,0 +1,30 @@ +/* Get the Linux TID from a pthread_t handle. + Copyright (C) 2025 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; see the file COPYING.LIB. If + not, see <https://www.gnu.org/licenses/>. */ + +#include <errno.h> +#include <pthreadP.h> + +pid_t +pthread_gettid_np (pthread_t threadid) +{ + /* The kernel may concurrently set this field. */ + pid_t tid = atomic_load_relaxed (&((struct pthread *) threadid)->tid); + if (tid <= 0) + return -1; + return tid; +} diff --git a/nptl/tst-pthread_gettid_np.c b/nptl/tst-pthread_gettid_np.c new file mode 100644 index 0000000000..6a98d864e2 --- /dev/null +++ b/nptl/tst-pthread_gettid_np.c @@ -0,0 +1,79 @@ +/* Test for pthread_gettid_np. + Copyright (C) 2025 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; see the file COPYING.LIB. If + not, see <https://www.gnu.org/licenses/>. */ + +#include <errno.h> +#include <pthread.h> +#include <sched.h> +#include <signal.h> +#include <support/check.h> +#include <support/xthread.h> +#include <unistd.h> + +static pthread_barrier_t barrier; + +static pid_t thread_tid; + +static void * +thread_func (void *ignored) +{ + thread_tid = gettid (); + TEST_VERIFY (thread_tid != getpid ()); + TEST_COMPARE (thread_tid, pthread_gettid_np (pthread_self ())); + xpthread_barrier_wait (&barrier); + /* The main thread calls pthread_gettid_np here. */ + xpthread_barrier_wait (&barrier); + return NULL; +} + +static int +do_test (void) +{ + TEST_COMPARE (pthread_gettid_np (pthread_self ()), getpid ()); + TEST_COMPARE (pthread_gettid_np (pthread_self ()), gettid ()); + + xpthread_barrier_init (&barrier, NULL, 2); + + pthread_t thr = xpthread_create (NULL, thread_func, NULL); + xpthread_barrier_wait (&barrier); + TEST_COMPARE (thread_tid, pthread_gettid_np (thr)); + xpthread_barrier_wait (&barrier); + + while (true) + { + /* Check if the kernel thread is still running. */ + if (tgkill (getpid (), thread_tid, 0)) + { + TEST_COMPARE (errno, ESRCH); + break; + } + + pid_t tid = pthread_gettid_np (thr); + if (tid != thread_tid) + { + TEST_COMPARE (tid, -1); + break; + } + TEST_COMPARE (sched_yield (), 0); + } + + TEST_VERIFY (xpthread_join (thr) == NULL); + + return 0; +} + +#include <support/test-driver.c> |
