+2002-01-24 andrew@andypo.net
+ (tweaks, test and commit by Loren J. Rittle <ljrittle@acm.org>)
+
+ 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 <bkoz@redhat.com>
* testsuite/22_locale/num_put_members_wchar_t.cc (test03): Use
// 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
#pragma GCC system_header
+#include <bits/atomicity.h>
+
namespace std
{
// The following definitions of bitmask types are enums, not ints,
_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;
#include <string> // For string
#include <bits/functexcept.h>
+#include <bits/atomicity.h>
+
namespace std
{
// NB: Don't instantiate required wchar_t facets if no wchar_t support.
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[];
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; }
friend class __enc_traits;
private:
- size_t _M_references;
+ _Atomic_word _M_references;
protected:
// Contains data from the underlying "C" library for default "C"
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
// 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
#include <istream>
#include <fstream>
+#include <bits/atomicity.h>
+
namespace std
{
// Extern declarations for global objects in src/globals.cc.
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
# include <cwctype> // for towupper, etc.
#endif
+#include <bits/atomicity.h>
+
namespace std
{
// Defined in globals.cc.
#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
{
_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(); }
locale const&
locale::classic()
{
- // XXX MT
+ static _STL_mutex_lock __lock __STL_MUTEX_INITIALIZER;
+ _STL_auto_lock __auto(__lock);
+
if (!_S_classic)
{
try
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; }
{
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