about summary refs log tree commit diff
path: root/nptl
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>2003-01-28 10:42:28 +0000
committerUlrich Drepper <drepper@redhat.com>2003-01-28 10:42:28 +0000
commite6ebd2e4db59da6c1726ecfa3516f1f1b3048442 (patch)
treedfa3797737a8e4dc76ed38e52cf7baa27e936003 /nptl
parent772e3426a7b6f5200cb1029d41308b8b666cdbab (diff)
downloadglibc-e6ebd2e4db59da6c1726ecfa3516f1f1b3048442.tar.gz
glibc-e6ebd2e4db59da6c1726ecfa3516f1f1b3048442.tar.xz
glibc-e6ebd2e4db59da6c1726ecfa3516f1f1b3048442.zip
Update.
2003-01-27  Martin Schwidefsky  <schwidefsky@de.ibm.com>

	* elf/elf.h: Add new s390 relocs.
	* elf/tls-macros.h: Add s390 versions.
	* sysdeps/s390/Versions [GLIBC_2.3] (ld): Export __tls_get_offset.
	* sysdeps/s390/dl-tls.h: New file.
	* sysdeps/s390/libc-tls.c: New file.
	* sysdeps/s390/s390-32/dl-machine.h (elf_machine_type_class): Add TLS
	relocs for class PLT.
	(elf_machine_rela): Handle TLS relocs.
	* sysdeps/s390/s390-64/dl-machine.h: Likewise.
	* sysdeps/s390/s390-32/elf/configure.in: Add TLS check.
	* sysdeps/s390/s390-64/elf/configure.in: Likewise.
	* sysdeps/unix/sysv/linux/s390/s390-32/clone.S: Add support for
	CLONE_CHILD_*TID flags.
	* sysdeps/unix/sysv/linux/s390/s390-64/clone.S: Likewise.
	* sysdeps/unix/sysv/linux/s390/s390-64/mmap.S: Use branch with 32
	bit offset.
	* sysdeps/unix/sysv/linux/s390/s390-64/socket.S: Likewise.
	* sysdeps/unix/sysv/linux/s390/s390-64/syscall.S: Likewise.
	* sysdeps/unix/sysv/linux/s390/s390-32/sysdep.S (__syscall_error):
	Support USE___THREAD. Define RTLD_PRIVATE_ERRNO variant.
	* sysdeps/unix/sysv/linux/s390/s390-64/sysdep.S (__syscall_error):
	Likewise.
	* sysdeps/unix/sysv/linux/s390/s390-32/sysdep.h:
	(SYSCALL_ERROR_LABEL): Move define next to SYSCALL_ERROR_HANDLER.
	(SYSCALL_ERROR_HANDLER): Add USE___THREAD and RTLD_PRIVATE_ERRNO
	variants.
	* sysdeps/unix/sysv/linux/s390/s390-64/sysdep.h:
	(SYSCALL_ERROR_LABEL): Move define next to SYSCALL_ERROR_HANDLER. Use
	direct branch to syscall_error for !PIC and PIC && !_LIBC_REENTRANT.
	(SYSCALL_ERROR_HANDLER): Add USE___THREAD and RTLD_PRIVATE_ERRNO
	variants.
Diffstat (limited to 'nptl')
-rw-r--r--nptl/ChangeLog7
-rw-r--r--nptl/sysdeps/pthread/createthread.c145
-rw-r--r--nptl/sysdeps/unix/sysv/linux/i386/createthread.c170
3 files changed, 183 insertions, 139 deletions
diff --git a/nptl/ChangeLog b/nptl/ChangeLog
index 9f5080b8aa..1f293f505a 100644
--- a/nptl/ChangeLog
+++ b/nptl/ChangeLog
@@ -1,3 +1,10 @@
+2003-01-28  Ulrich Drepper  <drepper@redhat.com>
+
+	* sysdeps/unix/sysv/linux/i386/createthread.c: Define
+	PREPARE_CREATE and TLS_VALUE with x86-specific bits.  All the rest
+	of the code is moved to ...
+	* sysdeps/pthread/createthread.c: ...here.  New file.
+
 2003-01-27  Ulrich Drepper  <drepper@redhat.com>
 
 	* sysdeps/unix/sysv/linux/i386/i486/lowlevelsem.S
