aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn David Anglin <dave@hiauly1.hia.nrc.ca>2001-06-14 06:06:48 +0000
committerLoren J. Rittle <ljrittle@gcc.gnu.org>2001-06-14 06:06:48 +0000
commit91bfd02daeabbe18216560b47d54919c98bcce36 (patch)
tree69f64e107f81355dfa627981137133c327e6cdf0
parent5ffd49b80090449894c03b350d2279d97d535de5 (diff)
downloadgcc-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/ChangeLog13
-rw-r--r--libstdc++-v3/include/bits/stl_threads.h60
-rw-r--r--libstdc++-v3/src/globals.cc29
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
}