summaryrefslogtreecommitdiff
path: root/nptl
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2006-08-02 16:57:42 +0000
committerJakub Jelinek <jakub@redhat.com>2006-08-02 16:57:42 +0000
commit5d550e87dde9b5a3321c98513099d7da601319ef (patch)
tree2533cbd8626062bb158d72ceda221d35c76605a1 /nptl
parentebe3a574be44dc0d7724945e8cea53b92297593b (diff)
Updated to fedora-glibc-20060802T1650cvs/fedora-glibc-2_4_90-16
Diffstat (limited to 'nptl')
-rw-r--r--nptl/ChangeLog13
-rw-r--r--nptl/Makefile2
-rw-r--r--nptl/allocatestack.c11
-rw-r--r--nptl/sysdeps/unix/sysv/linux/i386/smp.h56
-rw-r--r--nptl/sysdeps/unix/sysv/linux/smp.h30
-rw-r--r--nptl/tst-getpid3.c114
6 files changed, 195 insertions, 31 deletions
diff --git a/nptl/ChangeLog b/nptl/ChangeLog
index 9a95de8bd4..e9011be083 100644
--- a/nptl/ChangeLog
+++ b/nptl/ChangeLog
@@ -1,3 +1,16 @@
+2006-08-01 Ulrich Drepper <drepper@redhat.com>
+
+ * sysdeps/unix/sysv/linux/i386/smp.h: New file. Old Linux-specific
+ file. Don't use sysctl.
+ * sysdeps/unix/sysv/linux/smp.h: Always assume SMP. Archs can
+ overwrite the file if this is likely not true.
+
+2006-07-31 Daniel Jacobowitz <dan@codesourcery.com>
+
+ * allocatestack.c (__reclaim_stacks): Reset the PID on cached stacks.
+ * Makefile (tests): Add tst-getpid3.
+ * tst-getpid3.c: New file.
+
2006-07-30 Roland McGrath <roland@redhat.com>
* Makefile (libpthread-routines): Add ptw-sigsuspend.
diff --git a/nptl/Makefile b/nptl/Makefile
index 1a1c377f48..3a72d3707e 100644
--- a/nptl/Makefile
+++ b/nptl/Makefile
@@ -256,7 +256,7 @@ tests = tst-typesizes \
tst-backtrace1 \
tst-oddstacklimit \
tst-vfork1 tst-vfork2 tst-vfork1x tst-vfork2x \
- tst-getpid1 tst-getpid2 \
+ tst-getpid1 tst-getpid2 tst-getpid3 \
tst-initializers1 $(patsubst %,tst-initializers1-%,c89 gnu89 c99 gnu99)
xtests = tst-setuid1 tst-setuid1-static
diff --git a/nptl/allocatestack.c b/nptl/allocatestack.c
index a3ed1a33d3..4a1cd18481 100644
--- a/nptl/allocatestack.c
+++ b/nptl/allocatestack.c
@@ -742,9 +742,7 @@ __reclaim_stacks (void)
list_t *runp;
list_for_each (runp, &stack_used)
{
- struct pthread *curp;
-
- curp = list_entry (runp, struct pthread, list);
+ struct pthread *curp = list_entry (runp, struct pthread, list);
if (curp != self)
{
/* This marks the stack as free. */
@@ -758,6 +756,13 @@ __reclaim_stacks (void)
}
}
+ /* Reset the PIDs in any cached stacks. */
+ list_for_each (runp, &stack_cache)
+ {
+ struct pthread *curp = list_entry (runp, struct pthread, list);
+ curp->pid = self->pid;
+ }
+
/* Add the stack of all running threads to the cache. */
list_splice (&stack_used, &stack_cache);
diff --git a/nptl/sysdeps/unix/sysv/linux/i386/smp.h b/nptl/sysdeps/unix/sysv/linux/i386/smp.h
new file mode 100644
index 0000000000..f68a0c0758
--- /dev/null
+++ b/nptl/sysdeps/unix/sysv/linux/i386/smp.h
@@ -0,0 +1,56 @@
+/* Determine whether the host has multiple processors. Linux version.
+ Copyright (C) 1996, 2002, 2004, 2006 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 Library General Public License as
+ published by the Free Software Foundation; either version 2 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <string.h>
+#include <sys/utsname.h>
+#include <not-cancel.h>
+
+/* Test whether the machine has more than one processor. This is not the
+ best test but good enough. More complicated tests would require `malloc'
+ which is not available at that time. */
+static inline int
+is_smp_system (void)
+{
+ union
+ {
+ struct utsname uts;
+ char buf[512];
+ } u;
+ char *cp;
+
+ /* Try reading the number using `sysctl' first. */
+ if (uname (&u.uts) == 0)
+ cp = u.uts.version;
+ else
+ {
+ /* This was not successful. Now try reading the /proc filesystem. */
+ int fd = open_not_cancel_2 ("/proc/sys/kernel/version", O_RDONLY);
+ if (__builtin_expect (fd, 0) == -1
+ || read_not_cancel (fd, u.buf, sizeof (u.buf)) <= 0)
+ /* This also didn't work. We give up and say it's a UP machine. */
+ u.buf[0] = '\0';
+
+ close_not_cancel_no_status (fd);
+ cp = u.buf;
+ }
+
+ return strstr (cp, "SMP") != NULL;
+}
diff --git a/nptl/sysdeps/unix/sysv/linux/smp.h b/nptl/sysdeps/unix/sysv/linux/smp.h
index 4f4d358d32..fcc34f7681 100644
--- a/nptl/sysdeps/unix/sysv/linux/smp.h
+++ b/nptl/sysdeps/unix/sysv/linux/smp.h
@@ -1,5 +1,5 @@
/* Determine whether the host has multiple processors. Linux version.
- Copyright (C) 1996, 2002, 2004 Free Software Foundation, Inc.
+ Copyright (C) 1996, 2002, 2004, 2006 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
@@ -17,36 +17,12 @@
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
-#include <errno.h>
-#include <fcntl.h>
-#include <string.h>
-#include <sys/sysctl.h>
-#include <not-cancel.h>
-
/* Test whether the machine has more than one processor. This is not the
best test but good enough. More complicated tests would require `malloc'
which is not available at that time. */
static inline int
is_smp_system (void)
{
- static const int sysctl_args[] = { CTL_KERN, KERN_VERSION };
- char buf[512];
- size_t reslen = sizeof (buf);
-
- /* Try reading the number using `sysctl' first. */
- if (__sysctl ((int *) sysctl_args,
- sizeof (sysctl_args) / sizeof (sysctl_args[0]),
- buf, &reslen, NULL, 0) < 0)
- {
- /* This was not successful. Now try reading the /proc filesystem. */
- int fd = open_not_cancel_2 ("/proc/sys/kernel/version", O_RDONLY);
- if (__builtin_expect (fd, 0) == -1
- || (reslen = read_not_cancel (fd, buf, sizeof (buf))) <= 0)
- /* This also didn't work. We give up and say it's a UP machine. */
- buf[0] = '\0';
-
- close_not_cancel_no_status (fd);
- }
-
- return strstr (buf, "SMP") != NULL;
+ /* Assume all machines are SMP and/or CMT and/or SMT. */
+ return 1;
}
diff --git a/nptl/tst-getpid3.c b/nptl/tst-getpid3.c
new file mode 100644
index 0000000000..f1e77f6b10
--- /dev/null
+++ b/nptl/tst-getpid3.c
@@ -0,0 +1,114 @@
+#include <errno.h>
+#include <pthread.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/wait.h>
+
+
+static pid_t pid;
+
+static void *
+pid_thread (void *arg)
+{
+ if (pid != getpid ())
+ {
+ printf ("pid wrong in thread: should be %d, is %d\n",
+ (int) pid, (int) getpid ());
+ return (void *) 1L;
+ }
+
+ return NULL;
+}
+
+static int
+do_test (void)
+{
+ pid = getpid ();
+
+ pthread_t thr;
+ int ret = pthread_create (&thr, NULL, pid_thread, NULL);
+ if (ret)
+ {
+ printf ("pthread_create failed: %d\n", ret);
+ return 1;
+ }
+
+ void *thr_ret;
+ ret = pthread_join (thr, &thr_ret);
+ if (ret)
+ {
+ printf ("pthread_create failed: %d\n", ret);
+ return 1;
+ }
+ else if (thr_ret)
+ {
+ printf ("thread getpid failed\n");
+ return 1;
+ }
+
+ pid_t child = fork ();
+ if (child == -1)
+ {
+ printf ("fork failed: %m\n");
+ return 1;
+ }
+ else if (child == 0)
+ {
+ if (pid == getpid ())
+ {
+ puts ("pid did not change after fork");
+ exit (1);
+ }
+
+ pid = getpid ();
+ ret = pthread_create (&thr, NULL, pid_thread, NULL);
+ if (ret)
+ {
+ printf ("pthread_create failed: %d\n", ret);
+ return 1;
+ }
+
+ ret = pthread_join (thr, &thr_ret);
+ if (ret)
+ {
+ printf ("pthread_create failed: %d\n", ret);
+ return 1;
+ }
+ else if (thr_ret)
+ {
+ printf ("thread getpid failed\n");
+ return 1;
+ }
+
+ return 0;
+ }
+
+ int status;
+ if (TEMP_FAILURE_RETRY (waitpid (child, &status, 0)) != child)
+ {
+ puts ("waitpid failed");
+ kill (child, SIGKILL);
+ return 1;
+ }
+
+ if (!WIFEXITED (status))
+ {
+ if (WIFSIGNALED (status))
+ printf ("died from signal %s\n", strsignal (WTERMSIG (status)));
+ else
+ puts ("did not terminate correctly");
+ return 1;
+ }
+ if (WEXITSTATUS (status) != 0)
+ {
+ printf ("exit code %d\n", WEXITSTATUS (status));
+ return 1;
+ }
+
+ return 0;
+}
+
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"