diff --git a/nptl/sysdeps/pthread/createthread.c b/nptl/sysdeps/pthread/createthread.c
new file mode 100644
index 0000000000..b6898368ef
--- /dev/null
+++ b/nptl/sysdeps/pthread/createthread.c
@@ -0,0 +1,145 @@
+/* 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.
+
+   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, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <sched.h>
+#include <setjmp.h>
+#include <signal.h>
+#include <stdlib.h>
+#include <atomic.h>
+#include <ldsodefs.h>
+#include <tls.h>
+
+
+#define CLONE_SIGNAL    	(CLONE_SIGHAND | CLONE_THREAD)
+
+/* Unless otherwise specified, the thread "register" is going to be
+   initialized with a pointer to the TCB.  */
+#ifndef TLS_VALUE
+# define TLS_VALUE pd
+#endif
+
+
+static int
+create_thread (struct pthread *pd, STACK_VARIABLES_PARMS)
+{
+#ifdef PREPARE_CREATE
+  PREPARE_CREATE;
+#endif
+
+  assert (pd->header.data.tcb != NULL);
+
+
+  if (__builtin_expect (THREAD_GETMEM (THREAD_SELF, report_events), 0))
+    {
+      /* The parent thread is supposed to report events.  Check whether
+	 the TD_CREATE event is needed, too.  */
+      const int _idx = __td_eventword (TD_CREATE);
+      const uint32_t _mask = __td_eventmask (TD_CREATE);
+
+      if ((_mask & (__nptl_threads_events.event_bits[_idx]
+		    | pd->eventbuf.eventmask.event_bits[_idx])) != 0)
+	{
+	  /* We have to report the new thread.  Make sure the thread
+	     does not run far by forcing it to get a lock.  We lock it
+	     here too so that the new thread cannot continue until we
+	     tell it to.  */
+	  lll_lock (pd->lock);
+
+	  /* Create the thread.  */
+	  if (__clone (start_thread_debug, STACK_VARIABLES_ARGS,
+		       CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGNAL |
+		       CLONE_SETTLS | CLONE_PARENT_SETTID |
+		       CLONE_CHILD_CLEARTID | CLONE_DETACHED | 0,
+		       pd, &pd->tid, TLS_VALUE, &pd->tid) == -1)
+	    /* Failed.  */
+	    return errno;
+
+	  /* We now have for sure more than one thread.  */
+	  pd->header.data.multiple_threads = 1;
+
+	  /* Now fill in the information about the new thread in
+	     the newly created thread's data structure.  We cannot let
+	     the new thread do this since we don't know whether it was
+	     already scheduled when we send the event.  */
+	  pd->eventbuf.eventnum = TD_CREATE;
+	  pd->eventbuf.eventdata = pd;
+
+	  /* Enqueue the descriptor.  */
+	  do
+	    pd->nextevent = __nptl_last_event;
+	  while (atomic_compare_and_exchange_acq (&__nptl_last_event, pd,
+						  pd->nextevent) != 0);
+
+	  /* Now call the function which signals the event.  */
+	  __nptl_create_event ();
+
+	  /* And finally restart the new thread.  */
+	  lll_unlock (pd->lock);
+
+	  return 0;
+	}
+    }
+
+#ifdef NEED_DL_SYSINFO
+  assert (THREAD_GETMEM (THREAD_SELF, header.data.sysinfo)
+	  == pd->header.data.sysinfo);
+#endif
+
+  /* We rely heavily on various flags the CLONE function understands:
+
+     CLONE_VM, CLONE_FS, CLONE_FILES
+	These flags select semantics with shared address space and
+	file descriptors according to what POSIX requires.
+
+     CLONE_SIGNAL
+	This flag selects the POSIX signal semantics.
+
+     CLONE_SETTLS
+	The sixth parameter to CLONE determines the TLS area for the
+	new thread.
+
+     CLONE_PARENT_SETTID
+	The kernels writes the thread ID of the newly created thread
+	into the location pointed to by the fifth parameters to CLONE.
+
+	Note that it would be semantically equivalent to use
+	CLONE_CHILD_SETTID but it is be more expensive in the kernel.
+
+     CLONE_CHILD_CLEARTID
+	The kernels clears the thread ID of a thread that has called
+	sys_exit() - using the same parameter as CLONE_SETTID.
+
+     CLONE_DETACHED
+	No signal is generated if the thread exists and it is
+	automatically reaped.
+
+     The termination signal is chosen to be zero which means no signal
+     is sent.  */
+  if (__clone (start_thread, STACK_VARIABLES_ARGS,
+	       CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGNAL |
+	       CLONE_SETTLS | CLONE_PARENT_SETTID | CLONE_CHILD_CLEARTID |
+	       CLONE_DETACHED | 0, pd, &pd->tid, TLS_VALUE, &pd->tid) == -1)
+    /* Failed.  */
+    return errno;
+
+  /* We now have for sure more than one thread.  */
+  THREAD_SETMEM (THREAD_SELF, header.data.multiple_threads, 1);
+
+  return 0;
+}
diff --git a/nptl/sysdeps/unix/sysv/linux/i386/createthread.c b/nptl/sysdeps/unix/sysv/linux/i386/createthread.c
index def163350f..37e3d94996 100644
--- a/nptl/sysdeps/unix/sysv/linux/i386/createthread.c
+++ b/nptl/sysdeps/unix/sysv/linux/i386/createthread.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.
 
