From patchwork Sun Aug 22 16:51:36 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John David Anglin X-Patchwork-Id: 62392 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) by ozlabs.org (Postfix) with SMTP id 72DB9B70D1 for ; Mon, 23 Aug 2010 02:51:51 +1000 (EST) Received: (qmail 13696 invoked by alias); 22 Aug 2010 16:51:49 -0000 Received: (qmail 13679 invoked by uid 22791); 22 Aug 2010 16:51:46 -0000 X-SWARE-Spam-Status: No, hits=-1.8 required=5.0 tests=AWL, BAYES_00, TW_CX, TW_JV, TW_LG, TW_LR, TW_MG, T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from hiauly1.hia.nrc.ca (HELO hiauly1.hia.nrc.ca) (132.246.100.193) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Sun, 22 Aug 2010 16:51:39 +0000 Received: by hiauly1.hia.nrc.ca (Postfix, from userid 1000) id DB7074D06; Sun, 22 Aug 2010 12:51:36 -0400 (EDT) Date: Sun, 22 Aug 2010 12:51:36 -0400 From: John David Anglin To: gcc-patches@gcc.gnu.org Subject: [committed] Revise gthread active check on hppa-hpux11 Message-ID: <20100822165135.GA1737@hiauly1.hia.nrc.ca> Reply-To: John David Anglin MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.5.16 (2007-06-09) Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org I recently changed the __gthread_active_p check on hppa-hpux11 to use pthread_default_stacksize_np because the old method using pthread_create creates a thread and breaks pthread_default_stacksize_np. However, Olivier pointed out that HP only added a stub for pthread_default_stacksize_np to libc.sl in a fairly recent patch. Further, I noticed that there is still no stub in the archive variant of libc. The same is true for other pthread functions. We had side stepped the lack of stubs in libc.a by linking against libpthread.a when -static was specified. The attached patch adds stubs for pthread_default_stacksize_np, pthread_lock and pthread_unlock to our own stub library, libgcc_stub.a, and the SPEC machinary to link against it when not building a shared library. LIB_SPEC is modified to only add -lpthread when -mt or -pthread is specified. The build machinary is updated on the 32-bit targets to build the stub library. I simplified the __gthread_active_p check since as far as I can tell there was no reason to take a lock around the check. The downside of this approach is the additional complexity in linking threaded applications, but this is difficult to avoid given the lack of proper weak support. Tested on hppa2.0w-hp-hpux11.11 and hppa64-hp-hpux11.11. Committed to trunk. Dave Index: gthr-posix.h =================================================================== --- gthr-posix.h (revision 163445) +++ gthr-posix.h (working copy) @@ -260,47 +260,34 @@ calls in shared flavors of the HP-UX C library. Most of the stubs have no functionality. The details are described in the "libc cumulative patch" for each subversion of HP-UX 11. There are two special interfaces - provided for checking whether an application is linked to a pthread + provided for checking whether an application is linked to a shared pthread library or not. However, these interfaces aren't available in early - libc versions. We also can't use pthread_once as some libc versions - call the init function. So, we use pthread_create to check whether it - is possible to create a thread or not. The stub implementation returns - the error number ENOSYS. */ + libpthread libraries. We also need a test that works for archive + libraries. We can't use pthread_once as some libc versions call the + init function. We also can't use pthread_create or pthread_attr_init + as these create a thread and thereby prevent changing the default stack + size. The function pthread_default_stacksize_np is available in both + the archive and shared versions of libpthread. It can be used to + determine the default pthread stack size. There is a stub in some + shared libc versions which returns a zero size if pthreads are not + active. We provide an equivalent stub to handle cases where libc + doesn't provide one. */ #if defined(__hppa__) && defined(__hpux__) -#include - static volatile int __gthread_active = -1; -static void __gthread_active_init (void) __attribute__((noinline)); -static void -__gthread_active_init (void) -{ - static pthread_mutex_t __gthread_active_mutex = PTHREAD_MUTEX_INITIALIZER; - size_t __s; - - __gthrw_(pthread_mutex_lock) (&__gthread_active_mutex); - if (__gthread_active < 0) - { - pthread_default_stacksize_np (0, &__s); - __gthread_active = __s ? 1 : 0; - } - __gthrw_(pthread_mutex_unlock) (&__gthread_active_mutex); -} - static inline int __gthread_active_p (void) { /* Avoid reading __gthread_active twice on the main code path. */ int __gthread_active_latest_value = __gthread_active; + size_t __s; - /* This test is not protected to avoid taking a lock on the main code - path so every update of __gthread_active in a threaded program must - be atomic with regard to the result of the test. */ if (__builtin_expect (__gthread_active_latest_value < 0, 0)) { - __gthread_active_init (); + pthread_default_stacksize_np (0, &__s); + __gthread_active = __s ? 1 : 0; __gthread_active_latest_value = __gthread_active; } Index: gthr-posix95.h =================================================================== --- gthr-posix95.h (revision 163445) +++ gthr-posix95.h (working copy) @@ -184,47 +184,34 @@ calls in shared flavors of the HP-UX C library. Most of the stubs have no functionality. The details are described in the "libc cumulative patch" for each subversion of HP-UX 11. There are two special interfaces - provided for checking whether an application is linked to a pthread + provided for checking whether an application is linked to a shared pthread library or not. However, these interfaces aren't available in early - libc versions. We also can't use pthread_once as some libc versions - call the init function. So, we use pthread_create to check whether it - is possible to create a thread or not. The stub implementation returns - the error number ENOSYS. */ + pthread libraries. We also need a test that works for archive + libraries. We can't use pthread_once as some libc versions call the + init function. We also can't use pthread_create or pthread_attr_init + as these create a thread and thereby prevent changing the default stack + size. The function pthread_default_stacksize_np is available in both + the archive and shared versions of libpthread. It can be used to + determine the default pthread stack size. There is a stub in some + shared libc versions which returns a zero size if pthreads are not + active. We provide an equivalent stub to handle cases where libc + doesn't provide one. */ #if defined(__hppa__) && defined(__hpux__) -#include - static volatile int __gthread_active = -1; -static void __gthread_active_init (void) __attribute__((noinline)); -static void -__gthread_active_init (void) -{ - static pthread_mutex_t __gthread_active_mutex = PTHREAD_MUTEX_INITIALIZER; - size_t __s; - - __gthrw_(pthread_mutex_lock) (&__gthread_active_mutex); - if (__gthread_active < 0) - { - pthread_default_stacksize_np (0, &__s); - __gthread_active = __s ? 1 : 0; - } - __gthrw_(pthread_mutex_unlock) (&__gthread_active_mutex); -} - static inline int __gthread_active_p (void) { /* Avoid reading __gthread_active twice on the main code path. */ int __gthread_active_latest_value = __gthread_active; + size_t __s; - /* This test is not protected to avoid taking a lock on the main code - path so every update of __gthread_active in a threaded program must - be atomic with regard to the result of the test. */ if (__builtin_expect (__gthread_active_latest_value < 0, 0)) { - __gthread_active_init (); + pthread_default_stacksize_np (0, &__s); + __gthread_active = __s ? 1 : 0; __gthread_active_latest_value = __gthread_active; } Index: config.gcc =================================================================== --- config.gcc (revision 163445) +++ config.gcc (working copy) @@ -1106,6 +1106,7 @@ else tmake_file="$tmake_file pa/t-slibgcc-dwarf-ver" fi + extra_parts="libgcc_stub.a" case x${enable_threads} in x | xyes | xposix ) thread_file=posix Index: config/pa/pa64-hpux.h =================================================================== --- config/pa/pa64-hpux.h (revision 163445) +++ config/pa/pa64-hpux.h (working copy) @@ -59,35 +59,35 @@ #if ((TARGET_DEFAULT | TARGET_CPU_DEFAULT) & MASK_GNU_LD) #define LIB_SPEC \ "%{!shared:\ - %{!p:%{!pg:%{static|mt|pthread:%{fopenmp:%{static:-a shared} -lrt\ - %{static:-a archive}} -lpthread} -lc\ + %{!p:%{!pg:%{fopenmp:%{static:-a shared} -lrt %{static:-a archive}}\ + %{mt|pthread:-lpthread} -lc\ %{static:%{!nolibdld:-a shared -ldld -a archive -lc}}}}\ %{p:%{!pg:%{static:%{!mhp-ld:-a shared}%{mhp-ld:-a archive_shared}}\ -lprof %{static:-a archive}\ - %{static|mt|pthread:%{fopenmp:%{static:-a shared} -lrt\ - %{static:-a archive}} -lpthread} -lc\ + %{fopenmp:%{static:-a shared} -lrt %{static:-a archive}}\ + %{mt|pthread:-lpthread} -lc\ %{static:%{!nolibdld:-a shared -ldld -a archive -lc}}}}\ %{pg:%{static:%{!mhp-ld:-a shared}%{mhp-ld:-a archive_shared}}\ -lgprof %{static:-a archive}\ - %{static|mt|pthread:%{fopenmp:%{static:-a shared} -lrt\ - %{static:-a archive}} -lpthread} -lc\ + %{fopenmp:%{static:-a shared} -lrt %{static:-a archive}}\ + %{mt|pthread:-lpthread} -lc\ %{static:%{!nolibdld:-a shared -ldld -a archive -lc}}}}\ %{shared:%{mt|pthread:-lpthread}}" #else #define LIB_SPEC \ "%{!shared:\ - %{!p:%{!pg:%{static|mt|pthread:%{fopenmp:%{static:-a shared} -lrt\ - %{static:-a archive}} -lpthread} -lc\ + %{!p:%{!pg:%{fopenmp:%{static:-a shared} -lrt %{static:-a archive}}\ + %{mt|pthread:-lpthread} -lc\ %{static:%{!nolibdld:-a shared -ldld -a archive -lc}}}}\ %{p:%{!pg:%{static:%{mgnu-ld:-a shared}%{!mgnu-ld:-a archive_shared}}\ -lprof %{static:-a archive}\ - %{static|mt|pthread:%{fopenmp:%{static:-a shared} -lrt\ - %{static:-a archive}} -lpthread} -lc\ + %{fopenmp:%{static:-a shared} -lrt %{static:-a archive}}\ + %{mt|pthread:-lpthread} -lc\ %{static:%{!nolibdld:-a shared -ldld -a archive -lc}}}}\ %{pg:%{static:%{mgnu-ld:-a shared}%{!mgnu-ld:-a archive_shared}}\ -lgprof %{static:-a archive}\ - %{static|mt|pthread:%{fopenmp:%{static:-a shared} -lrt\ - %{static:-a archive}} -lpthread} -lc\ + %{fopenmp:%{static:-a shared} -lrt %{static:-a archive}}\ + %{mt|pthread:-lpthread} -lc\ %{static:%{!nolibdld:-a shared -ldld -a archive -lc}}}}\ %{shared:%{mt|pthread:-lpthread}}" #endif Index: config/pa/t-pa-hpux11 =================================================================== --- config/pa/t-pa-hpux11 (revision 163445) +++ config/pa/t-pa-hpux11 (working copy) @@ -1,2 +1,26 @@ TARGET_LIBGCC2_CFLAGS = -fPIC -frandom-seed=fixed-seed LIB2FUNCS_EXTRA=lib2funcs.asm quadlib.c +LIBGCCSTUB_OBJS = pthread_default_stacksize_np-stub.o \ + pthread_mutex_lock-stub.o \ + pthread_mutex_unlock-stub.o + +stublib.c: $(srcdir)/config/pa/stublib.c + rm -f stublib.c + cp $(srcdir)/config/pa/stublib.c . + +pthread_default_stacksize_np-stub.o: stublib.c $(GCC_PASSES) + $(GCC_FOR_TARGET) -c -O2 -DL_pthread_default_stacksize_np stublib.c \ + -o pthread_default_stacksize_np-stub.o + +pthread_mutex_lock-stub.o: stublib.c $(GCC_PASSES) + $(GCC_FOR_TARGET) -c -O2 -DL_pthread_mutex_lock stublib.c \ + -o pthread_mutex_lock-stub.o + +pthread_mutex_unlock-stub.o: stublib.c $(GCC_PASSES) + $(GCC_FOR_TARGET) -c -O2 -DL_pthread_mutex_unlock stublib.c \ + -o pthread_mutex_unlock-stub.o + +$(T)libgcc_stub.a: $(LIBGCCSTUB_OBJS) + -rm -rf $(T)libgcc_stub.a + $(AR) rc $(T)libgcc_stub.a $(LIBGCCSTUB_OBJS) + $(RANLIB) $(T)libgcc_stub.a Index: config/pa/pa-hpux11.h =================================================================== --- config/pa/pa-hpux11.h (revision 163445) +++ config/pa/pa-hpux11.h (working copy) @@ -121,11 +121,16 @@ #undef LIB_SPEC #define LIB_SPEC \ "%{!shared:\ - %{static|mt|pthread:%{fopenmp:%{static:-a archive_shared} -lrt\ - %{static:-a archive}} -lpthread} -lc\ + %{fopenmp:%{static:-a archive_shared} -lrt %{static:-a archive}}\ + %{mt|pthread:-lpthread} -lc\ %{static:%{!nolibdld:-a archive_shared -ldld -a archive -lc}}}\ %{shared:%{mt|pthread:-lpthread}}" +/* The libgcc_stub.a library needs to come last. */ +#undef LINK_GCC_C_SEQUENCE_SPEC +#define LINK_GCC_C_SEQUENCE_SPEC \ + "%G %L %G %{!nostdlib:%{!nodefaultlibs:%{!shared:-lgcc_stub}}}" + #undef STARTFILE_SPEC #define STARTFILE_SPEC \ "%{!shared:%{pg:gcrt0%O%s}%{!pg:%{p:mcrt0%O%s}%{!p:crt0%O%s}} \ Index: config/pa/t-pa64 =================================================================== --- config/pa/t-pa64 (revision 163445) +++ config/pa/t-pa64 (working copy) @@ -1,5 +1,5 @@ # Copyright (C) 2000, 2001, 2002, 2004, 2006, -# 2007 Free Software Foundation, Inc. +# 2007, 2010 Free Software Foundation, Inc. # # This file is part of GCC. # @@ -19,7 +19,10 @@ TARGET_LIBGCC2_CFLAGS = -fPIC -Dpa64=1 -DELF=1 -mlong-calls LIB2FUNCS_EXTRA = quadlib.c -LIBGCCSTUB_OBJS = rfi-stub.o dfi-stub.o jvrc-stub.o cxaf-stub.o +LIBGCCSTUB_OBJS = rfi-stub.o dfi-stub.o jvrc-stub.o cxaf-stub.o \ + pthread_default_stacksize_np-stub.o \ + pthread_mutex_lock-stub.o \ + pthread_mutex_unlock-stub.o stublib.c: $(srcdir)/config/pa/stublib.c rm -f stublib.c @@ -41,6 +44,18 @@ $(GCC_FOR_TARGET) -c -O2 -DL_Jv_RegisterClasses stublib.c \ -o jvrc-stub.o +pthread_default_stacksize_np-stub.o: stublib.c $(GCC_PASSES) + $(GCC_FOR_TARGET) -c -O2 -DL_pthread_default_stacksize_np stublib.c \ + -o pthread_default_stacksize_np-stub.o + +pthread_mutex_lock-stub.o: stublib.c $(GCC_PASSES) + $(GCC_FOR_TARGET) -c -O2 -DL_pthread_mutex_lock stublib.c \ + -o pthread_mutex_lock-stub.o + +pthread_mutex_unlock-stub.o: stublib.c $(GCC_PASSES) + $(GCC_FOR_TARGET) -c -O2 -DL_pthread_mutex_unlock stublib.c \ + -o pthread_mutex_unlock-stub.o + $(T)libgcc_stub.a: $(LIBGCCSTUB_OBJS) -rm -rf $(T)libgcc_stub.a $(AR) rc $(T)libgcc_stub.a $(LIBGCCSTUB_OBJS) Index: config/pa/stublib.c =================================================================== --- config/pa/stublib.c (revision 163445) +++ config/pa/stublib.c (working copy) @@ -1,5 +1,5 @@ /* Stub functions. - Copyright (C) 2006, 2009 Free Software Foundation, Inc. + Copyright (C) 2006, 2009, 2010 Free Software Foundation, Inc. This file is part of GCC. @@ -56,3 +56,33 @@ { } #endif + +#ifdef L_pthread_default_stacksize_np +int pthread_default_stacksize_np (unsigned long __attribute__((unused)), + unsigned long *); +int +pthread_default_stacksize_np (unsigned long new, unsigned long *old) +{ + if (old) + *old = 0; + return 0; +} +#endif + +#ifdef L_pthread_mutex_lock +int pthread_mutex_lock (void * __attribute__((unused))); +int +pthread_mutex_lock (void *p) +{ + return 0; +} +#endif + +#ifdef L_pthread_mutex_unlock +int pthread_mutex_unlock (void * __attribute__((unused))); +int +pthread_mutex_unlock (void *p) +{ + return 0; +} +#endif