mt_allocator.h: Change include to gthr.h.

2003-10-21  Benjamin Kosnik  <bkoz@redhat.com>

	* include/ext/mt_allocator.h: Change include to gthr.h.
	* include/ext/rope: Same. Add _Refcount_base definitions.
	* include/ext/pool_allocator.h: Adjust namespaces.
	* include/bits/stl_threads.h (_Refcount_base): Move.
	Put remaining into namespace __gnu_cxx.

From-SVN: r72763
This commit is contained in:
Benjamin Kosnik 2003-10-21 18:01:37 +00:00 committed by Benjamin Kosnik
parent c3220510b4
commit 6b5a2662c7
5 changed files with 80 additions and 97 deletions

View File

@ -1,3 +1,11 @@
2003-10-21 Benjamin Kosnik <bkoz@redhat.com>
* include/ext/mt_allocator.h: Change include to gthr.h.
* include/ext/rope: Same. Add _Refcount_base definitions.
* include/ext/pool_allocator.h: Adjust namespaces.
* include/bits/stl_threads.h (_Refcount_base): Move.
Put remaining into namespace __gnu_cxx.
2003-10-21 Benjamin Kosnik <bkoz@redhat.com>
PR libstdc++/9858

View File

@ -50,56 +50,19 @@
#include <cstddef>
// The only supported threading model is GCC's own gthr.h abstraction layer.
// The only supported threading model is GCC's own gthr.h abstraction
// layer.
#include "bits/gthr.h"
namespace std
namespace __gnu_cxx
{
// Class _Refcount_Base provides a type, _RC_t, a data member,
// _M_ref_count, and member functions _M_incr and _M_decr, which perform
// atomic preincrement/predecrement. The constructor initializes
// _M_ref_count.
struct _Refcount_Base
{
// The type _RC_t
typedef size_t _RC_t;
// The data member _M_ref_count
volatile _RC_t _M_ref_count;
// Constructor
__gthread_mutex_t _M_ref_count_lock;
_Refcount_Base(_RC_t __n) : _M_ref_count(__n)
{
#ifdef __GTHREAD_MUTEX_INIT
__gthread_mutex_t __tmp = __GTHREAD_MUTEX_INIT;
_M_ref_count_lock = __tmp;
#elif defined(__GTHREAD_MUTEX_INIT_FUNCTION)
__GTHREAD_MUTEX_INIT_FUNCTION (&_M_ref_count_lock);
#else
#error __GTHREAD_MUTEX_INIT or __GTHREAD_MUTEX_INIT_FUNCTION should be defined by gthr.h abstraction layer, report problem to libstdc++@gcc.gnu.org.
#if !defined(__GTHREAD_MUTEX_INIT) && defined(__GTHREAD_MUTEX_INIT_FUNCTION)
extern __gthread_mutex_t _GLIBCXX_mutex;
extern __gthread_mutex_t *_GLIBCXX_mutex_address;
extern __gthread_once_t _GLIBCXX_once;
extern void _GLIBCXX_mutex_init(void);
extern void _GLIBCXX_mutex_address_init(void);
#endif
}
void
_M_incr()
{
__gthread_mutex_lock(&_M_ref_count_lock);
++_M_ref_count;
__gthread_mutex_unlock(&_M_ref_count_lock);
}
_RC_t
_M_decr()
{
__gthread_mutex_lock(&_M_ref_count_lock);
volatile _RC_t __tmp = --_M_ref_count;
__gthread_mutex_unlock(&_M_ref_count_lock);
return __tmp;
}
};
} //namespace std
// Locking class. Note that this class *does not have a
// constructor*. It must be initialized either statically, with
@ -113,20 +76,6 @@ namespace std
// 8.5.1 of the C++ standard) can be initialized that way. That
// means we must have no constructors, no base classes, no virtual
// functions, and no private or protected members.
#if !defined(__GTHREAD_MUTEX_INIT) && defined(__GTHREAD_MUTEX_INIT_FUNCTION)
namespace __gnu_cxx
{
extern __gthread_mutex_t _GLIBCXX_mutex;
extern __gthread_mutex_t *_GLIBCXX_mutex_address;
extern __gthread_once_t _GLIBCXX_once;
extern void _GLIBCXX_mutex_init (void);
extern void _GLIBCXX_mutex_address_init (void);
}
#endif
namespace std
{
struct _STL_mutex_lock
{
// The class must be statically initialized with __STL_MUTEX_INITIALIZER.
@ -143,24 +92,24 @@ namespace std
// There should be no code in this path given the usage rules above.
#elif defined(__GTHREAD_MUTEX_INIT_FUNCTION)
if (_M_init_flag) return;
if (__gthread_once (&__gnu_cxx::_GLIBCXX_once,
__gnu_cxx::_GLIBCXX_mutex_init) != 0
&& __gthread_active_p ())
if (__gthread_once(&__gnu_cxx::_GLIBCXX_once,
__gnu_cxx::_GLIBCXX_mutex_init) != 0
&& __gthread_active_p())
abort ();
__gthread_mutex_lock (&__gnu_cxx::_GLIBCXX_mutex);
__gthread_mutex_lock(&__gnu_cxx::_GLIBCXX_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.
__gnu_cxx::_GLIBCXX_mutex_address = &_M_lock;
if (__gthread_once (&_M_once,
__gnu_cxx::_GLIBCXX_mutex_address_init) != 0
&& __gthread_active_p ())
abort ();
if (__gthread_once(&_M_once,
__gnu_cxx::_GLIBCXX_mutex_address_init) != 0
&& __gthread_active_p())
abort();
_M_init_flag = 1;
}
__gthread_mutex_unlock (&__gnu_cxx::_GLIBCXX_mutex);
__gthread_mutex_unlock(&__gnu_cxx::_GLIBCXX_mutex);
#endif
}
@ -193,24 +142,6 @@ namespace std
#define __STL_MUTEX_INITIALIZER = { 0, __GTHREAD_ONCE_INIT }
#endif
#endif
// A locking class that uses _STL_mutex_lock. The constructor takes a
// reference to an _STL_mutex_lock, and acquires a lock. The
// destructor releases the lock. It's not clear that this is exactly
// the right functionality. It will probably change in the future.
struct _STL_auto_lock
{
_STL_mutex_lock& _M_lock;
_STL_auto_lock(_STL_mutex_lock& __lock) : _M_lock(__lock)
{ _M_lock._M_acquire_lock(); }
~_STL_auto_lock() { _M_lock._M_release_lock(); }
private:
void operator=(const _STL_auto_lock&);
_STL_auto_lock(const _STL_auto_lock&);
} __attribute__ ((__unused__));
} // namespace std
} // namespace __gnu_cxx
#endif

