Commit 6b5a2662 by Benjamin Kosnik Committed by Benjamin Kosnik

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
parent c3220510
2003-10-21 Benjamin Kosnik <bkoz@redhat.com> 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 PR libstdc++/9858
* include/bits/locale_facets.h (ctype<char>): Remove * include/bits/locale_facets.h (ctype<char>): Remove
......
...@@ -50,56 +50,19 @@ ...@@ -50,56 +50,19 @@
#include <cstddef> #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" #include "bits/gthr.h"
namespace std namespace __gnu_cxx
{ {
// Class _Refcount_Base provides a type, _RC_t, a data member, #if !defined(__GTHREAD_MUTEX_INIT) && defined(__GTHREAD_MUTEX_INIT_FUNCTION)
// _M_ref_count, and member functions _M_incr and _M_decr, which perform extern __gthread_mutex_t _GLIBCXX_mutex;
// atomic preincrement/predecrement. The constructor initializes extern __gthread_mutex_t *_GLIBCXX_mutex_address;
// _M_ref_count. extern __gthread_once_t _GLIBCXX_once;
struct _Refcount_Base extern void _GLIBCXX_mutex_init(void);
{ extern void _GLIBCXX_mutex_address_init(void);
// 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 #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 // Locking class. Note that this class *does not have a
// constructor*. It must be initialized either statically, with // constructor*. It must be initialized either statically, with
...@@ -113,20 +76,6 @@ namespace std ...@@ -113,20 +76,6 @@ namespace std
// 8.5.1 of the C++ standard) can be initialized that way. That // 8.5.1 of the C++ standard) can be initialized that way. That
// means we must have no constructors, no base classes, no virtual // means we must have no constructors, no base classes, no virtual
// functions, and no private or protected members. // 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 struct _STL_mutex_lock
{ {
// The class must be statically initialized with __STL_MUTEX_INITIALIZER. // The class must be statically initialized with __STL_MUTEX_INITIALIZER.
...@@ -143,24 +92,24 @@ namespace std ...@@ -143,24 +92,24 @@ namespace std
// 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) #elif defined(__GTHREAD_MUTEX_INIT_FUNCTION)
if (_M_init_flag) return; if (_M_init_flag) return;
if (__gthread_once (&__gnu_cxx::_GLIBCXX_once, if (__gthread_once(&__gnu_cxx::_GLIBCXX_once,
__gnu_cxx::_GLIBCXX_mutex_init) != 0 __gnu_cxx::_GLIBCXX_mutex_init) != 0
&& __gthread_active_p ()) && __gthread_active_p())
abort (); abort ();
__gthread_mutex_lock (&__gnu_cxx::_GLIBCXX_mutex); __gthread_mutex_lock(&__gnu_cxx::_GLIBCXX_mutex);
if (!_M_init_flag) if (!_M_init_flag)
{ {
// Even though we have a global lock, we use __gthread_once to be // Even though we have a global lock, we use __gthread_once to be
// absolutely certain the _M_lock mutex is only initialized once on // absolutely certain the _M_lock mutex is only initialized once on
// multiprocessor systems. // multiprocessor systems.
__gnu_cxx::_GLIBCXX_mutex_address = &_M_lock; __gnu_cxx::_GLIBCXX_mutex_address = &_M_lock;
if (__gthread_once (&_M_once, if (__gthread_once(&_M_once,
__gnu_cxx::_GLIBCXX_mutex_address_init) != 0 __gnu_cxx::_GLIBCXX_mutex_address_init) != 0
&& __gthread_active_p ()) && __gthread_active_p())
abort (); abort();
_M_init_flag = 1; _M_init_flag = 1;
} }
__gthread_mutex_unlock (&__gnu_cxx::_GLIBCXX_mutex); __gthread_mutex_unlock(&__gnu_cxx::_GLIBCXX_mutex);
#endif #endif
} }
...@@ -193,24 +142,6 @@ namespace std ...@@ -193,24 +142,6 @@ namespace std
#define __STL_MUTEX_INITIALIZER = { 0, __GTHREAD_ONCE_INIT } #define __STL_MUTEX_INITIALIZER = { 0, __GTHREAD_ONCE_INIT }
#endif #endif
#endif #endif
} // namespace __gnu_cxx
// 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
#endif #endif
...@@ -37,7 +37,7 @@ ...@@ -37,7 +37,7 @@
#include <cstdlib> #include <cstdlib>
#include <bits/functexcept.h> #include <bits/functexcept.h>
#include <bits/stl_threads.h> #include <bits/gthr.h>
#include <bits/atomicity.h> #include <bits/atomicity.h>
#include <bits/allocator_traits.h> #include <bits/allocator_traits.h>
......
...@@ -56,7 +56,6 @@ ...@@ -56,7 +56,6 @@
namespace __gnu_cxx namespace __gnu_cxx
{ {
using std::_STL_mutex_lock;
using std::__throw_bad_alloc; using std::__throw_bad_alloc;
/** /**
...@@ -80,11 +79,12 @@ namespace __gnu_cxx ...@@ -80,11 +79,12 @@ namespace __gnu_cxx
* transfers its ownership to the second one. This may have undesirable * transfers its ownership to the second one. This may have undesirable
* effects on reference locality. * effects on reference locality.
* *
* The second parameter is unused and serves only to allow the creation of * The second parameter is unused and serves only to allow the
* multiple default_alloc instances. Note that containers built on different * creation of multiple default_alloc instances. Note that
* allocator instances have different types, limiting the utility of this * containers built on different allocator instances have different
* approach. If you do not wish to share the free lists with the main * types, limiting the utility of this approach. If you do not
* default_alloc instance, instantiate this with a non-zero __inst. * wish to share the free lists with the main default_alloc
* instance, instantiate this with a non-zero __inst.
* *
* @endif * @endif
* (See @link Allocators allocators info @endlink for more.) * (See @link Allocators allocators info @endlink for more.)
......
...@@ -61,7 +61,7 @@ ...@@ -61,7 +61,7 @@
# ifdef __GC # ifdef __GC
# define __GC_CONST const # define __GC_CONST const
# else # else
# include <bits/stl_threads.h> # include <bits/gthr.h>
# define __GC_CONST // constant except for deallocation # define __GC_CONST // constant except for deallocation
# endif # endif
...@@ -76,7 +76,6 @@ using std::iterator; ...@@ -76,7 +76,6 @@ using std::iterator;
using std::reverse_iterator; using std::reverse_iterator;
using std::_Alloc_traits; using std::_Alloc_traits;
using std::_Destroy; using std::_Destroy;
using std::_Refcount_Base;
// The _S_eos function is used for those functions that // The _S_eos function is used for those functions that
// convert to/from C-like strings to detect the end of the string. // convert to/from C-like strings to detect the end of the string.
...@@ -346,6 +345,51 @@ identity_element(_Rope_Concat_fn<_CharT, _Alloc>) ...@@ -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, // What follows should really be local to rope. Unfortunately,
// that doesn't work, since it makes it impossible to define generic // that doesn't work, since it makes it impossible to define generic
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment