From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 25549 invoked by alias); 16 Jan 2007 15:58:04 -0000 Received: (qmail 25532 invoked by uid 22791); 16 Jan 2007 15:58:03 -0000 X-Spam-Check-By: sourceware.org Received: from sunsite.ms.mff.cuni.cz (HELO sunsite.mff.cuni.cz) (195.113.15.26) by sourceware.org (qpsmtpd/0.31) with ESMTP; Tue, 16 Jan 2007 15:57:58 +0000 Received: from sunsite.mff.cuni.cz (localhost.localdomain [127.0.0.1]) by sunsite.mff.cuni.cz (8.13.8/8.13.8) with ESMTP id l0GG1AGq024069; Tue, 16 Jan 2007 17:01:10 +0100 Received: (from jakub@localhost) by sunsite.mff.cuni.cz (8.13.8/8.13.8/Submit) id l0GG1AV5024067; Tue, 16 Jan 2007 17:01:10 +0100 Date: Tue, 16 Jan 2007 15:58:00 -0000 From: Jakub Jelinek To: Ulrich Drepper Cc: Glibc hackers Subject: [PATCH] Speed up pthread_cleanup_{push,pop} inside of libpthread Message-ID: <20070116160109.GE3819@sunsite.mff.cuni.cz> Reply-To: Jakub Jelinek Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.4.2.2i Mailing-List: contact libc-hacker-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-hacker-owner@sourceware.org X-SW-Source: 2007-01/txt/msg00007.txt.bz2 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 * 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 , 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 , 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 , 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 , 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 , 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 , 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 , 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