[PATCH] Fix gthr-posix.h for use on Tru64

Roger Sayle roger@eyesopen.com
Sat Jan 21 02:10:00 GMT 2006


The following patch fixes an impressive number of unexpected failures
when running the testsuite on alphaev67-dec-osf5.1.  To be specific,
it resolves 1231 g++ failures, 4808 gfortran failures, 629 objc failures,
1182 libstdc++ failures and 79 libffi failures.

The problem concerns a poor interaction between the peculiar weak
reference semantics in OSF/1, the name mangling used by pthread.h
on those systems, and the recent implementation of #pragma extern_prefix
in GCC.  Its a convoluted story (and many thanks to Alexandre Oliva and
Andrew Pinski for helping me figure it out!).

In dim dark past, Tru64 orginally implemented the old POSIX 1003.4a/D4
API for the pthreads interface, where many of the functions had the same
names as the newer POSIX 1003.1c specification.  To preserve backwards
binary compatability on Tru64, and avoid conflicting symbols, pthread.h
on Tru64 mangles the names of the conflicting function prototypes such
that the new definitions are prefixed with "__".  i.e. pthread_mutex_init
is the old implementation, and __pthread_mutex_init is the new one, with
magic in the system headers to select the appropriate one.

Now between gthr-posix.h and gthr-posix.c, we internally define weak
references with names "__gthr_foo" to pthread function "foo", where on
Tru64 dummy implementations are provided in gthr-posix.c.

Now once upon a time, the fixincluded /usr/include/pthread.h detected
that GCC didn't support #pragma extern_prefix so used the failsafe idiom
#define pthread_mutex_init __pthread_mutex_init.  This fortunately
played nicely with our weak reference hackery as the pthread_mutex_init
was suitably substituted/expanded both in the definition in gthr-posix.c
and in the __attribute__ ((__weakref__ ...)).

The problem is that GCC 4.x now handles #pragma extern_prefix, and
fixincludes adjusts pthread.h so that it now uses the idiom
#pragma extern_prefix "__" around the prototype of pthread_mutex_init.
This means that the implementation in gthr-posix.c is still called
__pthread_mutex_init, but the weakref in gthr.h now references the
unmangled symbol pthread_mutex_init.


One possible solution is implement and document an interaction between
#pragma extern_prefix and __attribute__ ((__weakref__ ...)) such that
if the alias string in the weak ref matches a declared DECL with a
specified DECL_ASSEMBLER_NAME, the weakref refers to the latter.
This I find hideously complicated, but some might disagree.

The other solution is that the text in __weakref__ should refer to
the real low-level symbol being aliased, and that the code in gthr.h
should make sure we map from __gthr_foo to the correct foo or __foo.

This patch below implements the latter.  We split the existing
functionality of __gthrw into a binary __gthrw2(foo,bar) which
creates a weak reference for __gthr_foo to bar.  Then define the
original __gthrw as simply __gthrw2(x,x).  Finally we test for
__osf__ and _PTHREAD_USE_MANGLED_NAMES_ to determine whether we
need to perform Tru64's pthread function name mangling ourselves.

Ultimately, the weak references in libstdc++, libgfortran and
libobjc, now match the dummy symbols that we define in libgcc.a.


The following patch has been tested on i686-pc-linux-gnu and
alphaev67-dec-osf5.1 with a full "make bootstrap", all default
languages, and regression tested with a top-level "make -k check"
with no new failures.

Due to disk space issues on my Tru64 system, I've not yet checked
whether this affects gcc 4.0.x, but it is causing a significant
number of regressions on mainline and 4.1.x.

Ok for mainline and 4.1?



2006-01-20  Roger Sayle  <roger@eyesopen.com>

	* gthr-posix.h: On Tru64, map __gthr_foo as a weak reference to
	__foo and not foo when _PTHREAD_USE_MANGLED_NAMES_ is defined.


Index: gthr-posix.h
===================================================================
*** gthr-posix.h	(revision 109912)
--- gthr-posix.h	(working copy)
***************
*** 1,6 ****
  /* Threads compatibility routines for libgcc2 and libobjc.  */
  /* Compile this one with gcc.  */
! /* Copyright (C) 1997, 1999, 2000, 2001, 2002, 2003, 2004, 2005
     Free Software Foundation, Inc.

  This file is part of GCC.
--- 1,6 ----
  /* Threads compatibility routines for libgcc2 and libobjc.  */
  /* Compile this one with gcc.  */
