aboutsummaryrefslogtreecommitdiff
path: root/nptl
diff options
context:
space:
mode:
Diffstat (limited to 'nptl')
-rw-r--r--nptl/ChangeLog15
-rw-r--r--nptl/allocatestack.c9
-rw-r--r--nptl/descr.h3
-rw-r--r--nptl/init.c10
-rw-r--r--nptl/pthread_cancel.c17
-rw-r--r--nptl/sysdeps/unix/sysv/linux/fork.c3
-rw-r--r--nptl/sysdeps/unix/sysv/linux/pt-raise.c16
-rw-r--r--nptl/sysdeps/unix/sysv/linux/pthread_kill.c15
-rw-r--r--nptl/sysdeps/unix/sysv/linux/raise.c15
9 files changed, 94 insertions, 9 deletions
diff --git a/nptl/ChangeLog b/nptl/ChangeLog
index 9dd2465d5b..4fa3910bac 100644
--- a/nptl/ChangeLog
+++ b/nptl/ChangeLog
@@ -1,3 +1,18 @@
+2003-07-07 Ulrich Drepper <drepper@redhat.com>
+
+ * descr.h (struct pthread): Add pid field.
+ * allocatestack.c (allocate_stack): Initialize pid field in descriptor.
+ (__reclaim_stacks): Likewise.
+ * init.c (sigcancel_handler): If __ASSUME_CORRECT_SI_PID is defined
+ also check for PID of the signal source.
+ (__pthread_initialize_minimal_internal): Also initialize pid field
+ of initial thread's descriptor.
+ * pthread_cancel.c: Use tgkill instead of tkill if possible.
+ * sysdeps/unix/sysv/linux/fork.c: Likewise.
+ * sysdeps/unix/sysv/linux/pt-raise.c: Likewise.
+ * sysdeps/unix/sysv/linux/pthread_kill.c: Likewise.
+ * sysdeps/unix/sysv/linux/raise.c: Likewise.
+
2003-07-05 Ulrich Drepper <drepper@redhat.com>
* sysdeps/pthread/bits/libc-lock.h (__libc_cleanup_push): Renamed.
diff --git a/nptl/allocatestack.c b/nptl/allocatestack.c
index 223f0e445d..e042cf4840 100644
--- a/nptl/allocatestack.c
+++ b/nptl/allocatestack.c
@@ -332,6 +332,9 @@ allocate_stack (const struct pthread_attr *attr, struct pthread **pdp,
pd->header.sysinfo = THREAD_GETMEM (THREAD_SELF, header.sysinfo);
#endif
+ /* The process ID is also the same as that of the caller. */
+ pd->pid = THREAD_GETMEM (THREAD_SELF, pid);
+
/* Allocate the DTV for this thread. */
if (_dl_allocate_tls (TLS_TPADJ (pd)) == NULL)
/* Something went wrong. */
@@ -464,6 +467,9 @@ allocate_stack (const struct pthread_attr *attr, struct pthread **pdp,
pd->header.sysinfo = THREAD_GETMEM (THREAD_SELF, header.sysinfo);
#endif
+ /* The process ID is also the same as that of the caller. */
+ pd->pid = THREAD_GETMEM (THREAD_SELF, pid);
+
/* Allocate the DTV for this thread. */
if (_dl_allocate_tls (TLS_TPADJ (pd)) == NULL)
{
@@ -626,6 +632,9 @@ __reclaim_stacks (void)
/* This marks the stack as free. */
curp->tid = 0;
+ /* The PID field must be initialized for the new process. */
+ curp->pid = self->pid;
+
/* Account for the size of the stack. */
stack_cache_actsize += curp->stackblock_size;
}
diff --git a/nptl/descr.h b/nptl/descr.h
index 26ee42d7c3..fb364b95ca 100644
--- a/nptl/descr.h
+++ b/nptl/descr.h
@@ -177,6 +177,9 @@ struct pthread
/* Two-level array for the thread-specific data. */
struct pthread_key_data *specific[PTHREAD_KEY_1STLEVEL_SIZE];
+ /* Process ID - thread group ID in kernel speak. */
+ pid_t pid;
+
/* True if events must be reported. */
bool report_events;
diff --git a/nptl/init.c b/nptl/init.c
index abc785730a..9c76773504 100644
--- a/nptl/init.c
+++ b/nptl/init.c
@@ -139,10 +139,12 @@ sigcancel_handler (int sig, siginfo_t *si, void *ctx)
correct and might even be a security problem. Try to catch as
many incorrect invocations as possible. */
if (sig != SIGCANCEL
+#ifdef __ASSUME_CORRECT_SI_PID
+ /* Kernels before 2.5.75 stored the thread ID and not the process
+ ID in si_pid so we skip this test. */
+ || si->si_pid != THREAD_GETMEM (THREAD_SELF, pid)
+#endif
|| si->si_code != SI_TKILL)
- /* XXX The Linux kernel currently does not report the correct PID
- in the si->si_pid field. Once this is changed another test
- will be added. */
return;
struct pthread *self = THREAD_SELF;
@@ -202,7 +204,7 @@ __pthread_initialize_minimal_internal (void)
/* Minimal initialization of the thread descriptor. */
struct pthread *pd = THREAD_SELF;
INTERNAL_SYSCALL_DECL (err);
- pd->tid = INTERNAL_SYSCALL (set_tid_address, err, 1, &pd->tid);
+ pd->pid = pd->tid = INTERNAL_SYSCALL (set_tid_address, err, 1, &pd->tid);
THREAD_SETMEM (pd, specific[0], &pd->specific_1stblock[0]);
THREAD_SETMEM (pd, user_stack, true);
if (LLL_LOCK_INITIALIZER != 0)
diff --git a/nptl/pthread_cancel.c b/nptl/pthread_cancel.c
index 43b65b6c02..9e3dfda6b3 100644
--- a/nptl/pthread_cancel.c
+++ b/nptl/pthread_cancel.c
@@ -22,6 +22,7 @@
#include "pthreadP.h"
#include "atomic.h"
#include <sysdep.h>
+#include <kernel-features.h>
int
@@ -61,7 +62,21 @@ pthread_cancel (th)
thread as canceled. */
INTERNAL_SYSCALL_DECL (err);
- int val = INTERNAL_SYSCALL (tkill, err, 2, pd->tid, SIGCANCEL);
+ int val;
+#if __ASSUME_TGKILL
+ val = INTERNAL_SYSCALL (tgkill, err, 3,
+ THREAD_GETMEM (THREAD_SELF, pid), pd->tid,
+ SIGCANCEL);
+#else
+# ifdef __NR_tgkill
+ val = INTERNAL_SYSCALL (tgkill, err, 3,
+ THREAD_GETMEM (THREAD_SELF, pid), pd->tid,
+ SIGCANCEL);
+ if (INTERNAL_SYSCALL_ERROR_P (val, err)
+ && INTERNAL_SYSCALL_ERRNO (val, err) == ENOSYS)
+# endif
+ val = INTERNAL_SYSCALL (tkill, err, 2, pd->tid, SIGCANCEL);
+#endif
if (INTERNAL_SYSCALL_ERROR_P (val, err))
result = INTERNAL_SYSCALL_ERRNO (val, err);
diff --git a/nptl/sysdeps/unix/sysv/linux/fork.c b/nptl/sysdeps/unix/sysv/linux/fork.c
index 8bca6b4ab3..43e1b43e2b 100644
--- a/nptl/sysdeps/unix/sysv/linux/fork.c
+++ b/nptl/sysdeps/unix/sysv/linux/fork.c
@@ -134,6 +134,9 @@ __libc_fork (void)
if (__fork_generation_pointer != NULL)
*__fork_generation_pointer += 4;
+ /* Adjust the PID field for the new process. */
+ self->pid = self->tid;
+
#if HP_TIMING_AVAIL
/* The CPU clock of the thread and process have to be set to zero. */
hp_timing_t now;
diff --git a/nptl/sysdeps/unix/sysv/linux/pt-raise.c b/nptl/sysdeps/unix/sysv/linux/pt-raise.c
index 0c68960e5d..2efd7616bf 100644
--- a/nptl/sysdeps/unix/sysv/linux/pt-raise.c
+++ b/nptl/sysdeps/unix/sysv/linux/pt-raise.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
@@ -21,11 +21,23 @@
#include <signal.h>
#include <sysdep.h>
#include <tls.h>
+#include <kernel-features.h>
int
raise (sig)
int sig;
{
- return INLINE_SYSCALL (tkill, 2, THREAD_SELF->tid, sig);
+#if __ASSUME_TGKILL
+ return INLINE_SYSCALL (tgkill, 3, THREAD_GETMEM (THREAD_SELF, pid),
+ THREAD_GETMEM (THREAD_SELF, tid), sig);
+#else
+# ifdef __NR_tgkill
+ int res = INLINE_SYSCALL (tgkill, 3, THREAD_GETMEM (THREAD_SELF, pid),
+ THREAD_GETMEM (THREAD_SELF, tid), sig);
+ if (res != -1 || errno != ENOSYS)
+ return res;
+# endif
+ return INLINE_SYSCALL (tkill, 2, THREAD_GETMEM (THREAD_SELF, tid), sig);
+#endif
}
diff --git a/nptl/sysdeps/unix/sysv/linux/pthread_kill.c b/nptl/sysdeps/unix/sysv/linux/pthread_kill.c
index 8da195aa0a..6967acd92b 100644
--- a/nptl/sysdeps/unix/sysv/linux/pthread_kill.c
+++ b/nptl/sysdeps/unix/sysv/linux/pthread_kill.c
@@ -22,6 +22,7 @@
#include <pthreadP.h>
#include <tls.h>
#include <sysdep.h>
+#include <kernel-features.h>
int
@@ -43,7 +44,19 @@ __pthread_kill (threadid, signo)
/* We have a special syscall to do the work. */
INTERNAL_SYSCALL_DECL (err);
- int val = INTERNAL_SYSCALL (tkill, err, 2, pd->tid, signo);
+ int val;
+#if __ASSUME_TGKILL
+ val = INTERNAL_SYSCALL (tgkill, err, 3, THREAD_GETMEM (THREAD_SELF, pid),
+ pd->tid, signo);
+#else
+# ifdef __NR_tgkill
+ val = INTERNAL_SYSCALL (tgkill, err, 3, THREAD_GETMEM (THREAD_SELF, pid),
+ pd->tid, signo);
+ if (INTERNAL_SYSCALL_ERROR_P (val, err)
+ && INTERNAL_SYSCALL_ERRNO (val, err) == ENOSYS)
+# endif
+ val = INTERNAL_SYSCALL (tkill, err, 2, pd->tid, signo);
+#endif
return (INTERNAL_SYSCALL_ERROR_P (val, err)
? INTERNAL_SYSCALL_ERRNO (val, err) : 0);
diff --git a/nptl/sysdeps/unix/sysv/linux/raise.c b/nptl/sysdeps/unix/sysv/linux/raise.c
index 24a00b1e4d..25d3ed8afd 100644
--- a/nptl/sysdeps/unix/sysv/linux/raise.c
+++ b/nptl/sysdeps/unix/sysv/linux/raise.c
@@ -21,6 +21,7 @@
#include <signal.h>
#include <sysdep.h>
#include <nptl/pthreadP.h>
+#include <kernel-features.h>
int
@@ -28,7 +29,7 @@ raise (sig)
int sig;
{
struct pthread *pd = THREAD_SELF;
- pid_t selftid = pd->tid;
+ pid_t selftid = THREAD_GETMEM (pd, tid);
if (selftid == 0)
{
/* This system call is not supposed to fail. */
@@ -39,9 +40,21 @@ raise (sig)
selftid = INLINE_SYSCALL (gettid, 0);
#endif
THREAD_SETMEM (pd, tid, selftid);
+
+ /* In this case the TID and PID are the same. */
+ THREAD_SETMEM (pd, pid, selftid);
}
+#if __ASSUME_TGKILL
+ return INLINE_SYSCALL (tgkill, 3, THREAD_GETMEM (pd, pid), selftid, sig);
+#else
+# ifdef __NR_tgkill
+ int res = INLINE_SYSCALL (tgkill, 3, THREAD_GETMEM (pd, pid), selftid, sig);
+ if (res != -1 || errno != ENOSYS)
+ return res;
+# endif
return INLINE_SYSCALL (tkill, 2, selftid, sig);
+#endif
}
libc_hidden_def (raise)
weak_alias (raise, gsignal)