Commit 91bfd02d by John David Anglin Committed by Loren J. Rittle

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
parent 5ffd49b8
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.
......
......@@ -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
......
......@@ -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
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment