This is the mail archive of the libstdc++@gcc.gnu.org mailing list for the libstdc++ project.


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] Thread support for TPF


Hello,

this patch adds thread support for the C++ libraries on the TPF OS.

While TPF does provide the POSIX thread interface, the heuristics
employed by __gthread_active_p in gthr-posix.h is suboptimal on
TPF: this routine tries to distinguish between (definitely) single-
threaded and (potentially) multi-threaded applications by checking
whether the weak symbol pthread_create is present or not.

This test is always true on TPF because applications are always
implicitly linked against libpthread.  On the other hand, the OS
maintains a distinct state difference between single-threaded
and multi-threaded applications: an application is switched from
single-threaded to multi-threaded state (with nontrivial overhead)
the first time it performs any pthread_ call.

This combines to a somewhat unfortunate effect: as __gthread_active_p
always returns true, the C++ libraries always try to use mutexes to
protect their datastructures, and the first such mutex call causes
TPF to switch the application to multi-threaded state ...

To avoid that overhead for really single-threaded applications, 
we should really only call the pthread_mutex_ functions on TPF
if the application is already in the multi-threaded state.

This patch adds a new file gthr-tpf.h that is used instead of
gthr-posix.h on TPF, which does just this.

Unfortunately, simply setting thread_file='tpf' in config.gcc is
*not* enough to cause this file to be used -- the master gthr.h
will completely ignore the value of thread_file if the OS defines
the _PTHREADS flag (which TPF does).  Is this intentional?
To get around this, the patch modifies the gthr.h to add an extra
check for TPF.

Bootstrapped/regtested on s390-ibm-lixux and s390x-ibm-linux;
tested on TPF by the TPF team.

OK for mainline?

Bye,
Ulrich


Patch provided by P.J. Darcy (darcypj@us.ibm.com).

ChangeLog:

	* gthr-tpf.h: New file.
	* config.gcc (s390x-ibm-tpf*): Add thread_file='tpf'.
	* gthr.h: Use gthr-tpf.h on TPF OS.

libstdc++/ChangeLog:

	* include/Makefile.am (thread_host_headers): Add gthr-tpf.h.
	Add rule to build ${host_builddir}/gthr-tpf.h.
	* include/Makefile.in: Regenerate.


Index: gcc/config.gcc
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config.gcc,v
retrieving revision 1.490
diff -c -p -r1.490 config.gcc
*** gcc/config.gcc	14 Sep 2004 19:58:49 -0000	1.490
--- gcc/config.gcc	21 Sep 2004 17:48:24 -0000
*************** s390x-ibm-tpf*)
*** 1675,1680 ****
--- 1675,1681 ----
  	extra_parts="crtbegin.o crtbeginS.o crtbeginT.o crtend.o crtendS.o"
  	out_file=s390/s390.c
  	tmake_file="t-slibgcc-elf-ver s390/t-crtstuff s390/t-tpf"
+ 	thread_file='tpf'
  	;;
  sh-*-elf* | sh[12346l]*-*-elf* | sh*-*-kaos* | \
  sh-*-symbianelf* | sh[12346l]*-*-symbianelf* | \
Index: gcc/gthr.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/gthr.h,v
retrieving revision 1.16
diff -c -p -r1.16 gthr.h
*** gcc/gthr.h	28 Aug 2004 02:33:48 -0000	1.16
--- gcc/gthr.h	21 Sep 2004 17:48:24 -0000
*************** Software Foundation, 59 Temple Place - S
*** 89,95 ****
  */
  
  /* Check first for thread specific defines.  */
! #if _PTHREADS
  #include "gthr-posix.h"
  #elif _DCE_THREADS
  #include "gthr-dce.h"
--- 89,97 ----
  */
  
  /* Check first for thread specific defines.  */
! #if defined (tpf)
! #include "gthr-tpf.h"
! #elif _PTHREADS
  #include "gthr-posix.h"
  #elif _DCE_THREADS
  #include "gthr-dce.h"
Index: libstdc++-v3/include/Makefile.am
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/include/Makefile.am,v
retrieving revision 1.84
diff -c -p -r1.84 Makefile.am
*** libstdc++-v3/include/Makefile.am	2 Sep 2004 16:56:28 -0000	1.84
--- libstdc++-v3/include/Makefile.am	21 Sep 2004 17:48:30 -0000
*************** thread_host_headers = \
*** 361,366 ****
--- 361,367 ----
  	${host_builddir}/gthr.h \
  	${host_builddir}/gthr-single.h \
  	${host_builddir}/gthr-posix.h \
