Update.
authorUlrich Drepper <drepper@redhat.com>
Sat, 27 Dec 2003 07:38:25 +0000 (07:38 +0000)
committerUlrich Drepper <drepper@redhat.com>
Sat, 27 Dec 2003 07:38:25 +0000 (07:38 +0000)
2003-12-23  Jakub Jelinek  <jakub@redhat.com>

* sysdeps/unix/sysv/linux/raise.c (raise): Protect pid = selftid
setting with __ASSUME_TGKILL || defined __NR_tgkill.
If pid is 0, set it to selftid.
* sysdeps/unix/sysv/linux/getpid.c (really_getpid): Make inline.
Don't set self->pid but self->tid.  If self->pid == 0 and self->tid
!= 0, return self->tid without doing a syscall.
* descr.h (struct pthread): Move pid field after tid.

* Makefile (tests): Add tst-raise1.
* tst-raise1.c: New file.

nptl/ChangeLog
nptl/Makefile
nptl/descr.h
nptl/sysdeps/unix/sysv/linux/getpid.c
nptl/sysdeps/unix/sysv/linux/raise.c
nptl/tst-raise1.c [new file with mode: 0644]

index e0e2bee..1fda8e4 100644 (file)
@@ -1,3 +1,16 @@
+2003-12-23  Jakub Jelinek  <jakub@redhat.com>
+
+       * sysdeps/unix/sysv/linux/raise.c (raise): Protect pid = selftid
+       setting with __ASSUME_TGKILL || defined __NR_tgkill.
+       If pid is 0, set it to selftid.
+       * sysdeps/unix/sysv/linux/getpid.c (really_getpid): Make inline.
+       Don't set self->pid but self->tid.  If self->pid == 0 and self->tid
+       != 0, return self->tid without doing a syscall.
+       * descr.h (struct pthread): Move pid field after tid.
+
+       * Makefile (tests): Add tst-raise1.
+       * tst-raise1.c: New file.
+
 2003-12-23  Roland McGrath  <roland@redhat.com>
 
        * tst-oddstacklimit.c: New file.
index 4cacbd6..08ed148 100644 (file)
@@ -205,6 +205,7 @@ tests = tst-attr1 tst-attr2 tst-attr3 \
        tst-align \
        tst-basic1 tst-basic2 tst-basic3 tst-basic4 tst-basic5 tst-basic6 \
        tst-kill1 tst-kill2 tst-kill3 tst-kill4 tst-kill5 tst-kill6 \
+       tst-raise1 \
        tst-join1 tst-join2 tst-join3 tst-join4 tst-join5 \
        tst-detach1 \
        tst-eintr1 tst-eintr2 tst-eintr3 tst-eintr4 tst-eintr5 \
index 6c7f231..a6e35ba 100644 (file)
@@ -121,6 +121,9 @@ struct pthread
      therefore stack) used' flag.  */
   pid_t tid;
 
+  /* Process ID - thread group ID in kernel speak.  */
+  pid_t pid;
+
   /* List of cleanup buffers.  */
   struct _pthread_cleanup_buffer *cleanup;
 
@@ -178,9 +181,6 @@ 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;
 
index 7efe3f2..1c3532b 100644 (file)
 
 
 #ifndef NOT_IN_libc
-static pid_t really_getpid (pid_t oldval);
-#endif
-
+static inline __attribute__((always_inline)) pid_t really_getpid (pid_t oldval);
 
-pid_t
-__getpid (void)
+static inline __attribute__((always_inline)) pid_t
+really_getpid (pid_t oldval)
 {
-#ifndef NOT_IN_libc
-  pid_t result = THREAD_GETMEM (THREAD_SELF, pid);
-  if (__builtin_expect (result <= 0, 0))
-    result = really_getpid (result);
+  pid_t selftid;
+  if (__builtin_expect (oldval == 0
+                       && ((selftid = THREAD_GETMEM (THREAD_SELF, tid))
+                           != 0), 1))
+    return selftid;
+
+  INTERNAL_SYSCALL_DECL (err);
+  pid_t result = INTERNAL_SYSCALL (getpid, err, 0);
+
+  /* We do not set the PID field in the TID here since we might be
+     called from a signal handler while the thread executes fork.  */
+  if (oldval == 0)
+    THREAD_SETMEM (THREAD_SELF, tid, result);
   return result;
 }
+#endif
 
-static pid_t
-really_getpid (pid_t oldval)
+pid_t
+__getpid (void)
 {
-#endif
+#ifdef NOT_IN_libc
   INTERNAL_SYSCALL_DECL (err);
   pid_t result = INTERNAL_SYSCALL (getpid, err, 0);
-#ifndef NOT_IN_libc
-  if (oldval == 0)
-    THREAD_SETMEM (THREAD_SELF, pid, result);
+#else
+  pid_t result = THREAD_GETMEM (THREAD_SELF, pid);
+  if (__builtin_expect (result <= 0, 0))
+    result = really_getpid (result);
 #endif
   return result;
 }
+
 libc_hidden_def (__getpid)
 weak_alias (__getpid, getpid)
 libc_hidden_def (getpid)
index 268ba87..ac54fa2 100644 (file)
@@ -44,17 +44,19 @@ raise (sig)
 #endif
       THREAD_SETMEM (pd, tid, selftid);
 
+#if __ASSUME_TGKILL || defined __NR_tgkill
       /* We do not set the PID field in the TID here since we might be
         called from a signal handler while the thread executes fork.  */
       pid = selftid;
+#endif
     }
 #if __ASSUME_TGKILL || defined __NR_tgkill
   else
     /* raise is an async-safe function.  It could be called while the
        fork function temporarily invalidated the PID field.  Adjust for
        that.  */
-    if (__builtin_expect (pid < 0, 0))
-      pid = -pid;
+    if (__builtin_expect (pid <= 0, 0))
+      pid = pid == 0 ? selftid : -pid;
 #endif
 
 #if __ASSUME_TGKILL
diff --git a/nptl/tst-raise1.c b/nptl/tst-raise1.c
new file mode 100644 (file)
index 0000000..9c291e6
--- /dev/null
@@ -0,0 +1,42 @@
+#include <errno.h>
+#include <error.h>
+#include <signal.h>
+#include <stdlib.h>
+
+volatile int count;
+
+void
+sh (int sig)
+{
+  ++count;
+}
+
+int
+main (void)
+{
+  struct sigaction sa;
+  sa.sa_handler = sh;
+  sigemptyset (&sa.sa_mask);
+  sa.sa_flags = 0;
+  if (sigaction (SIGUSR1, &sa, NULL) < 0)
+    {
+      printf ("sigaction failed: %m\n");
+      exit (1);
+    }
+  if (raise (SIGUSR1) < 0)
+    {
+      printf ("first raise failed: %m\n");
+      exit (1);
+    }
+  if (raise (SIGUSR1) < 0)
+    {
+      printf ("second raise failed: %m\n");
+      exit (1);
+    }
+  if (count != 2)
+    {
+      printf ("signal handler not called 2 times\n");
+      exit (1);
+    }
+  exit (0);
+}