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]

Re: PATCH: Provide runtime intialization of _STL_mutex_lock class (revised)



Assuming loren has no objections, and there are no regression with it,  
it's ok with me for both trunk and branch. I'd prefer if no warnings were 
issued, and the slight tweaks to gthr were made.

Let's see what Loren says, if ok then you'll need to resubmitt and cc 
Mark, with some kind of summary of the issues covered by this patch. 
(You've done this in the past, but just package it all in one email so 
that Mark can easily see what the deal is.)

Thanks again.
benjamin

> I have updated the patch to hopefully address your concerns and Loren's.
> 
> > 1) why are you adding this to libsupc++? it should be added to 
> > src/Makefile.am
> > 
> > 2) there is already a src/globals.cc -- why can't you use that?
> 
> 1) Global code moved to src/globals.cc.
> 
> > 3) In general, the naming seems a bit off. stl_globals, yet the patch is 
> > for threads and mutexes.... also we're trying to go away from _STL bits and 
> > towad _GLIBCPP_ bits in names. 
> 
> 2) Global names changed.
> 
> 3) _GTHREAD_MUTEX_INIT selected in preference to _GTHREAD_MUTEX_INIT_FUNCTION.
> 
> 4) Added an additional call to __gthread_once after the global lock has been
>    obtained to try to further ensure that the initialization of _M_lock works
>    correctly on multiprocessor systems.
> 
> There is one minor issue.  A warning occurs in the compilation of stl-inst.cc
> because only a partial inilization of the _STL_mutex_lock struct is done.
> This could be fixed if the gthr.h thread idiom were augmented to provide
> a default mutex initializer for the __gthread_mutex_t type for use when
> __GTHREAD_MUTEX_INIT_FUNCTION is defined.
> 
> I have tested this under i686 linux and hpux 10.20.  Under linux, I have
> checked both the __GTHREAD_MUTEX_INIT and __GTHREAD_MUTEX_INIT_FUNCTION.
> I don't see any regressions.  The only v3 errors that I see are 
> 
> FAIL: 21_strings/insert.cc execution test
> FAIL: 27_io/ios_members.cc execution test
> 
> for unix/-static.
> 
> How about it?
> 
> Dave
> -- 
> J. David Anglin                                  dave.anglin@nrc.ca
> National Research Council of Canada              (613) 990-0752 (FAX: 952-6605)
> 
> 2001-06-12  John David Anglin  <dave@hiauly1.hia.nrc.ca>
> 
> 	* src/globals.cc: Define globals _GLIBCPP_mutex_init (),
> 	_GLIBCPP_mutex_address_init (), _GLIBCPP_once, _GLIBCPP_mutex
> 	and _GLIBCPP_mutex_address.
> 	* include/bits/stl_threads.h (_STL_mutex_lock): Use above to provide
> 	once-only runtime initialization of _M_lock mutex when
> 	__GTHREAD_MUTEX_INIT_FUNCTION is defined.
> 
> --- src/globals.cc.orig	Wed Jun  6 14:13:01 2001
> +++ src/globals.cc	Mon Jun 11 16:53:03 2001
> @@ -25,6 +25,8 @@
>  // invalidate any other reasons why the executable file might be covered by
>  // the GNU General Public License.
>  
> +#include "bits/c++config.h"
> +#include "bits/gthr.h"
>  #include <fstream>
>  #include <istream>
>  #include <ostream>
> @@ -73,4 +74,31 @@
>    fake_wfilebuf buf_wcin;
>    fake_wfilebuf buf_wcerr;
>  #endif
> +
> +// Globals for once-only runtime initialization of mutex objects.  This
> +// allows static initialization of these objects on systems that need a
> +// function call to initialize a mutex.  For example, see stl_threads.h.
> +#if __GTHREADS
> +#ifdef __GTHREAD_MUTEX_INIT
> +// This path is not needed since static initialization of mutexs works
> +// on this platform.
> +#elif defined(__GTHREAD_MUTEX_INIT_FUNCTION)
> +__gthread_once_t _GLIBCPP_once = __GTHREAD_ONCE_INIT;
> +__gthread_mutex_t _GLIBCPP_mutex;
> +__gthread_mutex_t *_GLIBCPP_mutex_address;
> +
> +// Once-only initializer function for _GLIBCPP_mutex.  
> +void
> +_GLIBCPP_mutex_init ()
> +{
> +  __GTHREAD_MUTEX_INIT_FUNCTION (&_GLIBCPP_mutex);
> +}
> +// Once-only initializer function for _GLIBCPP_mutex_address.  
> +void
> +_GLIBCPP_mutex_address_init ()
> +{
> +  __GTHREAD_MUTEX_INIT_FUNCTION (_GLIBCPP_mutex_address);
> +}
> +#endif
> +#endif
>  }
> --- include/bits/stl_threads.h.orig	Fri Jun  8 18:44:50 2001
> +++ include/bits/stl_threads.h	Mon Jun 11 17:42:03 2001
> @@ -296,21 +296,62 @@
>  template <int __inst>
>  unsigned _STL_mutex_spin<__inst>::__last = 0;
>  
> +// GCC extension begin
> +#if defined(__STL_GTHREADS)
> +#if !defined(__GTHREAD_MUTEX_INIT) && defined(__GTHREAD_MUTEX_INIT_FUNCTION)
> +extern __gthread_mutex_t _GLIBCPP_mutex;
> +extern __gthread_mutex_t *_GLIBCPP_mutex_address;
> +extern __gthread_once_t _GLIBCPP_once;
> +extern void _GLIBCPP_mutex_init (void);
> +extern void _GLIBCPP_mutex_address_init (void);
> +#endif
> +#endif
> +// GCC extension end
> +
>  struct _STL_mutex_lock
>  {
>  // GCC extension begin
>  #if defined(__STL_GTHREADS)
> +  // The class must be statically initialized with __STL_MUTEX_INITIALIZER.
> +#if !defined(__GTHREAD_MUTEX_INIT) && defined(__GTHREAD_MUTEX_INIT_FUNCTION)
> +  int _M_init_flag;
> +  __gthread_once_t _M_once;
> +#endif
>    __gthread_mutex_t _M_lock;
> -  void _M_initialize()
> -  {
> +  void _M_initialize() {
>  #ifdef __GTHREAD_MUTEX_INIT
> -  // There should be no code in this path given the usage rules above.
> +    // There should be no code in this path given the usage rules above.
>  #elif defined(__GTHREAD_MUTEX_INIT_FUNCTION)
> -    __GTHREAD_MUTEX_INIT_FUNCTION (&_M_lock);
> +    if (_M_init_flag) return;
> +    if (__gthread_once (&_GLIBCPP_once, _GLIBCPP_mutex_init) != 0
> +        && __gthread_active_p ())
> +      abort ();
> +    __gthread_mutex_lock (&_GLIBCPP_mutex);
> +    if (!_M_init_flag) {
> +	// Even though we have a global lock, we use __gthread_once to be
> +	// absolutely certain the _M_lock mutex is only initialized once on
> +	// multiprocessor systems.
> +	_GLIBCPP_mutex_address = &_M_lock;
> +	if (__gthread_once (&_M_once, _GLIBCPP_mutex_address_init) != 0
> +	    && __gthread_active_p ())
> +	  abort ();
> +	_M_init_flag = 1;
> +    }
> +    __gthread_mutex_unlock (&_GLIBCPP_mutex);
>  #endif
>    }
> -  void _M_acquire_lock() { __gthread_mutex_lock(&_M_lock); }
> -  void _M_release_lock() { __gthread_mutex_unlock(&_M_lock); }
> +  void _M_acquire_lock() {
> +#if !defined(__GTHREAD_MUTEX_INIT) && defined(__GTHREAD_MUTEX_INIT_FUNCTION)
> +    if (!_M_init_flag) _M_initialize();
> +#endif
> +    __gthread_mutex_lock(&_M_lock);
> +  }
> +  void _M_release_lock() {
> +#if !defined(__GTHREAD_MUTEX_INIT) && defined(__GTHREAD_MUTEX_INIT_FUNCTION)
> +    if (!_M_init_flag) _M_initialize();
> +#endif
> +    __gthread_mutex_unlock(&_M_lock);
> +  }
>  #else
>  // GCC extension end
>  #if defined(__STL_SGI_THREADS) || defined(__STL_WIN32THREADS)
> @@ -415,8 +456,8 @@
>  #if defined(__STL_GTHREADS)
>  #ifdef __GTHREAD_MUTEX_INIT
>  #define __STL_MUTEX_INITIALIZER = { __GTHREAD_MUTEX_INIT }
> -#else
> -#define __STL_MUTEX_INITIALIZER
> +#elif defined(__GTHREAD_MUTEX_INIT_FUNCTION)
> +#define __STL_MUTEX_INITIALIZER = { 0, __GTHREAD_ONCE_INIT }
>  #endif
>  #else
>  // GCC extension end
> 


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