This is the mail archive of the libc-hacker@sourceware.org mailing list for the glibc project.

Note that libc-hacker is a closed list. You may look at the archives of this list, but subscription and posting are not open.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Speed up pthread_cleanup_{push,pop} inside of libpthread


Hi!

While looking at pthread_cond_*wait, I noticed it was calling
__pthread_cleanup_push/pop, which is the old (and slower) way of registering
a cleanup handler.  Except for pthread_once which really needs to use
that way (because it is calling a callback function, which might not have
unwind info - see e.g. tst-once3).  Tested on ppc32.

TODO things I have noticed, but didn't change:
i386 pthread_once.S shouldn't use sigsetjmp etc., but __pthread_cleanup_{push,pop}
x86_64 pthread_cond_*wait.S shouldn't use __pthread_cleanup_* but
     attribute cleanup handler
x86_64 lll_timedwait_tid should have unwind info

2007-01-16  Jakub Jelinek  <jakub@redhat.com>

	* Makefile (CFLAGS-lowlevellock.c): Compile with -fa-u-t.
	* pthreadP.h (pthread_cleanup_push, pthread_cleanup_pop): Don't
	redefine if _EXCEPTIONS is defined.
	* pthread_cond_wait.c (__pthread_cond_wait): Use
	pthread_cleanup_{push,pop} instead of __pthread_cleanup_{push,pop}.
	* pthread_cond_timedwait.c (__pthread_cond_timedwait): Likewise.
	* sysdeps/unix/sysv/linux/alpha/pthread_once.c (__pthread_once):
	Use explicitly __pthread_cond_{push,pop}.
	* sysdeps/unix/sysv/linux/s390/pthread_once.c (__pthread_once):
	Likewise.
	* sysdeps/unix/sysv/linux/powerpc/pthread_once.c (__pthread_once):
	Likewise.
	* sysdeps/unix/sysv/linux/sparc/pthread_once.c (__pthread_once):
	Likewise.
	* sysdeps/unix/sysv/linux/ia64/pthread_once.c (__pthread_once):
	Likewise.

--- libc/nptl/Makefile.jj	2006-09-08 13:57:49.000000000 +0200
+++ libc/nptl/Makefile	2007-01-16 15:56:05.000000000 +0100
@@ -175,6 +175,7 @@ CFLAGS-pthread_cond_wait.c = -fexception
 CFLAGS-pthread_cond_timedwait.c = -fexceptions -fasynchronous-unwind-tables
 CFLAGS-sem_wait.c = -fexceptions -fasynchronous-unwind-tables
 CFLAGS-sem_timedwait.c = -fexceptions -fasynchronous-unwind-tables
+CFLAGS-lowlevellock.c = -fasynchronous-unwind-tables
 
 # These are the function wrappers we have to duplicate here.
 CFLAGS-fcntl.c = -fexceptions -fasynchronous-unwind-tables
--- libc/nptl/sysdeps/unix/sysv/linux/alpha/pthread_once.c.jj	2004-09-08 18:56:46.000000000 +0200
+++ libc/nptl/sysdeps/unix/sysv/linux/alpha/pthread_once.c	2007-01-16 15:23:56.000000000 +0100
@@ -1,4 +1,4 @@
-/* Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+/* Copyright (C) 2003, 2004, 2007 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
@@ -77,12 +77,16 @@ __pthread_once (pthread_once_t *once_con
 
   /* This thread is the first here.  Do the initialization.
      Register a cleanup handler so that in case the thread gets
-     interrupted the initialization can be restarted.  */
-  pthread_cleanup_push (clear_once_control, once_control);
+     interrupted the initialization can be restarted.
+     This uses __pthread_cleanup_{push,pop} explicitly, because
+     init_routine or something it calls might not have unwind
+     information.  */
+  struct _pthread_cleanup_buffer buffer;
+  __pthread_cleanup_push (&buffer, clear_once_control, once_control);
 
   init_routine ();
 
-  pthread_cleanup_pop (0);
+  __pthread_cleanup_pop (&buffer, 0);
 
   /* Add one to *once_control to take the bottom 2 bits from 01 to 10.  */
   atomic_increment (once_control);