! /* Copyright (C) 1997, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
     Free Software Foundation, Inc.

  This file is part of GCC.
*************** typedef pthread_mutex_t __gthread_recurs
*** 59,93 ****
  #endif

  #if SUPPORTS_WEAK && GTHREAD_USE_WEAK
! # define __gthrw(name) \
!   static __typeof(name) __gthrw_ ## name __attribute__ ((__weakref__(#name)))
  #else
  # define __gthrw_asmname(cname) __gthrw_asmnamep (__USER_LABEL_PREFIX__, cname)
  # define __gthrw_asmnamep(prefix, cname) __gthrw_string (prefix) cname
  # define __gthrw_string(x) #x
! # define __gthrw(name) \
!   extern __typeof(name) __gthrw_ ## name __asm (__gthrw_asmname (#name))
  #endif

  __gthrw(pthread_once);
- __gthrw(pthread_key_create);
- __gthrw(pthread_key_delete);
  __gthrw(pthread_getspecific);
  __gthrw(pthread_setspecific);
  __gthrw(pthread_create);
  __gthrw(pthread_cancel);
-
  __gthrw(pthread_mutex_lock);
  __gthrw(pthread_mutex_trylock);
  __gthrw(pthread_mutex_unlock);
  __gthrw(pthread_mutexattr_init);
  __gthrw(pthread_mutexattr_settype);
  __gthrw(pthread_mutexattr_destroy);

- __gthrw(pthread_mutex_init);

  #if defined(_LIBOBJC) || defined(_LIBOBJC_WEAK)
  /* Objective-C.  */
  __gthrw(pthread_cond_broadcast);
  __gthrw(pthread_cond_destroy);
  __gthrw(pthread_cond_init);
--- 59,121 ----
  #endif

  #if SUPPORTS_WEAK && GTHREAD_USE_WEAK
! # define __gthrw2(name,name2) \
!   static __typeof(name) __gthrw_ ## name __attribute__ ((__weakref__(#name2)))
  #else
  # define __gthrw_asmname(cname) __gthrw_asmnamep (__USER_LABEL_PREFIX__, cname)
  # define __gthrw_asmnamep(prefix, cname) __gthrw_string (prefix) cname
  # define __gthrw_string(x) #x
! # define __gthrw2(name,name2) \
!   extern __typeof(name) __gthrw_ ## name __asm (__gthrw_asmname (#name2))
  #endif

+ /* By default, the __gthrw_foo names is a weak refernce to symbol foo.  */
+ #define __gthrw(name) __gthrw2(name,name)
+
+ /* On Tru64, /usr/include/pthread.h uses #pragma extern_prefix "__" to
+    map a subset of the POSIX pthread API to mangled versions of their
+    names.  */
+ #if defined(__osf__) && defined(_PTHREAD_USE_MANGLED_NAMES_)
+ __gthrw2(pthread_once,__pthread_once);
+ __gthrw2(pthread_getspecific,__pthread_getspecific);
+ __gthrw2(pthread_setspecific,__pthread_setspecific);
+ __gthrw2(pthread_create,__pthread_create);
+ __gthrw2(pthread_cancel,__pthread_cancel);
+ __gthrw2(pthread_mutex_lock,__pthread_mutex_lock);
+ __gthrw2(pthread_mutex_trylock,__pthread_mutex_trylock);
+ __gthrw2(pthread_mutex_unlock,__pthread_mutex_unlock);
+ __gthrw2(pthread_mutex_init,__pthread_mutex_init);
+ #else
  __gthrw(pthread_once);
  __gthrw(pthread_getspecific);
  __gthrw(pthread_setspecific);
  __gthrw(pthread_create);
  __gthrw(pthread_cancel);
  __gthrw(pthread_mutex_lock);
  __gthrw(pthread_mutex_trylock);
  __gthrw(pthread_mutex_unlock);
+ __gthrw(pthread_mutex_init);
+ #endif
+
+ __gthrw(pthread_key_create);
+ __gthrw(pthread_key_delete);
  __gthrw(pthread_mutexattr_init);
  __gthrw(pthread_mutexattr_settype);
  __gthrw(pthread_mutexattr_destroy);


  #if defined(_LIBOBJC) || defined(_LIBOBJC_WEAK)
  /* Objective-C.  */
+ #if defined(__osf__) && defined(_PTHREAD_USE_MANGLED_NAMES_)
+ __gthrw2(pthread_cond_broadcast,__pthread_cond_broadcast);
+ __gthrw2(pthread_cond_destroy,__pthread_cond_destroy);
+ __gthrw2(pthread_cond_init,__pthread_cond_init);
+ __gthrw2(pthread_cond_signal,__pthread_cond_signal);
+ __gthrw2(pthread_cond_wait,__pthread_cond_wait);
+ __gthrw2(pthread_exit,__pthread_exit);
+ __gthrw2(pthread_mutex_destroy,__pthread_mutex_destroy);
+ __gthrw2(pthread_self,__pthread_self);
+ #else
  __gthrw(pthread_cond_broadcast);
  __gthrw(pthread_cond_destroy);
  __gthrw(pthread_cond_init);
*************** __gthrw(pthread_cond_wait);
*** 96,101 ****
--- 124,130 ----
  __gthrw(pthread_exit);
  __gthrw(pthread_mutex_destroy);
  __gthrw(pthread_self);
+ #endif /* __osf__ && _PTHREAD_USE_MANGLED_NAMES_ */
  #ifdef _POSIX_PRIORITY_SCHEDULING
  #ifdef _POSIX_THREAD_PRIORITY_SCHEDULING
  __gthrw(sched_get_priority_max);


Roger
--
Roger Sayle,                         E-mail: roger@eyesopen.com
OpenEye Scientific Software,         WWW: http://www.eyesopen.com/
Suite 1107, 3600 Cerrillos Road,     Tel: (+1) 505-473-7385
Santa Fe, New Mexico, 87507.         Fax: (+1) 505-473-0833



More information about the Gcc-patches mailing list