@@ -17,141 +17,33 @@
    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
    02111-1307 USA.  */
 
-#include <sched.h>
-#include <setjmp.h>
-#include <signal.h>
-#include <stdlib.h>
-#include <atomic.h>
-#include <ldsodefs.h>
-#include <tls.h>
-
-
-#define CLONE_SIGNAL    	(CLONE_SIGHAND | CLONE_THREAD)
-
-
-static int
-create_thread (struct pthread *pd, STACK_VARIABLES_PARMS)
-{
-  union user_desc_init desc;
-
-  /* Describe the thread-local storage segment.  */
-
-  /* The 'entry_number' field.  The first three bits of the segment
-     register value select the GDT, ignore them.  We get the index
-     from the value of the %gs register in the current thread.  */
-  desc.vals[0] = TLS_GET_GS () >> 3;
-  /* The 'base_addr' field.  Pointer to the TCB.  */
-  desc.vals[1] = (unsigned long int) pd;
-  /* The 'limit' field.  We use 4GB which is 0xfffff pages.  */
-  desc.vals[2] = 0xfffff;
-  /* Collapsed value of the bitfield:
-       .seg_32bit = 1
-       .contents = 0
-       .read_exec_only = 0
-       .limit_in_pages = 1
-       .seg_not_present = 0
-       .useable = 1 */
-  desc.vals[3] = 0x51;
-
-
-  assert (pd->header.data.tcb != NULL);
-
-
-  if (__builtin_expect (THREAD_GETMEM (THREAD_SELF, report_events), 0))
-    {
-      /* The parent thread is supposed to report events.  Check whether
-	 the TD_CREATE event is needed, too.  */
-      const int _idx = __td_eventword (TD_CREATE);
-      const uint32_t _mask = __td_eventmask (TD_CREATE);
-
-      if ((_mask & (__nptl_threads_events.event_bits[_idx]
-		    | pd->eventbuf.eventmask.event_bits[_idx])) != 0)
-	{
-	  /* We have to report the new thread.  Make sure the thread
-	     does not run far by forcing it to get a lock.  We lock it
-	     here too so that the new thread cannot continue until we
-	     tell it to.  */
-	  lll_lock (pd->lock);
-
-	  /* Create the thread.  */
-	  if (__clone (start_thread_debug, STACK_VARIABLES_ARGS,
-		       CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGNAL |
-		       CLONE_SETTLS | CLONE_PARENT_SETTID |
-		       CLONE_CHILD_CLEARTID | CLONE_DETACHED | 0,
-		       pd, &pd->tid, &desc.desc, &pd->tid) == -1)
-	    /* Failed.  */
-	    return errno;
-
-	  /* We now have for sure more than one thread.  */
-	  pd->header.data.multiple_threads = 1;
-
-	  /* Now fill in the information about the new thread in
-	     the newly created thread's data structure.  We cannot let
-	     the new thread do this since we don't know whether it was
-	     already scheduled when we send the event.  */
-	  pd->eventbuf.eventnum = TD_CREATE;
-	  pd->eventbuf.eventdata = pd;
-
-	  /* Enqueue the descriptor.  */
-	  do
-	    pd->nextevent = __nptl_last_event;
-	  while (atomic_compare_and_exchange_acq (&__nptl_last_event, pd,
-						  pd->nextevent) != 0);
-
-	  /* Now call the function which signals the event.  */
-	  __nptl_create_event ();
-
-	  /* And finally restart the new thread.  */
-	  lll_unlock (pd->lock);
-
-	  return 0;
-	}
-    }
-
-#ifdef NEED_DL_SYSINFO
-  assert (THREAD_GETMEM (THREAD_SELF, header.data.sysinfo)
-	  == pd->header.data.sysinfo);
-#endif
-
-  /* We rely heavily on various flags the CLONE function understands:
-
-     CLONE_VM, CLONE_FS, CLONE_FILES
-	These flags select semantics with shared address space and
-	file descriptors according to what POSIX requires.
-
-     CLONE_SIGNAL
-	This flag selects the POSIX signal semantics.
-
-     CLONE_SETTLS
-	The sixth parameter to CLONE determines the TLS area for the
-	new thread.
-
-     CLONE_PARENT_SETTID
-	The kernels writes the thread ID of the newly created thread
-	into the location pointed to by the fifth parameters to CLONE.
-
-	Note that it would be semantically equivalent to use
-	CLONE_CHILD_SETTID but it is be more expensive in the kernel.
-
-     CLONE_CHILD_CLEARTID
-	The kernels clears the thread ID of a thread that has called
-	sys_exit() - using the same parameter as CLONE_SETTID.
-
-     CLONE_DETACHED
-	No signal is generated if the thread exists and it is
-	automatically reaped.
-
-     The termination signal is chosen to be zero which means no signal
-     is sent.  */
-  if (__clone (start_thread, STACK_VARIABLES_ARGS,
-	       CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGNAL |
-	       CLONE_SETTLS | CLONE_PARENT_SETTID | CLONE_CHILD_CLEARTID |
-	       CLONE_DETACHED | 0, pd, &pd->tid, &desc.desc, &pd->tid) == -1)
-    /* Failed.  */
-    return errno;
-
-  /* We now have for sure more than one thread.  */
-  THREAD_SETMEM (THREAD_SELF, header.data.multiple_threads, 1);
-
-  return 0;
-}
+/* The "thread register" gets initialized from a segment descriptor.
+   Initialize such a descriptor first.  */
+#define PREPARE_CREATE \
+  union user_desc_init desc;						      \
+									      \
+  /* Describe the thread-local storage segment.  */			      \
+									      \
+  /* The 'entry_number' field.  The first three bits of the segment	      \
+     register value select the GDT, ignore them.  We get the index	      \
+     from the value of the %gs register in the current thread.  */	      \
+  desc.vals[0] = TLS_GET_GS () >> 3;					      \
+  /* The 'base_addr' field.  Pointer to the TCB.  */			      \
+  desc.vals[1] = (unsigned long int) pd;				      \
+  /* The 'limit' field.  We use 4GB which is 0xfffff pages.  */		      \
+  desc.vals[2] = 0xfffff;						      \
+  /* Collapsed value of the bitfield:					      \
+       .seg_32bit = 1							      \
+       .contents = 0							      \
+       .read_exec_only = 0						      \
+       .limit_in_pages = 1						      \
+       .seg_not_present = 0						      \
+       .useable = 1 */							      \
+  desc.vals[3] = 0x51
+
+/* Value passed to 'clone' for initialization of the thread register.  */
+#define TLS_VALUE &desc.desc
+
+
+/* Get the real implementation.  */
+#include <nptl/sysdeps/pthread/createthread.c>