@@ -46,6 +46,8 @@ Major new features:
incosistent mutex state after fork call in multithread environment.
In both popen and system there is no direct access to user-defined mutexes.
+* On Linux, the gettid function has been added.
+
Deprecated and removed features, and other changes affecting compatibility:
* The glibc.tune tunable namespace has been renamed to glibc.cpu and the
@@ -228,6 +228,17 @@ The @code{getppid} function returns the process ID of the parent of the
current process.
@end deftypefun
+@deftypefun pid_t gettid (void)
+@standards{Linux, unistd.h}
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+The @code{gettid} function returns the thread ID of the current
+thread. The returned value is obtained from the Linux kernel and is
+not subject to caching. See the discussion of thread IDs above,
+especially regarding reuse of the IDs of threads which have exited.
+
+This function is specific to Linux.
+@end deftypefun
+
@node Creating a Process
@section Creating a Process
@@ -31,7 +31,8 @@ headers := sys/utsname.h sys/times.h sys/wait.h sys/types.h unistd.h \
bits/local_lim.h tar.h bits/utsname.h bits/confname.h \
bits/waitflags.h bits/waitstatus.h sys/unistd.h sched.h \
bits/sched.h bits/cpu-set.h re_comp.h wait.h bits/environments.h \
- cpio.h spawn.h bits/unistd.h bits/types/struct_sched_param.h
+ cpio.h spawn.h bits/unistd.h bits/types/struct_sched_param.h \
+ bits/unistd_ext.h
routines := \
uname \
new file mode 100644
@@ -0,0 +1,21 @@
+/* System-specific extensions of <unistd.h>, generic version.
+ Copyright (C) 2018 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/>. */
+
+#ifndef _UNISTD_H
+# error "Never include <bits/unistd_ext.h> directly; use <unistd.h> instead."
+#endif
@@ -1166,6 +1166,9 @@ int getentropy (void *__buffer, size_t __length) __wur;
# include <bits/unistd.h>
#endif
+/* System-specific extensions. */
+#include <bits/unistd_ext.h>
+
__END_DECLS
#endif /* unistd.h */
@@ -48,10 +48,9 @@ sysdep_headers += sys/mount.h sys/acct.h sys/sysctl.h \
tests += tst-clone tst-clone2 tst-clone3 tst-fanotify tst-personality \
tst-quota tst-sync_file_range tst-sysconf-iov_max tst-ttyname \
test-errno-linux tst-memfd_create tst-mlock2 tst-pkey \
- tst-rlimit-infinity tst-ofdlocks
+ tst-rlimit-infinity tst-ofdlocks tst-gettid tst-gettid-kill
tests-internal += tst-ofdlocks-compat
-
# Generate the list of SYS_* macros for the system calls (__NR_*
# macros). The file syscall-names.list contains all possible system
# call names, and the generated header file produces SYS_* macros for
@@ -100,6 +99,9 @@ $(objpfx)tst-sysconf-iov_max: $(objpfx)tst-sysconf-iov_max-uapi.o
$(objpfx)tst-pkey: $(shared-thread-library)
+$(objpfx)tst-gettid: $(shared-thread-library)
+$(objpfx)tst-gettid-kill: $(shared-thread-library)
+
endif # $(subdir) == misc
ifeq ($(subdir),time)
@@ -173,6 +173,7 @@ libc {
}
GLIBC_2.29 {
getcpu;
+ gettid;
}
GLIBC_PRIVATE {
# functions used in other libraries
@@ -2139,5 +2139,6 @@ GLIBC_2.28 thrd_equal F
GLIBC_2.28 thrd_sleep F
GLIBC_2.28 thrd_yield F
GLIBC_2.29 getcpu F
+GLIBC_2.29 gettid F
GLIBC_2.29 posix_spawn_file_actions_addchdir_np F
GLIBC_2.29 posix_spawn_file_actions_addfchdir_np F
@@ -2034,6 +2034,7 @@ GLIBC_2.28 thrd_equal F
GLIBC_2.28 thrd_sleep F
GLIBC_2.28 thrd_yield F
GLIBC_2.29 getcpu F
+GLIBC_2.29 gettid F
GLIBC_2.29 posix_spawn_file_actions_addchdir_np F
GLIBC_2.29 posix_spawn_file_actions_addfchdir_np F
GLIBC_2.3 __ctype_b_loc F
@@ -124,6 +124,7 @@ GLIBC_2.28 thrd_equal F
GLIBC_2.28 thrd_sleep F
GLIBC_2.28 thrd_yield F
GLIBC_2.29 getcpu F
+GLIBC_2.29 gettid F
GLIBC_2.29 posix_spawn_file_actions_addchdir_np F
GLIBC_2.29 posix_spawn_file_actions_addfchdir_np F
GLIBC_2.4 _Exit F
new file mode 100644
@@ -0,0 +1,36 @@
+/* System-specific extensions of <unistd.h>, Linux version.
+ Copyright (C) 2018 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/>. */
+
+#ifndef _UNISTD_H
+# error "Never include <bits/unistd_ext.h> directly; use <unistd.h> instead."
+#endif
+
+#ifdef __USE_GNU
+
+/* Return the kernel thread ID (TID) of the current thread. The
+ returned value is not subject to caching. Most Linux system calls
+ accept a TID in place of a PID. Using the TID to change properties
+ of a thread that has been created using pthread_create can lead to
+ undefined behavior (comparable to manipulating file descriptors
+ directly that have not been created explicitly). Note that a TID
+ uniquely identifies a thread only while this thread is running; a
+ TID can be reused once a thread has exited, even if the thread is
+ not detached and has not been joined. */
+extern __pid_t gettid (void) __THROW;
+
+#endif
@@ -1881,6 +1881,7 @@ GLIBC_2.28 thrd_equal F
GLIBC_2.28 thrd_sleep F
GLIBC_2.28 thrd_yield F
GLIBC_2.29 getcpu F
+GLIBC_2.29 gettid F
GLIBC_2.29 posix_spawn_file_actions_addchdir_np F
GLIBC_2.29 posix_spawn_file_actions_addfchdir_np F
GLIBC_2.3 __ctype_b_loc F
@@ -2046,6 +2046,7 @@ GLIBC_2.28 thrd_equal F
GLIBC_2.28 thrd_sleep F
GLIBC_2.28 thrd_yield F
GLIBC_2.29 getcpu F
+GLIBC_2.29 gettid F
GLIBC_2.29 posix_spawn_file_actions_addchdir_np F
GLIBC_2.29 posix_spawn_file_actions_addfchdir_np F
GLIBC_2.3 __ctype_b_loc F
@@ -1915,6 +1915,7 @@ GLIBC_2.28 thrd_equal F
GLIBC_2.28 thrd_sleep F
GLIBC_2.28 thrd_yield F
GLIBC_2.29 getcpu F
+GLIBC_2.29 gettid F
GLIBC_2.29 posix_spawn_file_actions_addchdir_np F
GLIBC_2.29 posix_spawn_file_actions_addfchdir_np F
GLIBC_2.3 __ctype_b_loc F
@@ -125,6 +125,7 @@ GLIBC_2.28 thrd_equal F
GLIBC_2.28 thrd_sleep F
GLIBC_2.28 thrd_yield F
GLIBC_2.29 getcpu F
+GLIBC_2.29 gettid F
GLIBC_2.29 posix_spawn_file_actions_addchdir_np F
GLIBC_2.29 posix_spawn_file_actions_addfchdir_np F
GLIBC_2.4 _Exit F
@@ -1990,6 +1990,7 @@ GLIBC_2.28 thrd_equal F
GLIBC_2.28 thrd_sleep F
GLIBC_2.28 thrd_yield F
GLIBC_2.29 getcpu F
+GLIBC_2.29 gettid F
GLIBC_2.29 posix_spawn_file_actions_addchdir_np F
GLIBC_2.29 posix_spawn_file_actions_addfchdir_np F
GLIBC_2.3 __ctype_b_loc F
@@ -2131,5 +2131,6 @@ GLIBC_2.28 thrd_equal F
GLIBC_2.28 thrd_sleep F
GLIBC_2.28 thrd_yield F
GLIBC_2.29 getcpu F
+GLIBC_2.29 gettid F
GLIBC_2.29 posix_spawn_file_actions_addchdir_np F
GLIBC_2.29 posix_spawn_file_actions_addfchdir_np F
@@ -1968,6 +1968,7 @@ GLIBC_2.28 thrd_equal F
GLIBC_2.28 thrd_sleep F
GLIBC_2.28 thrd_yield F
GLIBC_2.29 getcpu F
+GLIBC_2.29 gettid F
GLIBC_2.29 posix_spawn_file_actions_addchdir_np F
GLIBC_2.29 posix_spawn_file_actions_addfchdir_np F
GLIBC_2.3 __ctype_b_loc F
@@ -1966,6 +1966,7 @@ GLIBC_2.28 thrd_equal F
GLIBC_2.28 thrd_sleep F
GLIBC_2.28 thrd_yield F
GLIBC_2.29 getcpu F
+GLIBC_2.29 gettid F
GLIBC_2.29 posix_spawn_file_actions_addchdir_np F
GLIBC_2.29 posix_spawn_file_actions_addfchdir_np F
GLIBC_2.3 __ctype_b_loc F
@@ -1974,6 +1974,7 @@ GLIBC_2.28 thrd_equal F
GLIBC_2.28 thrd_sleep F
GLIBC_2.28 thrd_yield F
GLIBC_2.29 getcpu F
+GLIBC_2.29 gettid F
GLIBC_2.29 posix_spawn_file_actions_addchdir_np F
GLIBC_2.29 posix_spawn_file_actions_addfchdir_np F
GLIBC_2.3 __ctype_b_loc F
@@ -1969,6 +1969,7 @@ GLIBC_2.28 thrd_equal F
GLIBC_2.28 thrd_sleep F
GLIBC_2.28 thrd_yield F
GLIBC_2.29 getcpu F
+GLIBC_2.29 gettid F
GLIBC_2.29 posix_spawn_file_actions_addchdir_np F
GLIBC_2.29 posix_spawn_file_actions_addfchdir_np F
GLIBC_2.3 __ctype_b_loc F
@@ -2172,5 +2172,6 @@ GLIBC_2.28 thrd_equal F
GLIBC_2.28 thrd_sleep F
GLIBC_2.28 thrd_yield F
GLIBC_2.29 getcpu F
+GLIBC_2.29 gettid F
GLIBC_2.29 posix_spawn_file_actions_addchdir_np F
GLIBC_2.29 posix_spawn_file_actions_addfchdir_np F
@@ -1994,6 +1994,7 @@ GLIBC_2.28 thrd_equal F
GLIBC_2.28 thrd_sleep F
GLIBC_2.28 thrd_yield F
GLIBC_2.29 getcpu F
+GLIBC_2.29 gettid F
GLIBC_2.29 posix_spawn_file_actions_addchdir_np F
GLIBC_2.29 posix_spawn_file_actions_addfchdir_np F
GLIBC_2.3 __ctype_b_loc F
@@ -1998,6 +1998,7 @@ GLIBC_2.28 thrd_equal F
GLIBC_2.28 thrd_sleep F
GLIBC_2.28 thrd_yield F
GLIBC_2.29 getcpu F
+GLIBC_2.29 gettid F
GLIBC_2.29 posix_spawn_file_actions_addchdir_np F
GLIBC_2.29 posix_spawn_file_actions_addfchdir_np F
GLIBC_2.3 __ctype_b_loc F
@@ -124,6 +124,7 @@ GLIBC_2.28 thrd_equal F
GLIBC_2.28 thrd_sleep F
GLIBC_2.28 thrd_yield F
GLIBC_2.29 getcpu F
+GLIBC_2.29 gettid F
GLIBC_2.29 posix_spawn_file_actions_addchdir_np F
GLIBC_2.29 posix_spawn_file_actions_addfchdir_np F
GLIBC_2.3 _Exit F
@@ -2229,5 +2229,6 @@ GLIBC_2.28 thrd_equal F
GLIBC_2.28 thrd_sleep F
GLIBC_2.28 thrd_yield F
GLIBC_2.29 getcpu F
+GLIBC_2.29 gettid F
GLIBC_2.29 posix_spawn_file_actions_addchdir_np F
GLIBC_2.29 posix_spawn_file_actions_addfchdir_np F
@@ -2101,5 +2101,6 @@ GLIBC_2.28 thrd_equal F
GLIBC_2.28 thrd_sleep F
GLIBC_2.28 thrd_yield F
GLIBC_2.29 getcpu F
+GLIBC_2.29 gettid F
GLIBC_2.29 posix_spawn_file_actions_addchdir_np F
GLIBC_2.29 posix_spawn_file_actions_addfchdir_np F
@@ -2003,6 +2003,7 @@ GLIBC_2.28 thrd_equal F
GLIBC_2.28 thrd_sleep F
GLIBC_2.28 thrd_yield F
GLIBC_2.29 getcpu F
+GLIBC_2.29 gettid F
GLIBC_2.29 posix_spawn_file_actions_addchdir_np F
GLIBC_2.29 posix_spawn_file_actions_addfchdir_np F
GLIBC_2.3 __ctype_b_loc F
@@ -1909,6 +1909,7 @@ GLIBC_2.28 thrd_sleep F
GLIBC_2.28 thrd_yield F
GLIBC_2.29 __fentry__ F
GLIBC_2.29 getcpu F
+GLIBC_2.29 gettid F
GLIBC_2.29 posix_spawn_file_actions_addchdir_np F
GLIBC_2.29 posix_spawn_file_actions_addfchdir_np F
GLIBC_2.3 __ctype_b_loc F
@@ -1885,6 +1885,7 @@ GLIBC_2.28 thrd_equal F
GLIBC_2.28 thrd_sleep F
GLIBC_2.28 thrd_yield F
GLIBC_2.29 getcpu F
+GLIBC_2.29 gettid F
GLIBC_2.29 posix_spawn_file_actions_addchdir_np F
GLIBC_2.29 posix_spawn_file_actions_addfchdir_np F
GLIBC_2.3 __ctype_b_loc F
@@ -1997,6 +1997,7 @@ GLIBC_2.28 thrd_equal F
GLIBC_2.28 thrd_sleep F
GLIBC_2.28 thrd_yield F
GLIBC_2.29 getcpu F
+GLIBC_2.29 gettid F
GLIBC_2.29 posix_spawn_file_actions_addchdir_np F
GLIBC_2.29 posix_spawn_file_actions_addfchdir_np F
GLIBC_2.3 __ctype_b_loc F
@@ -1938,6 +1938,7 @@ GLIBC_2.28 thrd_equal F
GLIBC_2.28 thrd_sleep F
GLIBC_2.28 thrd_yield F
GLIBC_2.29 getcpu F
+GLIBC_2.29 gettid F
GLIBC_2.29 posix_spawn_file_actions_addchdir_np F
GLIBC_2.29 posix_spawn_file_actions_addfchdir_np F
GLIBC_2.3 __ctype_b_loc F
@@ -112,3 +112,4 @@ process_vm_writev EXTRA process_vm_writev i:ipipii process_vm_writev
memfd_create EXTRA memfd_create i:si memfd_create
pkey_alloc EXTRA pkey_alloc i:ii pkey_alloc
pkey_free EXTRA pkey_free i:i pkey_free
+gettid EXTRA gettid Ei: __gettid gettid
new file mode 100644
@@ -0,0 +1,129 @@
+/* Verify the interaction of kill and thread groups.
+ Copyright (C) 2018 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/>. */
+
+/* This test demonstrates that a signal which is sent to a specified
+ thread ID using the kill function is delivered to the entire thread
+ group (as if it had been sent to the process group). */
+
+#include <errno.h>
+#include <signal.h>
+#include <support/check.h>
+#include <support/xsignal.h>
+#include <support/xthread.h>
+#include <support/xunistd.h>
+
+/* Signal set containing SIGUSR1. */
+static sigset_t sigusr1_set;
+
+/* Used to synchronize the threads. */
+static pthread_barrier_t barrier;
+
+/* TID of the thread to which the signal is sent. */
+static pid_t target_tid;
+
+/* Thread which is expected to receive the SIGUSR1 signal. */
+static pthread_t signal_thread;
+
+/* Pipe used to block and terminate the signal thread. */
+static int pipe_signal[2];
+
+static volatile sig_atomic_t handler_tid;
+
+static void
+sigusr1_handler (int signo)
+{
+ TEST_COMPARE (signo, SIGUSR1);
+ TEST_VERIFY (pthread_self () == signal_thread);
+ TEST_COMPARE (handler_tid, 0);
+ handler_tid = gettid ();
+ TEST_VERIFY (handler_tid > 0);
+ /* Ensure that the read system call in thread_read exits if the
+ signal is delivered before the system call is invoked. */
+ char ch = 'X';
+ xwrite (pipe_signal[1], &ch, 1);
+}
+
+/* Thread which calls pause without expecting it to return. The TID
+ of this thread is used as the target in the kill function call. */
+static void *
+thread_pause_noreturn (void *closure)
+{
+ target_tid = gettid ();
+ TEST_VERIFY (target_tid > 0);
+ xpthread_barrier_wait (&barrier);
+ pause ();
+ FAIL_EXIT1 ("The pause function returned");
+ return NULL;
+}
+
+/* Thread which is expected to receive the signal. */
+static void *
+thread_read_signal (void *closure)
+{
+ xpthread_sigmask (SIG_UNBLOCK, &sigusr1_set, NULL);
+ xpthread_barrier_wait (&barrier);
+ TEST_VERIFY (target_tid > 0);
+ TEST_VERIFY (gettid () != target_tid);
+ char ch;
+ ssize_t ret = read (pipe_signal[0], &ch, 1);
+ if (ret == 1)
+ /* The signal was delivered before we entered the read system
+ call. */
+ TEST_COMPARE (ch, 'X');
+ else
+ {
+ /* The signal was delivered while blocked in the read system
+ call. */
+ TEST_COMPARE (ret, -1);
+ TEST_COMPARE (errno, EINTR);
+ }
+ TEST_COMPARE (handler_tid, gettid ());
+ return NULL;
+}
+
+static int
+do_test (void)
+{
+ /* Block the SIGUSR1 signal in all threads. */
+ sigemptyset (&sigusr1_set);
+ sigaddset (&sigusr1_set, SIGUSR1);
+ xpthread_sigmask (SIG_BLOCK, &sigusr1_set, NULL);
+
+ xsignal (SIGUSR1, sigusr1_handler);
+ xpipe (pipe_signal);
+
+ xpthread_barrier_init (&barrier, NULL, 3);
+
+ pthread_t target_thread
+ = xpthread_create (NULL, thread_pause_noreturn, NULL);
+ signal_thread = xpthread_create (NULL, thread_read_signal, NULL);
+ xpthread_barrier_wait (&barrier);
+
+ /* Send the SIGUSR1 signal to the thread which has it blocked, and
+ expect it to be delivered to the other thread. */
+ TEST_COMPARE (kill (target_tid, SIGUSR1), 0);
+
+ xpthread_join (signal_thread);
+ xpthread_cancel (target_thread);
+ xpthread_join (target_thread);
+
+ xpthread_barrier_destroy (&barrier);
+ return 0;
+}
+
+#include <support/test-driver.c>
new file mode 100644
@@ -0,0 +1,79 @@
+/* Smoke test for the gettid system call.
+ Copyright (C) 2018 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 <support/check.h>
+#include <support/namespace.h>
+#include <support/xthread.h>
+#include <support/xunistd.h>
+
+/* TID of the initial (main) thread. */
+static pid_t initial_tid;
+
+/* Check that PID and TID are the same in a subprocess. */
+static void
+subprocess (void *closure)
+{
+ TEST_COMPARE (getpid (), gettid ());
+ TEST_VERIFY (gettid () != initial_tid);
+}
+
+/* Check that the TID changes in a new thread. */
+static void *
+threadfunc (void *closure)
+{
+ TEST_VERIFY (getpid () != gettid ());
+ TEST_VERIFY (gettid () != initial_tid);
+ return NULL;
+}
+
+/* Check for interactions with vfork. */
+static void
+test_vfork (void)
+{
+ pid_t proc = vfork ();
+ if (proc == 0)
+ {
+ if (getpid () != gettid ())
+ _exit (1);
+ if (gettid () == initial_tid)
+ _exit (2);
+ _exit (0);
+ }
+ int status;
+ xwaitpid (proc, &status, 0);
+ TEST_COMPARE (status, 0);
+}
+
+static int
+do_test (void)
+{
+ initial_tid = gettid ();
+
+ /* The main thread has the same TID as the PID. */
+ TEST_COMPARE (getpid (), gettid ());
+
+ test_vfork ();
+
+ support_isolate_in_subprocess (subprocess, NULL);
+
+ xpthread_join (xpthread_create (NULL, threadfunc, NULL));
+
+ return 0;
+}
+
+#include <support/test-driver.c>
@@ -43,12 +43,6 @@
terminator. */
#define TASK_COMM_LEN 16
-long
-gettid (void)
-{
- return syscall(__NR_gettid);
-}
-
/* On Linux we can read this task's name from /proc. */
int
get_self_comm (long tid, char *buf, size_t len)
@@ -1896,6 +1896,7 @@ GLIBC_2.28 thrd_equal F
GLIBC_2.28 thrd_sleep F
GLIBC_2.28 thrd_yield F
GLIBC_2.29 getcpu F
+GLIBC_2.29 gettid F
GLIBC_2.29 posix_spawn_file_actions_addchdir_np F
GLIBC_2.29 posix_spawn_file_actions_addfchdir_np F
GLIBC_2.3 __ctype_b_loc F
@@ -2147,5 +2147,6 @@ GLIBC_2.28 thrd_equal F
GLIBC_2.28 thrd_sleep F
GLIBC_2.28 thrd_yield F
GLIBC_2.29 getcpu F
+GLIBC_2.29 gettid F
GLIBC_2.29 posix_spawn_file_actions_addchdir_np F
GLIBC_2.29 posix_spawn_file_actions_addfchdir_np F