aboutsummaryrefslogtreecommitdiff
path: root/libstdc++-v3
diff options
context:
space:
mode:
authorBenjamin Kosnik <bkoz@redhat.com>2004-03-07 01:32:43 +0000
committerBenjamin Kosnik <bkoz@gcc.gnu.org>2004-03-07 01:32:43 +0000
commitf83295bafc73a70666d5d67e05918b0e6882402c (patch)
treef71f116f1f9678557e7764415bf032ec269eadcf /libstdc++-v3
parent018e1b3b0b15655000518abaeca2c86c8fadf8a6 (diff)
downloadgcc-f83295bafc73a70666d5d67e05918b0e6882402c.zip
gcc-f83295bafc73a70666d5d67e05918b0e6882402c.tar.gz
gcc-f83295bafc73a70666d5d67e05918b0e6882402c.tar.bz2
re PR libstdc++/12658 (Thread safety problems in locale::global() and locale::locale())
2004-03-06 Benjamin Kosnik <bkoz@redhat.com> PR libstdc++/12658 * src/locale_init.cc (locale::locale): Lock critical regions with external mutexes. (locale::global): Same. * include/bits/concurrence.h (__glibcxx_mutex_define_initialized): Add in once bits for cases without __GTHREAD_MUTEX_INIT. (__glibcxx_mutex_lock): Same. * config/cpu/generic/atomicity.h: Remove _GLIBCXX_NEED_GENERIC_MUTEX, use concurrence.h. * src/misc-inst.cc: Move all locking bits out of this file. * config/os/hpux/os_defines.h: Remove _GLIBCXX_INST_ATOMICITY_LOCK. * src/misc-inst.cc: Same. * config/cpu/hppa/atomicity.h: Same. * config/linker-map.gnu: Remove types in the signature of atomic exports, as they may vary. From-SVN: r79043
Diffstat (limited to 'libstdc++-v3')
-rw-r--r--libstdc++-v3/ChangeLog21
-rw-r--r--libstdc++-v3/config/cpu/generic/atomicity.h24
-rw-r--r--libstdc++-v3/config/cpu/hppa/atomicity.h5
-rw-r--r--libstdc++-v3/config/linker-map.gnu4
-rw-r--r--libstdc++-v3/config/os/hpux/os_defines.h6
-rw-r--r--libstdc++-v3/include/bits/concurrence.h27
-rw-r--r--libstdc++-v3/include/ext/mt_allocator.h18
-rw-r--r--libstdc++-v3/src/locale_init.cc8
-rw-r--r--libstdc++-v3/src/misc-inst.cc18
9 files changed, 67 insertions, 64 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index e146e48..2f36a46 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,3 +1,24 @@
+2004-03-06 Benjamin Kosnik <bkoz@redhat.com>
+
+ PR libstdc++/12658
+ * src/locale_init.cc (locale::locale): Lock critical regions with
+ external mutexes.
+ (locale::global): Same.
+ * include/bits/concurrence.h (__glibcxx_mutex_define_initialized):
+ Add in once bits for cases without __GTHREAD_MUTEX_INIT.
+ (__glibcxx_mutex_lock): Same.
+
+ * config/cpu/generic/atomicity.h: Remove
+ _GLIBCXX_NEED_GENERIC_MUTEX, use concurrence.h.
+ * src/misc-inst.cc: Move all locking bits out of this file.
+
+ * config/os/hpux/os_defines.h: Remove _GLIBCXX_INST_ATOMICITY_LOCK.
+ * src/misc-inst.cc: Same.
+ * config/cpu/hppa/atomicity.h: Same.
+
+ * config/linker-map.gnu: Remove types in the signature of atomic
+ exports, as they may vary.
+
2004-03-06 Paolo Carlini <pcarlini@suse.de>
* include/bits/locale_facets.tcc: Tweak the comment preceding
diff --git a/libstdc++-v3/config/cpu/generic/atomicity.h b/libstdc++-v3/config/cpu/generic/atomicity.h
index 8481790..f30005a 100644
--- a/libstdc++-v3/config/cpu/generic/atomicity.h
+++ b/libstdc++-v3/config/cpu/generic/atomicity.h
@@ -28,34 +28,24 @@
// the GNU General Public License.
#include <bits/atomicity.h>
-#include <bits/gthr.h>
+#include <bits/concurrence.h>
-#define _GLIBCXX_NEED_GENERIC_MUTEX
+namespace __gnu_internal
+{
+ __glibcxx_mutex_define_initialized(atomic_mutex);
+} // namespace __gnu_internal
namespace __gnu_cxx
{
- extern __gthread_mutex_t _Atomic_add_mutex;
-
-#ifndef __GTHREAD_MUTEX_INIT
- extern __gthread_once_t _Atomic_add_mutex_once;
- extern void __gthread_atomic_add_mutex_once();
-#endif
-
_Atomic_word
__attribute__ ((__unused__))
__exchange_and_add(volatile _Atomic_word* __mem, int __val)
{
-#ifndef __GTHREAD_MUTEX_INIT
- __gthread_once(&__gnu_cxx::_Atomic_add_mutex_once,
- __gnu_cxx::__gthread_atomic_add_mutex_once);
-#endif
-
+ __glibcxx_mutex_lock(__gnu_internal::atomic_mutex);
_Atomic_word __result;
- __gthread_mutex_lock(&__gnu_cxx::_Atomic_add_mutex);
__result = *__mem;
*__mem += __val;
-
- __gthread_mutex_unlock(&__gnu_cxx::_Atomic_add_mutex);
+ __glibcxx_mutex_unlock(__gnu_internal::atomic_mutex);
return __result;
}
diff --git a/libstdc++-v3/config/cpu/hppa/atomicity.h b/libstdc++-v3/config/cpu/hppa/atomicity.h
index d173976..48c8283 100644
--- a/libstdc++-v3/config/cpu/hppa/atomicity.h
+++ b/libstdc++-v3/config/cpu/hppa/atomicity.h
@@ -43,11 +43,8 @@ namespace __gnu_cxx
_Atomicity_lock<_Inst>::_S_atomicity_lock __attribute__ ((aligned (16))) = 1;
// Because of the lack of weak support when using the hpux som
- // linker, we explicitly instantiate the atomicity lock in
- // src/misc-inst.cc when _GLIBCXX_INST_ATOMICITY_LOCK is defined.
-#ifndef _GLIBCXX_INST_ATOMICITY_LOCK
+ // linker, we explicitly instantiate the atomicity lock.
template volatile int _Atomicity_lock<0>::_S_atomicity_lock;
-#endif
int
__attribute__ ((__unused__))
diff --git a/libstdc++-v3/config/linker-map.gnu b/libstdc++-v3/config/linker-map.gnu
index c8be242..7dd9a2a 100644
--- a/libstdc++-v3/config/linker-map.gnu
+++ b/libstdc++-v3/config/linker-map.gnu
@@ -216,8 +216,8 @@ GLIBCXX_3.4 {
# __gnu_cxx::__atomic_add
# __gnu_cxx::__exchange_and_add
- _ZN9__gnu_cxx12__atomic_addEPVii;
- _ZN9__gnu_cxx18__exchange_and_addEPVii;
+ _ZN9__gnu_cxx12__atomic_add*;
+ _ZN9__gnu_cxx18__exchange_and_add*;
# DO NOT DELETE THIS LINE. Port-specific symbols, if any, will be here.
diff --git a/libstdc++-v3/config/os/hpux/os_defines.h b/libstdc++-v3/config/os/hpux/os_defines.h
index 64962fe..6cba739 100644
--- a/libstdc++-v3/config/os/hpux/os_defines.h
+++ b/libstdc++-v3/config/os/hpux/os_defines.h
@@ -91,12 +91,6 @@ typedef long int __padding_type;
#define _LIBUNWIND_STD_ABI 1
#endif
-/* We need explicit instantiation of the atomicity lock on HPPA if
- there is no weak support. */
-#if !__GXX_WEAK__ && defined (__hppa__)
-#define _GLIBCXX_INST_ATOMICITY_LOCK 1
-#endif
-
/* Don't use pragma weak in gthread headers. HP-UX rejects programs
with unsatisfied external references even if all of those references
are weak; gthread relies on such unsatisfied references being resolved
diff --git a/libstdc++-v3/include/bits/concurrence.h b/libstdc++-v3/include/bits/concurrence.h
index fe67881..ea99e56 100644
--- a/libstdc++-v3/include/bits/concurrence.h
+++ b/libstdc++-v3/include/bits/concurrence.h
@@ -1,6 +1,6 @@
// Support for concurrent programing -*- C++ -*-
-// Copyright (C) 2003
+// Copyright (C) 2003, 2004
// Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
@@ -28,27 +28,38 @@
// invalidate any other reasons why the executable file might be covered by
// the GNU General Public License.
-#ifndef _CONCURRENCE
-#define _CONCURRENCE 1
+#ifndef _CONCURRENCE_H
+#define _CONCURRENCE_H 1
// GCC's thread abstraction layer
#include "bits/gthr.h"
#if __GTHREADS
+
# ifdef __GTHREAD_MUTEX_INIT
# define __glibcxx_mutex_define_initialized(NAME) \
__gthread_mutex_t NAME = __GTHREAD_MUTEX_INIT
+# define __glibcxx_mutex_lock(NAME) \
+__gthread_mutex_lock(&NAME)
# else
+// Implies __GTHREAD_MUTEX_INIT_FUNCTION
# define __glibcxx_mutex_define_initialized(NAME) \
__gthread_mutex_t NAME; \
-__GTHREAD_MUTEX_INIT_FUNCTION(&NAME)
+__gthread_once_t NAME ## _once = __GTHREAD_ONCE_INIT; \
+void NAME ## _init() { __GTHREAD_MUTEX_INIT_FUNCTION(&NAME); }
+# define __glibcxx_mutex_lock(NAME) \
+__gthread_once(&NAME ## _once, NAME ## _init); \
+__gthread_mutex_lock(&NAME)
# endif
-# define __glibcxx_mutex_lock(LOCK) __gthread_mutex_lock(&LOCK)
-# define __glibcxx_mutex_unlock(LOCK) __gthread_mutex_unlock(&LOCK)
+
+# define __glibcxx_mutex_unlock(NAME) __gthread_mutex_unlock(&NAME)
+
#else
+
# define __glibcxx_mutex_define_initialized(NAME)
-# define __glibcxx_mutex_lock(LOCK)
-# define __glibcxx_mutex_unlock(LOCK)
+# define __glibcxx_mutex_lock(NAME)
+# define __glibcxx_mutex_unlock(NAME)
+
#endif
#endif
diff --git a/libstdc++-v3/include/ext/mt_allocator.h b/libstdc++-v3/include/ext/mt_allocator.h
index 7000c05..1bcff03 100644
--- a/libstdc++-v3/include/ext/mt_allocator.h
+++ b/libstdc++-v3/include/ext/mt_allocator.h
@@ -559,8 +559,8 @@ namespace __gnu_cxx
}
// Setup the bin map for quick lookup of the relevant bin.
- _S_binmap = (binmap_type*)
- ::operator new ((_S_options._M_max_bytes + 1) * sizeof(binmap_type));
+ const size_t n1 = (_S_options._M_max_bytes + 1) * sizeof(binmap_type);
+ _S_binmap = static_cast<binmap_type*>(::operator new(n1));
binmap_type* bp_t = _S_binmap;
binmap_type bin_max_t = 1;
@@ -581,9 +581,8 @@ namespace __gnu_cxx
#ifdef __GTHREADS
if (__gthread_active_p())
{
- _S_thread_freelist_first =
- static_cast<thread_record*>(::operator
- new(sizeof(thread_record) * _S_options._M_max_threads));
+ const size_t n2 = sizeof(thread_record) * _S_options._M_max_threads;
+ _S_thread_freelist_first = static_cast<thread_record*>(::operator new(n2));
// NOTE! The first assignable thread id is 1 since the
// global pool uses id 0
@@ -637,7 +636,7 @@ namespace __gnu_cxx
*br.mutex = __tmp;
}
#else
- { __GTHREAD_MUTEX_INIT_FUNCTION (br.mutex); }
+ { __GTHREAD_MUTEX_INIT_FUNCTION(br.mutex); }
#endif
}
#endif
@@ -741,12 +740,13 @@ namespace __gnu_cxx
template<typename _Tp>
__gthread_key_t __mt_alloc<_Tp>::_S_thread_key;
- template<typename _Tp> __gthread_mutex_t
+ template<typename _Tp>
+ __gthread_mutex_t
#ifdef __GTHREAD_MUTEX_INIT
- __mt_alloc<_Tp>::_S_thread_freelist_mutex = __GTHREAD_MUTEX_INIT;
+ __mt_alloc<_Tp>::_S_thread_freelist_mutex = __GTHREAD_MUTEX_INIT;
#else
// XXX
- __mt_alloc<_Tp>::_S_thread_freelist_mutex;
+ __mt_alloc<_Tp>::_S_thread_freelist_mutex;
#endif
#endif
} // namespace __gnu_cxx
diff --git a/libstdc++-v3/src/locale_init.cc b/libstdc++-v3/src/locale_init.cc
index 78f91d2..c1dac9f 100644
--- a/libstdc++-v3/src/locale_init.cc
+++ b/libstdc++-v3/src/locale_init.cc
@@ -88,6 +88,10 @@ namespace __gnu_internal
extern std::__moneypunct_cache<wchar_t, true> moneypunct_cache_wt;
extern std::__timepunct_cache<wchar_t> timepunct_cache_w;
#endif
+
+ // Mutex objects for locale initialization.
+ __glibcxx_mutex_define_initialized(locale_cons_mutex);
+ __glibcxx_mutex_define_initialized(locale_global_mutex);
} // namespace __gnu_internal
namespace std
@@ -97,19 +101,23 @@ namespace std
locale::locale() throw()
{
_S_initialize();
+ __glibcxx_mutex_lock(__gnu_internal::locale_cons_mutex);
_S_global->_M_add_reference();
_M_impl = _S_global;
+ __glibcxx_mutex_unlock(__gnu_internal::locale_cons_mutex);
}
locale
locale::global(const locale& __other)
{
_S_initialize();
+ __glibcxx_mutex_lock(__gnu_internal::locale_global_mutex);
_Impl* __old = _S_global;
__other._M_impl->_M_add_reference();
_S_global = __other._M_impl;
if (__other.name() != "*")
setlocale(LC_ALL, __other.name().c_str());
+ __glibcxx_mutex_unlock(__gnu_internal::locale_global_mutex);
// Reference count sanity check: one reference removed for the
// subsition of __other locale, one added by return-by-value. Net
diff --git a/libstdc++-v3/src/misc-inst.cc b/libstdc++-v3/src/misc-inst.cc
index c449652..b9bc298 100644
--- a/libstdc++-v3/src/misc-inst.cc
+++ b/libstdc++-v3/src/misc-inst.cc
@@ -73,24 +73,6 @@ namespace std
namespace __gnu_cxx
{
-#ifdef _GLIBCXX_INST_ATOMICITY_LOCK
- template volatile int _Atomicity_lock<0>::_S_atomicity_lock;
-#endif
-
-#ifdef _GLIBCXX_NEED_GENERIC_MUTEX
-#ifdef __GTHREAD_MUTEX_INIT
- __gthread_mutex_t _Atomic_add_mutex = __GTHREAD_MUTEX_INIT;
-#else
- // generic atomicity.h without static initialization
- __gthread_mutex_t _Atomic_add_mutex;
- __gthread_once_t _Atomic_add_mutex_once = __GTHREAD_ONCE_INIT;
- void __gthread_atomic_add_mutex_once()
- {
- __GTHREAD_MUTEX_INIT_FUNCTION (&_Atomic_add_mutex);
- }
-#endif
-#endif // _GLIBCXX_NEED_GLOBAL_MUTEX
-
template class stdio_sync_filebuf<char>;
#ifdef _GLIBCXX_USE_WCHAR_T
template class stdio_sync_filebuf<wchar_t>;