--- libc/nptl/sysdeps/unix/sysv/linux/s390/pthread_once.c.jj	2003-02-05 10:29:49.000000000 +0100
+++ libc/nptl/sysdeps/unix/sysv/linux/s390/pthread_once.c	2007-01-16 15:25:56.000000000 +0100
@@ -1,4 +1,4 @@
-/* Copyright (C) 2003 Free Software Foundation, Inc.
+/* Copyright (C) 2003, 2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Martin Schwidefsky <schwidefsky@de.ibm.com>, 2003.
 
@@ -83,12 +83,16 @@ __pthread_once (once_control, init_routi
 
       /* This thread is the first here.  Do the initialization.
 	 Register a cleanup handler so that in case the thread gets
-	 interrupted the initialization can be restarted.  */
-      pthread_cleanup_push (clear_once_control, once_control);
+	 interrupted the initialization can be restarted.
+	 This uses __pthread_cleanup_{push,pop} explicitly, because
+	 init_routine or something it calls might not have unwind  
+	 information.  */
+      struct _pthread_cleanup_buffer buffer;
+      __pthread_cleanup_push (&buffer, clear_once_control, once_control);
 
       init_routine ();
 
-      pthread_cleanup_pop (0);
+      __pthread_cleanup_pop (&buffer, 0);
 
 
       /* Add one to *once_control.  */
--- libc/nptl/sysdeps/unix/sysv/linux/powerpc/pthread_once.c.jj	2004-09-08 18:56:46.000000000 +0200
+++ libc/nptl/sysdeps/unix/sysv/linux/powerpc/pthread_once.c	2007-01-16 15:22:45.000000000 +0100
@@ -1,4 +1,4 @@
-/* Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+/* Copyright (C) 2003, 2004, 2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Paul Mackerras <paulus@au.ibm.com>, 2003.
 
@@ -80,12 +80,16 @@ __pthread_once (pthread_once_t *once_con
 
   /* This thread is the first here.  Do the initialization.
      Register a cleanup handler so that in case the thread gets
-     interrupted the initialization can be restarted.  */
-  pthread_cleanup_push (clear_once_control, once_control);
+     interrupted the initialization can be restarted.
+     This uses __pthread_cleanup_{push,pop} explicitly, because
+     init_routine or something it calls might not have unwind
+     information.  */
+  struct _pthread_cleanup_buffer buffer;
+  __pthread_cleanup_push (&buffer, clear_once_control, once_control);
 
   init_routine ();
 
-  pthread_cleanup_pop (0);
+  __pthread_cleanup_pop (&buffer, 0);
 
 
   /* Add one to *once_control to take the bottom 2 bits from 01 to 10.  */
--- libc/nptl/sysdeps/unix/sysv/linux/sparc/pthread_once.c.jj	2004-09-08 18:56:46.000000000 +0200
+++ libc/nptl/sysdeps/unix/sysv/linux/sparc/pthread_once.c	2007-01-16 15:27:19.000000000 +0100
@@ -1,4 +1,4 @@
-/* Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+/* Copyright (C) 2003, 2004, 2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Jakub Jelinek <jakub@redhat.com>, 2003.
 
@@ -72,12 +72,16 @@ __pthread_once (once_control, init_routi
 
       /* This thread is the first here.  Do the initialization.
 	 Register a cleanup handler so that in case the thread gets
-	 interrupted the initialization can be restarted.  */
-      pthread_cleanup_push (clear_once_control, once_control);
+	 interrupted the initialization can be restarted.
+	 This uses __pthread_cleanup_{push,pop} explicitly, because
+	 init_routine or something it calls might not have unwind
+	 information.  */
+      struct _pthread_cleanup_buffer buffer;
+      __pthread_cleanup_push (&buffer, clear_once_control, once_control);
 
       init_routine ();
 
-      pthread_cleanup_pop (0);
+      __pthread_cleanup_pop (&buffer, 0);
 
 
       /* Add one to *once_control.  */
--- libc/nptl/sysdeps/unix/sysv/linux/ia64/pthread_once.c.jj	2004-09-08 18:56:46.000000000 +0200
+++ libc/nptl/sysdeps/unix/sysv/linux/ia64/pthread_once.c	2007-01-16 15:28:18.000000000 +0100
@@ -1,4 +1,4 @@
-/* Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+/* Copyright (C) 2003, 2004, 2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Jakub Jelinek <jakub@redhat.com>, 2003.
 
@@ -72,12 +72,16 @@ __pthread_once (once_control, init_routi
 
       /* This thread is the first here.  Do the initialization.
 	 Register a cleanup handler so that in case the thread gets
-	 interrupted the initialization can be restarted.  */
-      pthread_cleanup_push (clear_once_control, once_control);
+	 interrupted the initialization can be restarted.
+	 This uses __pthread_cleanup_{push,pop} explicitly, because
+	 init_routine or something it calls might not have unwind
+	 information.  */
+      struct _pthread_cleanup_buffer buffer;
+      __pthread_cleanup_push (&buffer, clear_once_control, once_control);
 
       init_routine ();
 
-      pthread_cleanup_pop (0);
+      __pthread_cleanup_pop (&buffer, 0);
 
 
       /* Add one to *once_control.  */
