diff options
author | John David Anglin <dave@hiauly1.hia.nrc.ca> | 2001-06-14 06:06:48 +0000 |
---|---|---|
committer | Loren J. Rittle <ljrittle@gcc.gnu.org> | 2001-06-14 06:06:48 +0000 |
commit | 91bfd02daeabbe18216560b47d54919c98bcce36 (patch) | |
tree | 69f64e107f81355dfa627981137133c327e6cdf0 | |
parent | 5ffd49b80090449894c03b350d2279d97d535de5 (diff) | |
download | gcc-91bfd02daeabbe18216560b47d54919c98bcce36.zip gcc-91bfd02daeabbe18216560b47d54919c98bcce36.tar.gz gcc-91bfd02daeabbe18216560b47d54919c98bcce36.tar.bz2 |
globals.cc: Define globals _GLIBCPP_mutex_init ()...
* 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.
(__STL_MUTEX_INITIALIZER): Provide initializer for _STL_mutex_lock
for __GTHREAD_MUTEX_INIT_FUNCTION case.
From-SVN: r43360
-rw-r--r-- | libstdc++-v3/ChangeLog | 13 | ||||
-rw-r--r-- | libstdc++-v3/include/bits/stl_threads.h | 60 | ||||
-rw-r--r-- | libstdc++-v3/src/globals.cc | 29 |
3 files changed, 95 insertions, 7 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 63eeb61..2cf5c70 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,16 @@ +2001-06-13 John David Anglin <dave@hiauly1.hia.nrc.ca> + + (Approved by Mark and Benjamin. Applied by Loren.) + + * 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. + (__STL_MUTEX_INITIALIZER): Provide initializer for _STL_mutex_lock + for __GTHREAD_MUTEX_INIT_FUNCTION case. + 2001-06-13 Gabriel Dos Reis <gdr@merlin.codesourcery.com> * testsuite/26_numerics/slice_array_assignment.cc (main): New test. diff --git a/libstdc++-v3/include/bits/stl_threads.h b/libstdc++-v3/include/bits/stl_threads.h index 21f4722..cdbf205 100644 --- a/libstdc++-v3/include/bits/stl_threads.h +++ b/libstdc++-v3/include/bits/stl_threads.h @@ -296,21 +296,62 @@ unsigned _STL_mutex_spin<__inst>::__max = _STL_mutex_spin<__inst>::__low_max; 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) + volatile 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,13 @@ struct _STL_mutex_lock #if defined(__STL_GTHREADS) #ifdef __GTHREAD_MUTEX_INIT #define __STL_MUTEX_INITIALIZER = { __GTHREAD_MUTEX_INIT } +#elif defined(__GTHREAD_MUTEX_INIT_FUNCTION) +#ifdef __GTHREAD_MUTEX_INIT_DEFAULT +#define __STL_MUTEX_INITIALIZER \ + = { 0, __GTHREAD_ONCE_INIT, __GTHREAD_MUTEX_INIT_DEFAULT } #else -#define __STL_MUTEX_INITIALIZER +#define __STL_MUTEX_INITIALIZER = { 0, __GTHREAD_ONCE_INIT } +#endif #endif #else // GCC extension end diff --git a/libstdc++-v3/src/globals.cc b/libstdc++-v3/src/globals.cc index 11930b0..d70cc29 100644 --- a/libstdc++-v3/src/globals.cc +++ b/libstdc++-v3/src/globals.cc @@ -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 +75,31 @@ namespace std 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 } |