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]

Configuration patches to handle threading and general tuning issues


This patch is still a work in progress.

In addition to all changes shown, this patch assumes that we can now
remove config/threads-no.h and config/threads-posix.h .

Regenerated files are not shown.  Some Makefile.am patches are not
shown (since they are not done yet) which handle the removed and added
files.  Nor is the actual installation of gthr*.h files handled yet
although I did handle (in a manner almost OK, I think) the proper
staging of all required gthr*.h files from ../gcc into
libstdc++-v3/include/bits (I'm sure someone will tell me how to
replace the ``mkdir -p include/bits; echo >include/bits/[...]'' with
the correct autoconf way to do it.  Since I got the staging into
libstdc++-v3's $(objdir), I know it should be fairly simple to get
final installation working if we like this configuration change.

stl_threads.h still has to have the actual mapping from the gthr.h
abstraction layer to what STL requires.  Simple enough, but not done
yet. (At this point, we get the non-thread path of stl_threads.h).
Since this file is imported from SGI, I will add markers in the style
shown unless there is another convention people would like me to follow.

Finally, I changed the configuration of __USE_MALLOC (no longer define
it) and documented why and how to re-add it or how to use another
method to get malloc allocation on a per-container basis instead of
globally changing the default for all users of STL.  I have personally
profiled this configuration change (see e-mail from about a week ago).
For single-threaded code, the speed-up from *not* defining
__USE_MALLOC is amazing on FreeBSD.  Ports that absolutely want this
allocator, can always throw __USE_MALLOC in bits/os_defines.h, but if
it keep the symbol defined, there is no way for ports to undo the
speed impairment.  For threaded code, one can always explicitly pick
the allocator to use (see comment below).

libstdc++-v3 was completely rebuilt and reinstalled (with a little
help to move gthr*.h files by hand) but only informal testing has
commenced so far, no full bootstrap, no full regression test.
However, I did check to ensure all the right macros are appearing
where they should under this ../gcc/gthr*.h-based configuration style.

No ChangeLog yet but I do try to comment my patches thus you should
find anything non-trivial below.  For changes similar to Dave's posted
patch, I would think similar words would work fine... ;-)

Expect a semi-final version of this from me late today or Friday.  I
think this approach handles Dave's port problems quite fine, but if
you are unhappy with it, then we can put our thinking caps back on.

Regards,
Loren

Index: acconfig.h
===================================================================
RCS file: /cvs/gcc/egcs/libstdc++-v3/acconfig.h,v
retrieving revision 1.17
diff -c -r1.17 acconfig.h
*** acconfig.h	2001/04/26 02:23:51	1.17
--- acconfig.h	2001/05/24 12:36:24
***************
*** 1,13 ****
  // acconfig.h symbols and macros for libstdc++ v3 -*- C++ -*-
  
  // Define if GCC support for __complex__ float is buggy.
  #undef _GLIBCPP_BUGGY_FLOAT_COMPLEX
  
  // Define if GCC support for __complex__ is buggy.
  #undef _GLIBCPP_BUGGY_COMPLEX
- 
- // Include support for multiple threads, e.g., in the I/O package.
- #undef _GLIBCPP_USE_THREADS
  
  // Include support for 'long long' and 'unsigned long long'.
  #undef _GLIBCPP_USE_LONG_LONG
--- 1,16 ----
  // acconfig.h symbols and macros for libstdc++ v3 -*- C++ -*-
  
+ // Define if GCC supports weak symbols
+ #undef SUPPORTS_WEAK
+ 
+ // Define if gthr-default.h exists
+ #undef HAVE_GTHR_DEFAULT
+ 
  // Define if GCC support for __complex__ float is buggy.
  #undef _GLIBCPP_BUGGY_FLOAT_COMPLEX
  
  // Define if GCC support for __complex__ is buggy.
  #undef _GLIBCPP_BUGGY_COMPLEX
  
  // Include support for 'long long' and 'unsigned long long'.
  #undef _GLIBCPP_USE_LONG_LONG
Index: acinclude.m4
===================================================================
RCS file: /cvs/gcc/egcs/libstdc++-v3/acinclude.m4,v
retrieving revision 1.147
diff -c -r1.147 acinclude.m4
*** acinclude.m4	2001/05/19 20:27:34	1.147
--- acinclude.m4	2001/05/24 12:19:04
***************
*** 1187,1226 ****
  
  
  dnl
! dnl Check for which threading library to use.
  dnl