--- libc/nptl/pthreadP.h.jj	2006-08-25 11:01:24.000000000 +0200
+++ libc/nptl/pthreadP.h	2007-01-16 15:23:18.000000000 +0100
@@ -1,4 +1,5 @@
-/* Copyright (C) 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007
+   Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -512,16 +513,20 @@ extern void __librt_disable_asynccancel 
 extern void __pthread_cleanup_push (struct _pthread_cleanup_buffer *buffer,
 				    void (*routine) (void *), void *arg)
      attribute_hidden;
-# undef pthread_cleanup_push
-# define pthread_cleanup_push(routine,arg) \
+# ifndef __EXCEPTIONS
+#  undef pthread_cleanup_push
+#  define pthread_cleanup_push(routine,arg) \
   { struct _pthread_cleanup_buffer _buffer;				      \
     __pthread_cleanup_push (&_buffer, (routine), (arg));
+# endif
 
 extern void __pthread_cleanup_pop (struct _pthread_cleanup_buffer *buffer,
 				   int execute) attribute_hidden;
-# undef pthread_cleanup_pop
-# define pthread_cleanup_pop(execute) \
+# ifndef __EXCEPTIONS
+#  undef pthread_cleanup_pop
+#  define pthread_cleanup_pop(execute) \
     __pthread_cleanup_pop (&_buffer, (execute)); }
+# endif
 #endif
 
 extern void __pthread_cleanup_push_defer (struct _pthread_cleanup_buffer *buffer,
--- libc/nptl/pthread_cond_wait.c.jj	2006-10-28 07:08:47.000000000 +0200
+++ libc/nptl/pthread_cond_wait.c	2007-01-16 15:23:31.000000000 +0100
@@ -1,4 +1,4 @@
-/* Copyright (C) 2003, 2004, 2006 Free Software Foundation, Inc.
+/* Copyright (C) 2003, 2004, 2006, 2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Martin Schwidefsky <schwidefsky@de.ibm.com>, 2003.
 
@@ -93,7 +93,6 @@ __pthread_cond_wait (cond, mutex)
      pthread_cond_t *cond;
      pthread_mutex_t *mutex;
 {
-  struct _pthread_cleanup_buffer buffer;
   struct _condvar_cleanup_buffer cbuffer;
   int err;
 
@@ -125,7 +124,7 @@ __pthread_cond_wait (cond, mutex)
 
   /* Before we block we enable cancellation.  Therefore we have to
      install a cancellation handler.  */
-  __pthread_cleanup_push (&buffer, __condvar_cleanup, &cbuffer);
+  pthread_cleanup_push (__condvar_cleanup, &cbuffer);
 
   /* The current values of the wakeup counter.  The "woken" counter
      must exceed this value.  */
@@ -181,7 +180,7 @@ __pthread_cond_wait (cond, mutex)
   lll_mutex_unlock (cond->__data.__lock);
 
   /* The cancellation handling is back to normal, remove the handler.  */
-  __pthread_cleanup_pop (&buffer, 0);
+  pthread_cleanup_pop (0);
 
   /* Get the mutex before returning.  */
   return __pthread_mutex_cond_lock (mutex);
--- libc/nptl/pthread_cond_timedwait.c.jj	2006-10-28 07:08:17.000000000 +0200
+++ libc/nptl/pthread_cond_timedwait.c	2007-01-16 15:23:40.000000000 +0100
@@ -1,4 +1,4 @@
-/* Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+/* Copyright (C) 2003, 2004, 2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Martin Schwidefsky <schwidefsky@de.ibm.com>, 2003.
 
@@ -45,7 +45,6 @@ __pthread_cond_timedwait (cond, mutex, a
      pthread_mutex_t *mutex;
      const struct timespec *abstime;
 {
-  struct _pthread_cleanup_buffer buffer;
   struct _condvar_cleanup_buffer cbuffer;
   int result = 0;
 
@@ -81,7 +80,7 @@ __pthread_cond_timedwait (cond, mutex, a
 
   /* Before we block we enable cancellation.  Therefore we have to
      install a cancellation handler.  */
-  __pthread_cleanup_push (&buffer, __condvar_cleanup, &cbuffer);
+  pthread_cleanup_push (__condvar_cleanup, &cbuffer);
 
   /* The current values of the wakeup counter.  The "woken" counter
      must exceed this value.  */
@@ -202,7 +201,7 @@ __pthread_cond_timedwait (cond, mutex, a
   lll_mutex_unlock (cond->__data.__lock);
 
   /* The cancellation handling is back to normal, remove the handler.  */
-  __pthread_cleanup_pop (&buffer, 0);
+  pthread_cleanup_pop (0);
 
   /* Get the mutex before returning.  */
   err = __pthread_mutex_cond_lock (mutex);

	Jakub


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]