Subject: [PATCH] nptl: Add pthread_thread_number_np function
To: libc-alpha@sourceware.org
The implementation is actually in libc.so. With a full implementation
of pthread_self in libc.so, pthread_thread_number_np is completely
usable without libpthread.
2017-12-22 Florian Weimer <fweimer@redhat.com>
nptl: Add pthread_thread_number_np function.
* csu/libc-tls.c (__libc_setup_tls): Call __dl_inittcb.
* elf/Makefile (dl-routines): Add dl-inittcb.
* elf/dl-inittcb.c: New file.
* elf/rtld.c (init_tls): Call __dl_inittcb.
* manual/threads.texi (Non-POSIX Extensions): Reference Non-POSIX
Extensions.
(Non-POSIX Extensions): New node.
* nptl/Makefile (routines): Add thread_number.
(tests): Add tst-thread_number-single, tst-thread_number-multi,
tst-thread_number-single-static, tst-thread_number-multi-static.
(tests-nolibpthread): Add tst-thread_number-single,
tst-thread_number-single-static.
(tests-static): Add tst-thread_number-single-static,
tst-thread_number-multi-static.
* nptl/Versions (GLIBC_2.27): Export pthread_thread_number_np.
* nptl/allocatestack.c (allocate_stack): Increment
global_thread_number under__default_pthread_attr_lock and use its
value to set the new thread number.
* nptl/descr.h (struct pthread): Add number member.
* nptl/thread_number.c: New file.
* nptl/tst-thread_number-multi.c: Likewise.
* nptl/tst-thread_number-single.c: Likewise.
* nptl/tst-thread_number-multi-static.c: Likewise.
* nptl/tst-thread_number-single-static.c: Likewise.
* sysdeps/nptl/pthread.h (pthread_thread_number_np): Declare.
* sysdeps/unix/sysv/linux/hppa/pthread.h (pthread_thread_number_np):
Likewise.
* sysdeps/unix/sysv/linux/libc**.abilist: Update.
@@ -55,7 +55,8 @@ Major new features:
_Float32x types, as defined by ISO/IEC TS 18661-3:2015. These are
corresponding interfaces to those supported for _Float128.
-* glibc now implements the memfd_create and mlock2 functions on Linux.
+* glibc now implements the memfd_create, mlock2, and
+ pthread_thread_number_np functions on Linux.
* Support for memory protection keys was added. The <sys/mman.h> header now
declares the functions pkey_alloc, pkey_free, pkey_mprotect, pkey_set,
@@ -195,6 +195,7 @@ __libc_setup_tls (void)
#endif
if (__builtin_expect (lossage != NULL, 0))
_startup_fatal (lossage);
+ __dl_inittcb ();
/* Update the executable's link map with enough information to make
the TLS routines happy. */
@@ -31,7 +31,7 @@ routines = $(all-dl-routines) dl-support dl-iteratephdr \
# profiled libraries.
dl-routines = $(addprefix dl-,load lookup object reloc deps hwcaps \
runtime init fini debug misc \
- version profile tls origin scope \
+ version profile tls inittcb origin scope \
execstack caller open close trampoline \
exception sort-maps)
ifeq (yes,$(use-ldconfig))
new file mode 100644
@@ -0,0 +1,22 @@
+/* Initialize TCB contents. Generic version.
+ Copyright (C) 2017 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; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+void
+__dl_inittcb (void)
+{
+}
@@ -740,6 +740,7 @@ cannot allocate TLS data structures for initial thread\n");
const char *lossage = TLS_INIT_TP (tcbp);
if (__glibc_unlikely (lossage != NULL))
_dl_fatal_printf ("cannot set up thread-local storage: %s\n", lossage);
+ __dl_inittcb ();
tls_init_tp_called = true;
return tcbp;
@@ -80,6 +80,7 @@ the standard.
@menu
* Default Thread Attributes:: Setting default attributes for
threads in a process.
+* Identifying Threads:: Unique identifiers for threads.
@end menu
@node Default Thread Attributes
@@ -124,6 +125,30 @@ The system does not have sufficient memory.
@end table
@end deftypefun
+@node Identifying Threads
+@subsection Unique identifiers for threads
+
+@Theglibc{} provides a non-standard function to obtain a unique thread
+identifier.
+
+@deftypefun uint64_t pthread_thread_number_np (pthread_t @var{thread})
+@standards{GNU, pthread.h}
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+
+This function returns a number that uniquely identifies @var{thread}
+among all past, current, and future running threads. This number does
+not change during the life-time of the thread. Once returned by this
+function, a number will not be reused after the thread terminates.
+
+The returned number is only unique with regards to the current process.
+It may be shared by subprocesses and other processes in the system.
+
+The initial (main) thread has number 1. Thread numbers are not
+necessarily assigned in a consecutive fashion. They bear no
+relationship to POSIX thread IDs (@code{pthread_t} values), process IDs
+or thread IDs assigned by the kernel.
+@end deftypefun
+
@c FIXME these are undocumented:
@c pthread_atfork
@c pthread_attr_destroy
@@ -31,7 +31,7 @@ install-lib-ldscripts := libpthread.so
routines = alloca_cutoff forward libc-lowlevellock libc-cancellation \
libc-cleanup libc_pthread_init libc_multiple_threads \
- register-atfork unregister-atfork pthread_self
+ register-atfork unregister-atfork pthread_self thread_number
shared-only-routines = forward
# We need to provide certain routines for compatibility with existing
@@ -304,7 +304,8 @@ tests = tst-attr1 tst-attr2 tst-attr3 tst-default-attr \
c89 gnu89 c99 gnu99 c11 gnu11) \
tst-bad-schedattr \
tst-thread_local1 tst-mutex-errorcheck tst-robust10 \
- tst-robust-fork tst-create-detached tst-memstream
+ tst-robust-fork tst-create-detached tst-memstream \
+ tst-thread_number-single tst-thread_number-multi \
tests-internal := tst-rwlock19 tst-rwlock20 \
tst-sem11 tst-sem12 tst-sem13 \
@@ -320,7 +321,9 @@ test-srcs = tst-oddstacklimit
test-xfail-tst-once5 = yes
# Files which must not be linked with libpthread.
-tests-nolibpthread = tst-unload
+tests-nolibpthread = tst-unload \
+ tst-thread_number-single \
+ tst-thread_number-single-static \
gen-as-const-headers = pthread-errnos.sym \
unwindbuf.sym \
@@ -435,9 +438,13 @@ link-libc-static := $(common-objpfx)libc.a $(static-gnulib) \
tests-static += tst-locale1 tst-locale2 tst-stackguard1-static \
tst-cancel21-static tst-cancel24-static tst-cond8-static \
tst-mutex8-static tst-mutexpi8-static tst-sem11-static \
- tst-sem12-static
+ tst-sem12-static tst-thread_number-single-static \
+ tst-thread_number-multi-static \
+
tests += tst-cancel21-static tst-cancel24-static \
- tst-cond8-static
+ tst-cond8-static tst-thread_number-single-static \
+ tst-thread_number-multi-static \
+
tests-internal += tst-sem11-static tst-sem12-static tst-stackguard1-static
xtests-static += tst-setuid1-static
@@ -28,6 +28,9 @@ libc {
pthread_cond_wait; pthread_cond_signal;
pthread_cond_broadcast; pthread_cond_timedwait;
}
+ GLIBC_2.27 {
+ pthread_thread_number_np;
+ }
GLIBC_PRIVATE {
__libc_alloca_cutoff;
# Internal libc interface to libpthread
@@ -413,16 +413,28 @@ allocate_stack (const struct pthread_attr *attr, struct pthread **pdp,
assert (powerof2 (pagesize_m1 + 1));
assert (TCB_ALIGNMENT >= STACK_ALIGN);
- /* Get the stack size from the attribute if it is set. Otherwise we
- use the default we determined at start time. */
- if (attr->stacksize != 0)
- size = attr->stacksize;
- else
- {
- lll_lock (__default_pthread_attr_lock, LLL_PRIVATE);
+ uint64_t thread_number;
+ lll_lock (__default_pthread_attr_lock, LLL_PRIVATE);
+ {
+ /* Number 1 is reserved for the initial thread. Reuse
+ __default_pthread_attr_lock to avoid concurrent updates of this
+ counter. */
+ static uint64_t global_thread_number = 1;
+ thread_number = ++global_thread_number;
+
+ /* Check for counter wrap-around. This should never happen
+ because 2**64 is such a large value. */
+ if (thread_number == 0)
+ __libc_fatal ("Fatal glibc error: maximum number of threads exceeded\n");
+
+ /* Get the stack size from the attribute if it is set. Otherwise
+ we use the default we determined at start time. */
+ if (attr->stacksize != 0)
+ size = attr->stacksize;
+ else
size = __default_pthread_attr.stacksize;
- lll_unlock (__default_pthread_attr_lock, LLL_PRIVATE);
- }
+ }
+ lll_unlock (__default_pthread_attr_lock, LLL_PRIVATE);
/* Get memory for the stack. */
if (__glibc_unlikely (attr->flags & ATTR_FLAG_STACKADDR))
@@ -758,6 +770,8 @@ allocate_stack (const struct pthread_attr *attr, struct pthread **pdp,
#endif
pd->robust_head.list = &pd->robust_head;
+ pd->number = thread_number;
+
/* We place the thread descriptor at the end of the stack. */
*pdp = pd;
@@ -398,6 +398,9 @@ struct pthread
/* Resolver state. */
struct __res_state res;
+ /* Unique number assigned to this thread. */
+ uint64_t number;
+
/* This member must be last. */
char end_padding[];
new file mode 100644
@@ -0,0 +1,36 @@
+/* Unique numbers for threads.
+ Copyright (C) 2017 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; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include "pthreadP.h"
+
+/* This function should ideally return an integer wider than uint64_t,
+ so that the thread number can never-ever overflow. We may have to
+ switch to a 128-bit return value for new architectures
+ (particularly if those provide atomic operations on 128-bit
+ integers). But with current architectures, the baked-in limit of
+ 2**64 threads ever created by a process is not a problem because
+ architectural constraints result in a thread creation rate far
+ below one billion threads per second, and even at that rate, a
+ 64-bit counter lasts for hundreds of years. */
+
+__uint64_t
+pthread_thread_number_np (pthread_t threadid)
+{
+ struct pthread *pd = (struct pthread *) threadid;
+ return pd->number;
+}
new file mode 100644
@@ -0,0 +1,19 @@
+/* Test unique numbers for threads, static multi-threaded version.
+ Copyright (C) 2017 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; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include "tst-thread_number-multi.c"
new file mode 100644
@@ -0,0 +1,101 @@
+/* Test unique numbers for threads, non-static multi-threaded version.
+ Copyright (C) 2017 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; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <pthread.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <support/check.h>
+#include <support/namespace.h>
+#include <support/xthread.h>
+
+/* Used to check that the main thread still has thread number 1 in a
+ subprocess. */
+static void
+subprocess (void *closure)
+{
+ TEST_COMPARE (pthread_thread_number_np (pthread_self ()), 1U);
+}
+
+static void *
+subthread (void *closure)
+{
+ if (closure != NULL)
+ xpthread_barrier_wait (closure);
+ return NULL;
+}
+
+static int
+compare (const void *pleft, const void *pright)
+{
+ uint64_t left = *(const uint64_t *)pleft;
+ uint64_t right = *(const uint64_t *)pright;
+ if (left < right)
+ return -1;
+ if (left > right)
+ return 1;
+ return 0;
+}
+
+static int
+do_test (void)
+{
+ TEST_COMPARE (pthread_thread_number_np (pthread_self ()), 1U);
+ support_isolate_in_subprocess (subprocess, NULL);
+
+ /* Create thread_count threads, half of which are joined
+ immediately, have of which stay around. */
+ enum { thread_count = 10 };
+ pthread_barrier_t barrier;
+ xpthread_barrier_init (&barrier, NULL, thread_count / 2 + 1);
+ uint64_t ids[thread_count];
+ pthread_t threads[thread_count]; /* Only even-numbered entries are valid. */
+ for (int i = 0; i < thread_count; ++i)
+ {
+ bool stay_around = (i % 2) == 0;
+ threads[i] = xpthread_create (NULL, subthread,
+ stay_around ? &barrier : NULL);
+ ids[i] = pthread_thread_number_np (threads[i]);
+ TEST_VERIFY (ids[i] != 1);
+ if (!stay_around)
+ xpthread_join (threads[i]);
+ }
+
+ /* Check that the IDs are all distinct. */
+ qsort (ids, thread_count, sizeof (ids[0]), compare);
+ for (int i = 1; i < thread_count; ++i)
+ TEST_VERIFY (ids[i - 1] < ids[i]);
+
+ /* Main thread ID should remain at 1. */
+ TEST_COMPARE (pthread_thread_number_np (pthread_self ()), 1U);
+ support_isolate_in_subprocess (subprocess, NULL);
+
+ /* Clean up. */
+ xpthread_barrier_wait (&barrier);
+ for (int i = 0; i < thread_count; ++i)
+ if ((i % 2) == 0)
+ xpthread_join (threads[i]);
+
+ /* Main thread ID should still remain at 1. */
+ TEST_COMPARE (pthread_thread_number_np (pthread_self ()), 1U);
+ support_isolate_in_subprocess (subprocess, NULL);
+
+ return 0;
+}
+
+#include <support/test-driver.c>
new file mode 100644
@@ -0,0 +1,19 @@
+/* Test unique numbers for threads, static single-threaded version.
+ Copyright (C) 2017 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; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include "tst-thread_number-single.c"
new file mode 100644
@@ -0,0 +1,40 @@
+/* Test unique numbers for threads, non-static single-threaded version.
+ Copyright (C) 2017 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; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <pthread.h>
+#include <support/check.h>
+#include <support/namespace.h>
+
+/* Used to check that the main thread still has thread number 1 in a
+ subprocess. */
+static void
+subprocess (void *closure)
+{
+ TEST_COMPARE (pthread_thread_number_np (pthread_self ()), 1U);
+}
+
+static int
+do_test (void)
+{
+ TEST_COMPARE (pthread_thread_number_np (pthread_self ()), 1U);
+ support_isolate_in_subprocess (subprocess, NULL);
+
+ return 0;
+}
+
+#include <support/test-driver.c>
@@ -1071,6 +1071,10 @@ extern struct link_map * _dl_get_dl_main_map (void)
void __pthread_initialize_minimal (void) weak_function;
#endif
+/* Initialize the already-existing TCB for the main thread. Called
+ during dynamic linker startup or from __libc_setup_tls. */
+void __dl_inittcb (void) attribute_hidden;
+
/* Allocate memory for static TLS block (unless MEM is nonzero) and dtv. */
extern void *_dl_allocate_tls (void *mem);
rtld_hidden_proto (_dl_allocate_tls)
new file mode 100644
@@ -0,0 +1,27 @@
+/* Initialize TCB contents. NPTL version.
+ Copyright (C) 2017 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; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <ldsodefs.h>
+#include <tls.h>
+
+void
+__dl_inittcb (void)
+{
+ /* The main thread has number 1. */
+ THREAD_SELF->number = 1;
+}
@@ -1145,6 +1145,10 @@ extern int pthread_atfork (void (*__prepare) (void),
void (*__child) (void)) __THROW;
+/* Return a number uniquely identifying THREAD, even after its
+ termination. */
+__uint64_t pthread_thread_number_np (pthread_t __thread_id) __THROW;
+
#ifdef __USE_EXTERN_INLINES
/* Optimizations. */
__extern_inline int
@@ -2114,6 +2114,7 @@ GLIBC_2.27 pkey_free F
GLIBC_2.27 pkey_get F
GLIBC_2.27 pkey_mprotect F
GLIBC_2.27 pkey_set F
+GLIBC_2.27 pthread_thread_number_np F
GLIBC_2.27 strfromf128 F
GLIBC_2.27 strfromf32 F
GLIBC_2.27 strfromf32x F
@@ -2025,6 +2025,7 @@ GLIBC_2.27 pkey_free F
GLIBC_2.27 pkey_get F
GLIBC_2.27 pkey_mprotect F
GLIBC_2.27 pkey_set F
+GLIBC_2.27 pthread_thread_number_np F
GLIBC_2.27 strfromf128 F
GLIBC_2.27 strfromf32 F
GLIBC_2.27 strfromf32x F
@@ -115,6 +115,7 @@ GLIBC_2.27 pkey_free F
GLIBC_2.27 pkey_get F
GLIBC_2.27 pkey_mprotect F
GLIBC_2.27 pkey_set F
+GLIBC_2.27 pthread_thread_number_np F
GLIBC_2.27 strfromf32 F
GLIBC_2.27 strfromf32x F
GLIBC_2.27 strfromf64 F
@@ -1879,6 +1879,7 @@ GLIBC_2.27 pkey_free F
GLIBC_2.27 pkey_get F
GLIBC_2.27 pkey_mprotect F
GLIBC_2.27 pkey_set F
+GLIBC_2.27 pthread_thread_number_np F
GLIBC_2.27 strfromf32 F
GLIBC_2.27 strfromf32x F
GLIBC_2.27 strfromf64 F
@@ -1120,6 +1120,9 @@ extern int pthread_atfork (void (*__prepare) (void),
void (*__parent) (void),
void (*__child) (void)) __THROW;
+/* Return a number uniquely identifying THREAD, even after its
+ termination. */
+__uint64_t pthread_thread_number_np (pthread_t __thread_id) __THROW;
#ifdef __USE_EXTERN_INLINES
/* Optimizations. */
@@ -2044,6 +2044,7 @@ GLIBC_2.27 pkey_free F
GLIBC_2.27 pkey_get F
GLIBC_2.27 pkey_mprotect F
GLIBC_2.27 pkey_set F
+GLIBC_2.27 pthread_thread_number_np F
GLIBC_2.27 strfromf32 F
GLIBC_2.27 strfromf32x F
GLIBC_2.27 strfromf64 F
@@ -1908,6 +1908,7 @@ GLIBC_2.27 pkey_free F
GLIBC_2.27 pkey_get F
GLIBC_2.27 pkey_mprotect F
GLIBC_2.27 pkey_set F
+GLIBC_2.27 pthread_thread_number_np F
GLIBC_2.27 strfromf32 F
GLIBC_2.27 strfromf32x F
GLIBC_2.27 strfromf64 F
@@ -116,6 +116,7 @@ GLIBC_2.27 pkey_free F
GLIBC_2.27 pkey_get F
GLIBC_2.27 pkey_mprotect F
GLIBC_2.27 pkey_set F
+GLIBC_2.27 pthread_thread_number_np F
GLIBC_2.27 strfromf32 F
GLIBC_2.27 strfromf32x F
GLIBC_2.27 strfromf64 F
@@ -1993,6 +1993,7 @@ GLIBC_2.27 pkey_free F
GLIBC_2.27 pkey_get F
GLIBC_2.27 pkey_mprotect F
GLIBC_2.27 pkey_set F
+GLIBC_2.27 pthread_thread_number_np F
GLIBC_2.27 strfromf32 F
GLIBC_2.27 strfromf32x F
GLIBC_2.27 strfromf64 F
@@ -2114,6 +2114,7 @@ GLIBC_2.27 pkey_free F
GLIBC_2.27 pkey_get F
GLIBC_2.27 pkey_mprotect F
GLIBC_2.27 pkey_set F
+GLIBC_2.27 pthread_thread_number_np F
GLIBC_2.27 strfromf32 F
GLIBC_2.27 strfromf32x F
GLIBC_2.27 strfromf64 F
@@ -1968,6 +1968,7 @@ GLIBC_2.27 pkey_free F
GLIBC_2.27 pkey_get F
GLIBC_2.27 pkey_mprotect F
GLIBC_2.27 pkey_set F
+GLIBC_2.27 pthread_thread_number_np F
GLIBC_2.27 strfromf32 F
GLIBC_2.27 strfromf32x F
GLIBC_2.27 strfromf64 F
@@ -1966,6 +1966,7 @@ GLIBC_2.27 pkey_free F
GLIBC_2.27 pkey_get F
GLIBC_2.27 pkey_mprotect F
GLIBC_2.27 pkey_set F
+GLIBC_2.27 pthread_thread_number_np F
GLIBC_2.27 strfromf32 F
GLIBC_2.27 strfromf32x F
GLIBC_2.27 strfromf64 F
@@ -1964,6 +1964,7 @@ GLIBC_2.27 pkey_free F
GLIBC_2.27 pkey_get F
GLIBC_2.27 pkey_mprotect F
GLIBC_2.27 pkey_set F
+GLIBC_2.27 pthread_thread_number_np F
GLIBC_2.27 strfromf128 F
GLIBC_2.27 strfromf32 F
GLIBC_2.27 strfromf32x F
@@ -1959,6 +1959,7 @@ GLIBC_2.27 pkey_free F
GLIBC_2.27 pkey_get F
GLIBC_2.27 pkey_mprotect F
GLIBC_2.27 pkey_set F
+GLIBC_2.27 pthread_thread_number_np F
GLIBC_2.27 strfromf128 F
GLIBC_2.27 strfromf32 F
GLIBC_2.27 strfromf32x F
@@ -2155,6 +2155,7 @@ GLIBC_2.27 pkey_free F
GLIBC_2.27 pkey_get F
GLIBC_2.27 pkey_mprotect F
GLIBC_2.27 pkey_set F
+GLIBC_2.27 pthread_thread_number_np F
GLIBC_2.27 strfromf32 F
GLIBC_2.27 strfromf32x F
GLIBC_2.27 strfromf64 F
@@ -1997,6 +1997,7 @@ GLIBC_2.27 pkey_free F
GLIBC_2.27 pkey_get F
GLIBC_2.27 pkey_mprotect F
GLIBC_2.27 pkey_set F
+GLIBC_2.27 pthread_thread_number_np F
GLIBC_2.27 strfromf32 F
GLIBC_2.27 strfromf32x F
GLIBC_2.27 strfromf64 F
@@ -2002,6 +2002,7 @@ GLIBC_2.27 pkey_free F
GLIBC_2.27 pkey_get F
GLIBC_2.27 pkey_mprotect F
GLIBC_2.27 pkey_set F
+GLIBC_2.27 pthread_thread_number_np F
GLIBC_2.27 strfromf32 F
GLIBC_2.27 strfromf32x F
GLIBC_2.27 strfromf64 F
@@ -2209,6 +2209,7 @@ GLIBC_2.27 pkey_free F
GLIBC_2.27 pkey_get F
GLIBC_2.27 pkey_mprotect F
GLIBC_2.27 pkey_set F
+GLIBC_2.27 pthread_thread_number_np F
GLIBC_2.27 strfromf32 F
GLIBC_2.27 strfromf32x F
GLIBC_2.27 strfromf64 F
@@ -116,6 +116,7 @@ GLIBC_2.27 pkey_free F
GLIBC_2.27 pkey_get F
GLIBC_2.27 pkey_mprotect F
GLIBC_2.27 pkey_set F
+GLIBC_2.27 pthread_thread_number_np F
GLIBC_2.27 strfromf32 F
GLIBC_2.27 strfromf32x F
GLIBC_2.27 strfromf64 F
@@ -1997,6 +1997,7 @@ GLIBC_2.27 pkey_free F
GLIBC_2.27 pkey_get F
GLIBC_2.27 pkey_mprotect F
GLIBC_2.27 pkey_set F
+GLIBC_2.27 pthread_thread_number_np F
GLIBC_2.27 strfromf128 F
GLIBC_2.27 strfromf32 F
GLIBC_2.27 strfromf32x F
@@ -1898,6 +1898,7 @@ GLIBC_2.27 pkey_free F
GLIBC_2.27 pkey_get F
GLIBC_2.27 pkey_mprotect F
GLIBC_2.27 pkey_set F
+GLIBC_2.27 pthread_thread_number_np F
GLIBC_2.27 strfromf128 F
GLIBC_2.27 strfromf32 F
GLIBC_2.27 strfromf32x F
@@ -1883,6 +1883,7 @@ GLIBC_2.27 pkey_free F
GLIBC_2.27 pkey_get F
GLIBC_2.27 pkey_mprotect F
GLIBC_2.27 pkey_set F
+GLIBC_2.27 pthread_thread_number_np F
GLIBC_2.27 strfromf32 F
GLIBC_2.27 strfromf32x F
GLIBC_2.27 strfromf64 F
@@ -1990,6 +1990,7 @@ GLIBC_2.27 pkey_free F
GLIBC_2.27 pkey_get F
GLIBC_2.27 pkey_mprotect F
GLIBC_2.27 pkey_set F
+GLIBC_2.27 pthread_thread_number_np F
GLIBC_2.27 strfromf128 F
GLIBC_2.27 strfromf32 F
GLIBC_2.27 strfromf32x F
@@ -1927,6 +1927,7 @@ GLIBC_2.27 pkey_free F
GLIBC_2.27 pkey_get F
GLIBC_2.27 pkey_mprotect F
GLIBC_2.27 pkey_set F
+GLIBC_2.27 pthread_thread_number_np F
GLIBC_2.27 strfromf128 F
GLIBC_2.27 strfromf32 F
GLIBC_2.27 strfromf32x F
@@ -2121,6 +2121,7 @@ GLIBC_2.27 pkey_free F
GLIBC_2.27 pkey_get F
GLIBC_2.27 pkey_mprotect F
GLIBC_2.27 pkey_set F
+GLIBC_2.27 pthread_thread_number_np F
GLIBC_2.27 strfromf32 F
GLIBC_2.27 strfromf32x F
GLIBC_2.27 strfromf64 F
@@ -2121,6 +2121,7 @@ GLIBC_2.27 pkey_free F
GLIBC_2.27 pkey_get F
GLIBC_2.27 pkey_mprotect F
GLIBC_2.27 pkey_set F
+GLIBC_2.27 pthread_thread_number_np F
GLIBC_2.27 strfromf32 F
GLIBC_2.27 strfromf32x F
GLIBC_2.27 strfromf64 F
@@ -1885,6 +1885,7 @@ GLIBC_2.27 pkey_free F
GLIBC_2.27 pkey_get F
GLIBC_2.27 pkey_mprotect F
GLIBC_2.27 pkey_set F
+GLIBC_2.27 pthread_thread_number_np F
GLIBC_2.27 strfromf32 F
GLIBC_2.27 strfromf32x F
GLIBC_2.27 strfromf64 F
@@ -2128,6 +2128,7 @@ GLIBC_2.27 pkey_free F
GLIBC_2.27 pkey_get F
GLIBC_2.27 pkey_mprotect F
GLIBC_2.27 pkey_set F
+GLIBC_2.27 pthread_thread_number_np F
GLIBC_2.27 strfromf32 F
GLIBC_2.27 strfromf32x F
GLIBC_2.27 strfromf64 F