- dnl GLIBCPP_ENABLE_THREADS
- dnl --enable-threads=posix sets config/threads-posix.h et. al.
- dnl 
- dnl Default is no threads, which also disables _IO_MTSAFE_IO in
- dnl libio.  Any actual thread package will enable it.
- dnl
  AC_DEFUN(GLIBCPP_ENABLE_THREADS, [
    AC_MSG_CHECKING([for thread model used by GCC])
    target_thread_file=`$CC -v 2>&1 | sed -n 's/^Thread model: //p'`
    AC_MSG_RESULT([$target_thread_file])
- 
-   dnl Check for thread package actually supported in libstdc++ 
-   THREADH=
-   case "$target_thread_file" in
-     no | none | single)
-       THREADH=threads-no.h
-       ;;
-     posix | pthreads)
-       THREADH=threads-posix.h
-       ;;
-     decosf1 | irix | mach | os2 | solaris | win32 | dce | vxworks)
-       AC_MSG_WARN(disabling unsupported thread package $target_thread_file)
-       THREADH=threads-no.h
-       ;;
-     *)
-       AC_MSG_ERROR($target_thread_file: unsupported/unknown thread package)
-       ;;
-   esac
  
!   AC_LINK_FILES(config/$THREADH, include/bits/c++threads.h)
!   if test $THREADH != threads-no.h; then
!     AC_DEFINE(_GLIBCPP_USE_THREADS)
    fi
  ])
  
--- 1187,1214 ----
  
  
  dnl
! dnl Link to the gcc gthr.h threading model.  We must stage the required
! dnl headers so they will get installed with the library.  We currently
! dnl inject three additional user space macro names: HAVE_GTHR_DEFAULT,
! dnl SUPPORTS_WEAK and GTHREAD_USE_WEAK (plus all of <pthread.h> in the
! dnl common case of pthreads support but that violation was already present).
  dnl
  AC_DEFUN(GLIBCPP_ENABLE_THREADS, [
    AC_MSG_CHECKING([for thread model used by GCC])
    target_thread_file=`$CC -v 2>&1 | sed -n 's/^Thread model: //p'`
    AC_MSG_RESULT([$target_thread_file])
  
!   AC_LINK_FILES(../gcc/gthr.h, include/bits/gthr.h)
!   AC_LINK_FILES(../gcc/gthr-posix.h, include/bits/gthr-posix.h)
!   AC_LINK_FILES(../gcc/gthr-dce.h, include/bits/gthr-dce.h)
!   AC_LINK_FILES(../gcc/gthr-solaris.h, include/bits/gthr-solaris.h)
!   AC_LINK_FILES(../gcc/gthr-single.h, include/bits/gthr-single.h)
!   if test $target_thread_file != single; then
!     AC_DEFINE(HAVE_GTHR_DEFAULT)
!     AC_DEFINE(SUPPORTS_WEAK, __GXX_WEAK__)
!     mkdir -p include/bits
!     echo >include/bits/gthr-default.h '#include "gthr-'$target_thread_file'.h"'
!     AC_LINK_FILES(../gcc/gthr-$target_thread_file.h, include/bits/gthr-$target_thread_file.h)
    fi
  ])
  
Index: mkc++config
===================================================================
RCS file: /cvs/gcc/egcs/libstdc++-v3/mkc++config,v
retrieving revision 1.4
diff -c -r1.4 mkc++config
*** mkc++config	2000/10/29 22:32:29	1.4
--- mkc++config	2001/05/24 12:19:04
***************
*** 43,54 ****
  sed 's/PACKAGE/_GLIBCPP_PACKAGE/g' < temp-1 > temp-2
  sed 's/VERSION/_GLIBCPP_VERSION/g' < temp-2 > temp-3
  sed 's/WORDS_/_GLIBCPP_WORDS_/g' < temp-3 > temp-4
  
  
  # Part 2
  # cat this into generated bits/c++config.h
! cat $BASE_H temp-4 > $OUT_H
! rm temp-1 temp-2 temp-3 temp-4
  
  
  # Part 3
--- 43,56 ----
  sed 's/PACKAGE/_GLIBCPP_PACKAGE/g' < temp-1 > temp-2
  sed 's/VERSION/_GLIBCPP_VERSION/g' < temp-2 > temp-3
  sed 's/WORDS_/_GLIBCPP_WORDS_/g' < temp-3 > temp-4
+ # Until better solution is available, we have to undo one safe macro name:
+ sed 's/_GLIBCPP_HAVE_GTHR_DEFAULT/HAVE_GTHR_DEFAULT/g' < temp-4 > temp-5
  
  
  # Part 2
  # cat this into generated bits/c++config.h
! cat $BASE_H temp-5 > $OUT_H
! rm temp-1 temp-2 temp-3 temp-4 temp-5
  
  
  # Part 3
