From 46c8f2594a4d8f6f4a50127c727a8b4b18f7f626 Mon Sep 17 00:00:00 2001 From: ljrittle Date: Thu, 24 Jan 2002 21:14:41 +0000 Subject: [PATCH] libstdc++/5432 * include/bits/ios_base.h: Use _Atomic_word for reference counts. * include/bits/localefwd.h: Likewise. Also use for std::locale::id::_S_highwater. * src/ios.cc (ios_base::xalloc): Use _Atomic_word. * src/locale.cc: Support new usage of _Atomic_word. (std::locale::classic): Guard entire function against reentry. * src/localename.cc: Support new usage of _Atomic_word. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@49195 138bc75d-0d04-0410-961f-82ee72b054a4 --- libstdc++-v3/ChangeLog | 12 ++++++++++++ libstdc++-v3/include/bits/ios_base.h | 14 +++++++++----- libstdc++-v3/include/bits/localefwd.h | 12 +++++++----- libstdc++-v3/src/ios.cc | 12 ++++++++---- libstdc++-v3/src/locale.cc | 14 +++++++++----- libstdc++-v3/src/localename.cc | 2 +- 6 files changed, 46 insertions(+), 20 deletions(-) diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index e9e3282..5e849a4 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,15 @@ +2002-01-24 andrew@andypo.net + (tweaks, test and commit by Loren J. Rittle ) + + libstdc++/5432 + * include/bits/ios_base.h: Use _Atomic_word for reference counts. + * include/bits/localefwd.h: Likewise. + Also use for std::locale::id::_S_highwater. + * src/ios.cc (ios_base::xalloc): Use _Atomic_word. + * src/locale.cc: Support new usage of _Atomic_word. + (std::locale::classic): Guard entire function against reentry. + * src/localename.cc: Support new usage of _Atomic_word. + 2002-01-24 Benjamin Kosnik * testsuite/22_locale/num_put_members_wchar_t.cc (test03): Use diff --git a/libstdc++-v3/include/bits/ios_base.h b/libstdc++-v3/include/bits/ios_base.h index bf9fe69..7525e7d 100644 --- a/libstdc++-v3/include/bits/ios_base.h +++ b/libstdc++-v3/include/bits/ios_base.h @@ -1,6 +1,7 @@ // Iostreams base classes -*- C++ -*- -// Copyright (C) 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc. +// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 +// Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the @@ -41,6 +42,8 @@ #pragma GCC system_header +#include + namespace std { // The following definitions of bitmask types are enums, not ints, @@ -244,17 +247,18 @@ namespace std _Callback_list* _M_next; ios_base::event_callback _M_fn; int _M_index; - int _M_refcount; // 0 means one reference. + _Atomic_word _M_refcount; // 0 means one reference. _Callback_list(ios_base::event_callback __fn, int __index, _Callback_list* __cb) : _M_next(__cb), _M_fn(__fn), _M_index(__index), _M_refcount(0) { } void - _M_add_reference() { ++_M_refcount; } // XXX MT - + _M_add_reference() { __atomic_add(&_M_refcount, 1); } + int - _M_remove_reference() { return _M_refcount--; } // 0 => OK to delete + _M_remove_reference() { return __exchange_and_add(&_M_refcount, -1); } + // 0 => OK to delete }; _Callback_list* _M_callbacks; diff --git a/libstdc++-v3/include/bits/localefwd.h b/libstdc++-v3/include/bits/localefwd.h index be7f7e6..bcb60b7 100644 --- a/libstdc++-v3/include/bits/localefwd.h +++ b/libstdc++-v3/include/bits/localefwd.h @@ -49,6 +49,8 @@ #include // For string #include +#include + namespace std { // NB: Don't instantiate required wchar_t facets if no wchar_t support. @@ -317,7 +319,7 @@ namespace std private: // Data Members. - size_t _M_references; + _Atomic_word _M_references; __vec_facet* _M_facets; string _M_names[_S_num_categories]; static const locale::id* const _S_id_ctype[]; @@ -330,12 +332,12 @@ namespace std inline void _M_add_reference() throw() - { ++_M_references; } // XXX MT + { __atomic_add(&_M_references, 1); } inline void _M_remove_reference() throw() { - if (--_M_references == 0) // XXX MT + if (__exchange_and_add(&_M_references, -1) == 1) { try { delete this; } @@ -392,7 +394,7 @@ namespace std friend class __enc_traits; private: - size_t _M_references; + _Atomic_word _M_references; protected: // Contains data from the underlying "C" library for default "C" @@ -447,7 +449,7 @@ namespace std mutable size_t _M_index; // Last id number assigned - static size_t _S_highwater; + static _Atomic_word _S_highwater; void operator=(const id&); // not defined diff --git a/libstdc++-v3/src/ios.cc b/libstdc++-v3/src/ios.cc index 6ca5957..e8122bb 100644 --- a/libstdc++-v3/src/ios.cc +++ b/libstdc++-v3/src/ios.cc @@ -1,6 +1,7 @@ // Iostreams base classes -*- C++ -*- -// Copyright (C) 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc. +// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 +// Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the @@ -36,6 +37,8 @@ #include #include +#include + namespace std { // Extern declarations for global objects in src/globals.cc. @@ -224,10 +227,11 @@ namespace std int ios_base::xalloc() throw() { - // XXX MT // XXX should be a symbol. (Reserve 0..3 for builtins.) - static int top = 4; - return top++; + static _Atomic_word top = 0; + return __exchange_and_add(&top, 1) + 4; + // Implementation note: Initialize top to zero to ensure that + // initialization occurs before main() is started. } // 27.4.2.5 iword/pword storage diff --git a/libstdc++-v3/src/locale.cc b/libstdc++-v3/src/locale.cc index 630805e..5209182 100644 --- a/libstdc++-v3/src/locale.cc +++ b/libstdc++-v3/src/locale.cc @@ -41,6 +41,8 @@ # include // for towupper, etc. #endif +#include + namespace std { // Defined in globals.cc. @@ -72,7 +74,7 @@ namespace std #endif // Definitions for static const data members of locale::id - size_t locale::id::_S_highwater; // init'd to 0 by linker + _Atomic_word locale::id::_S_highwater; // init'd to 0 by linker // Definitions for static const data members of locale::_Impl const locale::id* const @@ -187,7 +189,7 @@ namespace std { _S_initialize(); (_M_impl = _S_global)->_M_add_reference(); - } // XXX MT + } locale::locale(const locale& __other) throw() { (_M_impl = __other._M_impl)->_M_add_reference(); } @@ -283,7 +285,9 @@ namespace std locale const& locale::classic() { - // XXX MT + static _STL_mutex_lock __lock __STL_MUTEX_INITIALIZER; + _STL_auto_lock __auto(__lock); + if (!_S_classic) { try @@ -364,13 +368,13 @@ namespace std void locale::facet:: _M_add_reference() throw() - { ++_M_references; } // XXX MT + { __atomic_add(&_M_references, 1); } void locale::facet:: _M_remove_reference() throw() { - if (_M_references-- == 0) + if (__exchange_and_add(&_M_references, -1) == 0) { try { delete this; } diff --git a/libstdc++-v3/src/localename.cc b/libstdc++-v3/src/localename.cc index 45c4732..816f758 100644 --- a/libstdc++-v3/src/localename.cc +++ b/libstdc++-v3/src/localename.cc @@ -178,7 +178,7 @@ namespace std { size_t& __index = __idp->_M_index; if (!__index) - __index = ++locale::id::_S_highwater; // XXX MT + __index = 1 + __exchange_and_add(&locale::id::_S_highwater, 1); if (__index >= _M_facets->size()) _M_facets->resize(__index + 1, 0); // might throw -- 2.7.4