View File

@ -37,7 +37,7 @@
#include <cstdlib>
#include <bits/functexcept.h>
#include <bits/stl_threads.h>
#include <bits/gthr.h>
#include <bits/atomicity.h>
#include <bits/allocator_traits.h>

View File

@ -56,7 +56,6 @@
namespace __gnu_cxx
{
using std::_STL_mutex_lock;
using std::__throw_bad_alloc;
/**
@ -80,11 +79,12 @@ namespace __gnu_cxx
* transfers its ownership to the second one. This may have undesirable
* effects on reference locality.
*
* The second parameter is unused and serves only to allow the creation of
* multiple default_alloc instances. Note that containers built on different
* allocator instances have different types, limiting the utility of this
* approach. If you do not wish to share the free lists with the main
* default_alloc instance, instantiate this with a non-zero __inst.
* The second parameter is unused and serves only to allow the
* creation of multiple default_alloc instances. Note that
* containers built on different allocator instances have different
* types, limiting the utility of this approach. If you do not
* wish to share the free lists with the main default_alloc
* instance, instantiate this with a non-zero __inst.
*
* @endif
* (See @link Allocators allocators info @endlink for more.)

View File

@ -61,7 +61,7 @@
# ifdef __GC
# define __GC_CONST const
# else
# include <bits/stl_threads.h>
# include <bits/gthr.h>
# define __GC_CONST // constant except for deallocation
# endif
@ -76,7 +76,6 @@ using std::iterator;
using std::reverse_iterator;
using std::_Alloc_traits;
using std::_Destroy;
using std::_Refcount_Base;
// The _S_eos function is used for those functions that
// convert to/from C-like strings to detect the end of the string.
@ -346,6 +345,51 @@ identity_element(_Rope_Concat_fn<_CharT, _Alloc>)
}
// Class _Refcount_Base provides a type, _RC_t, a data member,
// _M_ref_count, and member functions _M_incr and _M_decr, which perform
// atomic preincrement/predecrement. The constructor initializes
// _M_ref_count.
struct _Refcount_Base
{
// The type _RC_t
typedef size_t _RC_t;
// The data member _M_ref_count
volatile _RC_t _M_ref_count;
// Constructor
__gthread_mutex_t _M_ref_count_lock;
_Refcount_Base(_RC_t __n) : _M_ref_count(__n)
{
#ifdef __GTHREAD_MUTEX_INIT
__gthread_mutex_t __tmp = __GTHREAD_MUTEX_INIT;
_M_ref_count_lock = __tmp;
#elif defined(__GTHREAD_MUTEX_INIT_FUNCTION)
__GTHREAD_MUTEX_INIT_FUNCTION (&_M_ref_count_lock);
#else
#error __GTHREAD_MUTEX_INIT or __GTHREAD_MUTEX_INIT_FUNCTION should be defined by gthr.h abstraction layer, report problem to libstdc++@gcc.gnu.org.
#endif
}
void
_M_incr()
{
__gthread_mutex_lock(&_M_ref_count_lock);
++_M_ref_count;
__gthread_mutex_unlock(&_M_ref_count_lock);
}
_RC_t
_M_decr()
{
__gthread_mutex_lock(&_M_ref_count_lock);
volatile _RC_t __tmp = --_M_ref_count;
__gthread_mutex_unlock(&_M_ref_count_lock);
return __tmp;
}
};
//
// What follows should really be local to rope. Unfortunately,
// that doesn't work, since it makes it impossible to define generic