Index: config/c_io_stdio.h
===================================================================
RCS file: /cvs/gcc/egcs/libstdc++-v3/config/c_io_stdio.h,v
retrieving revision 1.8
diff -c -r1.8 c_io_stdio.h
*** c_io_stdio.h	2001/03/07 22:22:41	1.8
--- c_io_stdio.h	2001/05/24 12:19:04
***************
*** 34,40 ****
  
  #include <stdio.h>
  #include <stddef.h>
! #include <bits/c++threads.h>
  
  namespace std 
  {
--- 34,40 ----
  
  #include <stdio.h>
  #include <stddef.h>
! #include <bits/gthr.h>
  
  namespace std 
  {
***************
*** 46,57 ****
  #endif
    typedef fpos_t  	__c_streampos;
  
! #ifdef _GLIBCPP_USE_THREADS
!   typedef __mutext_type __c_lock;
! #else
!   typedef int          	__c_lock;
! 
! #endif
  
  // from basic_file.h
  #define _GLIBCPP_BASIC_FILE_ENCAPSULATION 1
--- 46,52 ----
  #endif
    typedef fpos_t  	__c_streampos;
  
!   typedef __gthread_mutex_t __c_lock;
  
  // from basic_file.h
  #define _GLIBCPP_BASIC_FILE_ENCAPSULATION 1
Index: include/bits/c++config
===================================================================
RCS file: /cvs/gcc/egcs/libstdc++-v3/include/bits/c++config,v
retrieving revision 1.22
diff -c -r1.22 c++config
*** c++config	2001/05/18 07:24:24	1.22
--- c++config	2001/05/24 12:19:04
***************
*** 62,83 ****
  // Enable concept checking code from the boost libraries.
  //#define _GLIBCPP_CONCEPT_CHECKS 1
  
! // From SGI's stl_config.h; generic settings and user hooks (_NOTHREADS).
! #ifdef _REENTRANT
  # define __STL_THREADS
- #endif
- 
- #if defined(_PTHREADS) && !defined(_NOTHREADS)
- # define __STL_PTHREADS
- #endif
- 
- #if defined(_UITHREADS) && !defined(_PTHREADS) && !defined(_NOTHREADS)
- # define __STL_UITHREADS
- #endif
- 
- #if defined(__STL_WIN32THREADS) || defined(__STL_SGI_THREADS) \
-     || defined(__STL_PTHREADS)  || defined(__STL_UITHREADS)
- # define __STL_THREADS
  # define __STL_VOLATILE volatile
  #else
  # define __STL_VOLATILE
--- 62,76 ----
  // Enable concept checking code from the boost libraries.
  //#define _GLIBCPP_CONCEPT_CHECKS 1
  
! // Map gthr.h abstraction to that required for STL.  Do not key off of
! // __GTHREADS at this point since we haven't seen the correct symbol
! // yet, instead setup so that include/bits/stl_threads.h will know to
! // include gthr.h instead of any other type of thread support.  Note:
! // that gthr.h may well map to gthr-single.h which is a correct way
! // to express no threads support in gcc.
! #if !defined(_NOTHREADS)
! # define __STL_GTHREADS
  # define __STL_THREADS
  # define __STL_VOLATILE volatile
  #else
  # define __STL_VOLATILE
***************
*** 100,109 ****
  # define __STL_NOTHROW 
  # define __STL_UNWIND(action) 
  #endif
  
! // This is the "underlying allocator" for STL.  The alternatives are
! // homegrown schemes involving a kind of mutex and free list; see stl_alloc.h.
! #define __USE_MALLOC
  
  // The remainder of the prewritten config is mostly automatic; all the
  // user hooks are listed above.
--- 93,120 ----
  # define __STL_NOTHROW 
  # define __STL_UNWIND(action) 
  #endif
+ 
+ // Default to the typically higher-speed libstdc++-v2 configuration.
+ // To debug STL code or to gain better performance in some threading
+ // cases on some platforms, uncomment this line to globally change
+ // behavior of your application code (this will require, at the very
+ // least, recompilation of your entire application and, perhaps, the
+ // entire libstdc++ library):
+ //
+ // #define __USE_MALLOC
  
! // However, once you define __USE_MALLOC, only the malloc allocator is
! // visible to application code (i.e. the typically higher-speed
! // allocator is not even available in this configuration).  Note that
! // it is possible to force the malloc-based allocator on a
! // per-case-basis for some application code even when the above macro
! // symbol is not defined.  The author of this comment believes that is
! // a better way to tune an application for high-speed using this
! // implementation of the STL.  Here is one possible example displaying
! // the forcing of the malloc-based allocator over the typically
! // higher-speed default allocator:
! //
! // std::list <void*, std::malloc_alloc>
  
  // The remainder of the prewritten config is mostly automatic; all the
  // user hooks are listed above.
Index: include/bits/std_fstream.h
===================================================================
RCS file: /cvs/gcc/egcs/libstdc++-v3/include/bits/std_fstream.h,v
retrieving revision 1.9
diff -c -r1.9 std_fstream.h
*** std_fstream.h	2001/05/22 18:48:19	1.9
--- std_fstream.h	2001/05/24 12:19:04
***************
*** 40,46 ****
  #include <bits/std_ostream.h>
  #include <bits/basic_file.h>
  #include <bits/std_locale.h>	// For codecvt
! #include <bits/c++threads.h>	// For __mutext_type
  
  namespace std 
  {
--- 40,46 ----
  #include <bits/std_ostream.h>
  #include <bits/basic_file.h>
  #include <bits/std_locale.h>	// For codecvt
! #include <bits/gthr.h>
  
  namespace std 
  {
Index: include/bits/stl_threads.h
===================================================================
RCS file: /cvs/gcc/egcs/libstdc++-v3/include/bits/stl_threads.h,v
retrieving revision 1.3
diff -c -r1.3 stl_threads.h
*** stl_threads.h	2001/03/04 21:34:01	1.3
--- stl_threads.h	2001/05/24 12:19:04
***************
*** 29,34 ****
--- 29,38 ----
  #include <time.h>
  #elif defined(__STL_PTHREADS)
  #include <pthread.h>
+ // GCC extension begin
+ #elif defined(__STL_GTHREADS)
+ #include "bits/gthr.h"
+ // GCC extension end
  #elif defined(__STL_UITHREADS)
  #include <thread.h>
  #include <synch.h>
Index: libsupc++/eh_alloc.cc
===================================================================
RCS file: /cvs/gcc/egcs/libstdc++-v3/libsupc++/eh_alloc.cc,v
retrieving revision 1.2
diff -c -r1.2 eh_alloc.cc
*** eh_alloc.cc	2001/04/12 07:47:34	1.2
--- eh_alloc.cc	2001/05/24 12:19:05
***************
*** 35,41 ****
  #include <cstring>
  #include <limits.h>
  #include "unwind-cxx.h"
! #include "gthr.h"
  
  using namespace __cxxabiv1;
  
--- 35,42 ----
  #include <cstring>
  #include <limits.h>
  #include "unwind-cxx.h"
! #include "bits/c++config.h"
! #include "bits/gthr.h"
  
  using namespace __cxxabiv1;
  
Index: libsupc++/eh_globals.cc
===================================================================
RCS file: /cvs/gcc/egcs/libstdc++-v3/libsupc++/eh_globals.cc,v
retrieving revision 1.1
diff -c -r1.1 eh_globals.cc
*** eh_globals.cc	2001/03/28 11:04:50	1.1
--- eh_globals.cc	2001/05/24 12:19:05
***************
*** 29,36 ****
  
  
  #include <exception>
  #include "unwind-cxx.h"
! #include "gthr.h"
  
  using namespace __cxxabiv1;
  
--- 29,38 ----
  
  
  #include <exception>
+ #include <cstdlib>
  #include "unwind-cxx.h"
! #include "bits/c++config.h"
! #include "bits/gthr.h"
  
  using namespace __cxxabiv1;
  
***************
*** 95,113 ****
    g = (__cxa_eh_globals *) __gthread_getspecific (globals_key);
    if (! g)
      {
!       static __gthread_once_t once = __GTHREAD_ONCE_INIT;
! 
!       // Make sure use_thread_key got initialized.  Some systems have
!       // dummy thread routines in their libc that return a success.
!       if (__gthread_once (&once, eh_threads_initialize) != 0
! 	  || use_thread_key < 0)
  	{
  	  use_thread_key = 0;
  	  return &globals_static;
  	}
        
!       if ((g = malloc (sizeof (__cxa_eh_globals))) == 0
! 	  || __gthread_setspecific (eh_context_key, (void *) g) != 0)
          std::terminate ();
        g->caughtExceptions = 0;
        g->uncaughtExceptions = 0;
--- 97,111 ----
    g = (__cxa_eh_globals *) __gthread_getspecific (globals_key);
    if (! g)
      {
!       // Make sure use_thread_key got initialized.
!       if (use_thread_key < 0)
  	{
  	  use_thread_key = 0;
  	  return &globals_static;
  	}
        
!       if ((g = (__cxa_eh_globals *) std::malloc (sizeof (__cxa_eh_globals))) == 0
! 	  || __gthread_setspecific (globals_key, (void *) g) != 0)
          std::terminate ();
        g->caughtExceptions = 0;
        g->uncaughtExceptions = 0;


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