+ 	${host_builddir}/gthr-tpf.h \
  	${host_builddir}/gthr-default.h
  
  pch_input = ${host_builddir}/stdc++.h
*************** ${host_builddir}/gthr-posix.h: ${topleve
*** 526,531 ****
--- 527,540 ----
  	    -e 's/\(${uppercase}*USE_WEAK\)/_GLIBCXX_\1/g' \
  	    < ${toplevel_srcdir}/gcc/gthr-posix.h > $@
  
+ ${host_builddir}/gthr-tpf.h: ${toplevel_srcdir}/gcc/gthr-tpf.h \
+ 				   stamp-${host_alias}
+ 	sed -e 's/\(UNUSED\)/_GLIBCXX_\1/g' \
+ 	    -e 's/\(GCC${uppercase}*_H\)/_GLIBCXX_\1/g' \
+ 	    -e 's/SUPPORTS_WEAK/__GXX_WEAK__/g' \
+ 	    -e 's/\(${uppercase}*USE_WEAK\)/_GLIBCXX_\1/g' \
+ 	    < ${toplevel_srcdir}/gcc/gthr-tpf.h > $@
+ 
  ${host_builddir}/gthr-default.h: ${toplevel_srcdir}/gcc/${glibcxx_thread_h} \
  				   stamp-${host_alias}
  	sed -e 's/\(UNUSED\)/_GLIBCXX_\1/g' \
Index: libstdc++-v3/include/Makefile.in
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/include/Makefile.in,v
retrieving revision 1.110
diff -c -p -r1.110 Makefile.in
*** libstdc++-v3/include/Makefile.in	2 Sep 2004 16:56:28 -0000	1.110
--- libstdc++-v3/include/Makefile.in	21 Sep 2004 17:48:30 -0000
*************** thread_host_headers = \
*** 575,580 ****
--- 575,581 ----
  	${host_builddir}/gthr.h \
  	${host_builddir}/gthr-single.h \
  	${host_builddir}/gthr-posix.h \
+ 	${host_builddir}/gthr-tpf.h \
  	${host_builddir}/gthr-default.h
  
  pch_input = ${host_builddir}/stdc++.h
*************** ${host_builddir}/gthr-posix.h: ${topleve
*** 903,908 ****
--- 904,917 ----
  	    -e 's/\(${uppercase}*USE_WEAK\)/_GLIBCXX_\1/g' \
  	    < ${toplevel_srcdir}/gcc/gthr-posix.h > $@
  
+ ${host_builddir}/gthr-tpf.h: ${toplevel_srcdir}/gcc/gthr-tpf.h \
+ 				   stamp-${host_alias}
+ 	sed -e 's/\(UNUSED\)/_GLIBCXX_\1/g' \
+ 	    -e 's/\(GCC${uppercase}*_H\)/_GLIBCXX_\1/g' \
+ 	    -e 's/SUPPORTS_WEAK/__GXX_WEAK__/g' \
+ 	    -e 's/\(${uppercase}*USE_WEAK\)/_GLIBCXX_\1/g' \
+ 	    < ${toplevel_srcdir}/gcc/gthr-tpf.h > $@
+ 
  ${host_builddir}/gthr-default.h: ${toplevel_srcdir}/gcc/${glibcxx_thread_h} \
  				   stamp-${host_alias}
  	sed -e 's/\(UNUSED\)/_GLIBCXX_\1/g' \
*** /dev/null	Mon Jul 12 10:01:50 2004
--- gcc/gthr-tpf.h	Tue Sep 21 19:42:05 2004
***************
*** 0 ****
--- 1,157 ----
+ /* Threads compatibility routines for libgcc2 and libobjc.
+    Compile this one with gcc.
+    Copyright (C) 2004 Free Software Foundation, Inc.
+ 
+ This file is part of GCC.
+ 
+ GCC is free software; you can redistribute it and/or modify it under
+ the terms of the GNU General Public License as published by the Free
+ Software Foundation; either version 2, or (at your option) any later
+ version.
+ 
+ GCC 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 General Public License
+ for more details.
+ 
+ You should have received a copy of the GNU General Public License
+ along with GCC; see the file COPYING.  If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA.  */
+ 
+ /* As a special exception, if you link this library with other files,
+    some of which are compiled with GCC, to produce an executable,
+    this library does not by itself cause the resulting executable
+    to be covered by the GNU General Public License.
+    This exception does not however invalidate any other reasons why
+    the executable file might be covered by the GNU General Public License.  */
+ 
+ 
+ /* TPF needs its own version of gthr-*.h because TPF always links to 
+    the thread library.  However, for performance reasons we still do not
+    want to issue thread api calls unless a check is made to see that we
+    are running as a thread.  */
+ 
+ #ifndef GCC_GTHR_TPF_H
+ #define GCC_GTHR_TPF_H
+ 
+ /* POSIX threads specific definitions.
+    Easy, since the interface is just one-to-one mapping.  */
+ 
+ #define __GTHREADS 1
+ 
+ /* Some implementations of <pthread.h> require this to be defined.  */
+ #ifndef _REENTRANT
+ #define _REENTRANT 1
+ #endif
+ 
+ #include <pthread.h>
+ #include <unistd.h>
+ 
+ typedef pthread_key_t __gthread_key_t;
+ typedef pthread_once_t __gthread_once_t;
+ typedef pthread_mutex_t __gthread_mutex_t;
+ 
+ #define __GTHREAD_MUTEX_INIT PTHREAD_MUTEX_INITIALIZER
+ #define __GTHREAD_ONCE_INIT PTHREAD_ONCE_INIT
+ 
+ #define NOTATHREAD   00
+ #define ECBBASEPTR (unsigned long int) *(unsigned int *)0x00000514u
+ #define ECBPG2PTR  ECBBASEPTR + 0x1000
+ #define CE2THRCPTR *((unsigned char *)(ECBPG2PTR + 208))
+ #define __tpf_pthread_active() (CE2THRCPTR != NOTATHREAD)
+ 
+ #if SUPPORTS_WEAK && GTHREAD_USE_WEAK
+ 
+ #pragma weak pthread_once
+ #pragma weak pthread_key_create
+ #pragma weak pthread_key_delete
+ #pragma weak pthread_getspecific
+ #pragma weak pthread_setspecific
+ #pragma weak pthread_create
+ 
+ #pragma weak pthread_mutex_lock
+ #pragma weak pthread_mutex_trylock
+ #pragma weak pthread_mutex_unlock
+ 
+ #endif /* SUPPORTS_WEAK */
+ 
+ static inline int
+ __gthread_active_p (void)
+ {
+   return 1;
+ }
+ 
+ static inline int
+ __gthread_once (__gthread_once_t *once, void (*func) (void))
+ {
+   if (__tpf_pthread_active ())
+     return pthread_once (once, func);
+   else
+     return -1;
+ }
+ 
+ static inline int
+ __gthread_key_create (__gthread_key_t *key, void (*dtor) (void *))
+ {
+   if (__tpf_pthread_active ())
+     return pthread_key_create (key, dtor);
+   else
+     return -1;
+ }
+ 
+ static inline int
+ __gthread_key_delete (__gthread_key_t key)
+ {
+   if (__tpf_pthread_active ())
+     return pthread_key_delete (key);
+   else
+     return -1;
+ }
+ 
+ static inline void *
+ __gthread_getspecific (__gthread_key_t key)
+ {
+   if (__tpf_pthread_active ())
+     return pthread_getspecific (key);
+   else
+     return NULL;
+ }
+ 
+ static inline int
+ __gthread_setspecific (__gthread_key_t key, const void *ptr)
+ {
+   if (__tpf_pthread_active ())
+     return pthread_setspecific (key, ptr);
+   else
+     return -1;
+ }
+ 
+ static inline int
+ __gthread_mutex_lock (__gthread_mutex_t *mutex)
+ {
+   if (__tpf_pthread_active ())
+     return pthread_mutex_lock (mutex);
+   else
+     return 0;
+ }
+ 
+ static inline int
+ __gthread_mutex_trylock (__gthread_mutex_t *mutex)
+ {
+   if (__tpf_pthread_active ())
+     return pthread_mutex_trylock (mutex);
+   else
+     return 0;
+ }
+ 
+ static inline int
+ __gthread_mutex_unlock (__gthread_mutex_t *mutex)
+ {
+   if (__tpf_pthread_active ())
+     return pthread_mutex_unlock (mutex);
+   else
+     return 0;
+ }
+ 
+ #endif /* ! GCC_GTHR_TPF_H */
-- 
  Dr. Ulrich Weigand
  weigand@informatik.uni-erlangen.de


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