mirror of git://gcc.gnu.org/git/gcc.git
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:
parent
c3220510b4
commit
6b5a2662c7
|
|
@ -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>
|
2003-10-21 Benjamin Kosnik <bkoz@redhat.com>
|
||||||
|
|
||||||
PR libstdc++/9858
|
PR libstdc++/9858
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
// 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
|
||||||
// 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
|
||||||
#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 @@
|
||||||
|
|
||||||
#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 @@
|
||||||
|
|
||||||
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
|
||||||
* 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 @@
|
||||||
# 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;
|
||||||
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>)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 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
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue