summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbkoz <bkoz@138bc75d-0d04-0410-961f-82ee72b054a4>2003-06-11 15:52:11 +0000
committerbkoz <bkoz@138bc75d-0d04-0410-961f-82ee72b054a4>2003-06-11 15:52:11 +0000
commit93666440745e2eb59c05d7ca9c202f1d962fb2c7 (patch)
tree61989852861e8690ab5a873c759b5218e2280ca7
parentf7874cd76589d7ea2fd729e956469565069cdf76 (diff)
downloadgcc-93666440745e2eb59c05d7ca9c202f1d962fb2c7.tar.gz
2003-06-11 Benjamin Kosnik <bkoz@redhat.com>
* include/bits/stl_alloc.h (__debug_alloc): Move out. (__malloc_alloc): Same. (__pool_alloc): Same. (__new_alloc): Same. Rename to.. * include/bits/allocator.h: ...this. * include/bits/stl_deque.h: Modify comment. * include/bits/stl_tree.h: Modify include. * include/std/std_memory.h: Same. * include/ext/rope: Same. * include/ext/slist: Same. * include/std/std_vector.h: Same. * include/std/std_stack.h: Same. * include/std/std_queue.h: Same. * include/std/std_list.h: Same. * include/std/std_deque.h: Same. * include/backward/alloc.h: Same. * include/ext/debug_allocator.h: New. * include/ext/malloc_allocator.h: New. * include/ext/pool_allocator.h: New. * include/ext/new_allocator.h: New. * include/bits/pthread_allocimpl.h: Remove. * include/bits/stl_pthread_alloc.h: Remove. * include/Makefile.am (ext_headers): Add. * include/Makefile.in: Regenerate. * src/stl-inst.cc: Use __gnu_cxx namespace. * src/stl-inst.cc: Move to... * src/allocator-inst.cc: Here. * src/Makefile.am (sources): Update. * src/Makefile.in: Regenerate. * config/linker-map.gnu: Remove __pool_alloc bits. * testsuite/ext/headers.cc: Add. * testsuite/ext/allocators.cc: Fixup. 2003-06-11 Stefan Olsson <stefan@snon.net> Ola R�nnerup <fnolis@home.se> * include/Makefile.am (ext_headers): Add. * include/Makefile.in: Regenerate. * include/ext/mt_allocator.h: New file. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@67777 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--libstdc++-v3/ChangeLog43
-rw-r--r--libstdc++-v3/config/linker-map.gnu9
-rw-r--r--libstdc++-v3/include/Makefile.am10
-rw-r--r--libstdc++-v3/include/Makefile.in10
-rw-r--r--libstdc++-v3/include/backward/alloc.h14
-rw-r--r--libstdc++-v3/include/bits/allocator.h215
-rw-r--r--libstdc++-v3/include/bits/allocator_traits.h236
-rw-r--r--libstdc++-v3/include/bits/pthread_allocimpl.h525
-rw-r--r--libstdc++-v3/include/bits/stl_alloc.h900
-rw-r--r--libstdc++-v3/include/bits/stl_deque.h2
-rw-r--r--libstdc++-v3/include/bits/stl_threads.h3
-rw-r--r--libstdc++-v3/include/bits/stl_tree.h2
-rw-r--r--libstdc++-v3/include/ext/debug_allocator.h139
-rw-r--r--libstdc++-v3/include/ext/malloc_allocator.h163
-rw-r--r--libstdc++-v3/include/ext/mt_allocator.h861
-rw-r--r--libstdc++-v3/include/ext/new_allocator.h (renamed from libstdc++-v3/include/bits/stl_pthread_alloc.h)64
-rw-r--r--libstdc++-v3/include/ext/pool_allocator.h383
-rw-r--r--libstdc++-v3/include/ext/rope2
-rw-r--r--libstdc++-v3/include/ext/slist2
-rw-r--r--libstdc++-v3/include/std/std_deque.h2
-rw-r--r--libstdc++-v3/include/std/std_list.h2
-rw-r--r--libstdc++-v3/include/std/std_memory.h2
-rw-r--r--libstdc++-v3/include/std/std_queue.h2
-rw-r--r--libstdc++-v3/include/std/std_stack.h2
-rw-r--r--libstdc++-v3/include/std/std_vector.h2
-rw-r--r--libstdc++-v3/src/Makefile.am2
-rw-r--r--libstdc++-v3/src/Makefile.in21
-rw-r--r--libstdc++-v3/src/allocator-inst.cc41
-rw-r--r--libstdc++-v3/testsuite/ext/allocators.cc55
-rw-r--r--libstdc++-v3/testsuite/ext/headers.cc8
30 files changed, 2190 insertions, 1532 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index 0c01a43308e..ad3c2d65ab9 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,3 +1,46 @@
+2003-06-11 Benjamin Kosnik <bkoz@redhat.com>
+
+ * include/bits/stl_alloc.h (__debug_alloc): Move out.
+ (__malloc_alloc): Same.
+ (__pool_alloc): Same.
+ (__new_alloc): Same.
+ Rename to..
+ * include/bits/allocator.h: ...this.
+ * include/bits/stl_deque.h: Modify comment.
+ * include/bits/stl_tree.h: Modify include.
+ * include/std/std_memory.h: Same.
+ * include/ext/rope: Same.
+ * include/ext/slist: Same.
+ * include/std/std_vector.h: Same.
+ * include/std/std_stack.h: Same.
+ * include/std/std_queue.h: Same.
+ * include/std/std_list.h: Same.
+ * include/std/std_deque.h: Same.
+ * include/backward/alloc.h: Same.
+ * include/ext/debug_allocator.h: New.
+ * include/ext/malloc_allocator.h: New.
+ * include/ext/pool_allocator.h: New.
+ * include/ext/new_allocator.h: New.
+ * include/bits/pthread_allocimpl.h: Remove.
+ * include/bits/stl_pthread_alloc.h: Remove.
+ * include/Makefile.am (ext_headers): Add.
+ * include/Makefile.in: Regenerate.
+ * src/stl-inst.cc: Use __gnu_cxx namespace.
+ * src/stl-inst.cc: Move to...
+ * src/allocator-inst.cc: Here.
+ * src/Makefile.am (sources): Update.
+ * src/Makefile.in: Regenerate.
+ * config/linker-map.gnu: Remove __pool_alloc bits.
+ * testsuite/ext/headers.cc: Add.
+ * testsuite/ext/allocators.cc: Fixup.
+
+2003-06-11 Stefan Olsson <stefan@snon.net>
+ Ola Rönnerup <fnolis@home.se>
+
+ * include/Makefile.am (ext_headers): Add.
+ * include/Makefile.in: Regenerate.
+ * include/ext/mt_allocator.h: New file.
+
2003-06-10 Paolo Carlini <pcarlini@unitus.it>
* include/bits/fstream.tcc (close): Clean up a bit.
diff --git a/libstdc++-v3/config/linker-map.gnu b/libstdc++-v3/config/linker-map.gnu
index 6f87a0b9967..6723a057e07 100644
--- a/libstdc++-v3/config/linker-map.gnu
+++ b/libstdc++-v3/config/linker-map.gnu
@@ -78,15 +78,6 @@ GLIBCPP_3.4 {
# bool has_facet
_ZSt9has_facet*;
- # std::__pool_alloc
- _ZNSt12__pool_allocILb1ELi0EE10deallocateEPv[jm]*;
- _ZNSt12__pool_allocILb1ELi0EE8allocateE[jm]*;
- _ZNSt12__pool_allocILb1ELi0EE5_Lock*;
- _ZNSt12__pool_allocILb1ELi0EE12_S_force_newE;
- _ZNSt12__pool_allocILb1ELi0EE12_S_free_listE;
- _ZNSt12__pool_allocILb1ELi0EE7_S_lockE;
- _ZNSt12__pool_allocILb1ELi0EE9_S_refillE[jm];
-
# operator new(size_t)
_Znw[jm];
# operator new(size_t, std::nothrow_t const&)
diff --git a/libstdc++-v3/include/Makefile.am b/libstdc++-v3/include/Makefile.am
index 5c200dcd8a7..760e85ba4e8 100644
--- a/libstdc++-v3/include/Makefile.am
+++ b/libstdc++-v3/include/Makefile.am
@@ -103,6 +103,8 @@ std_headers_rename = \
bits_srcdir = ${glibcpp_srcdir}/include/bits
bits_builddir = ./bits
bits_headers = \
+ ${bits_srcdir}/allocator.h \
+ ${bits_srcdir}/allocator_traits.h \
${bits_srcdir}/basic_ios.h \
${bits_srcdir}/basic_ios.tcc \
${bits_srcdir}/basic_string.h \
@@ -129,14 +131,12 @@ bits_headers = \
${bits_srcdir}/localefwd.h \
${bits_srcdir}/mask_array.h \
${bits_srcdir}/ostream.tcc \
- ${bits_srcdir}/pthread_allocimpl.h \
${bits_srcdir}/stream_iterator.h \
${bits_srcdir}/streambuf_iterator.h \
${bits_srcdir}/slice_array.h \
${bits_srcdir}/sstream.tcc \
${bits_srcdir}/stl_algo.h \
${bits_srcdir}/stl_algobase.h \
- ${bits_srcdir}/stl_alloc.h \
${bits_srcdir}/stl_bvector.h \
${bits_srcdir}/stl_construct.h \
${bits_srcdir}/stl_deque.h \
@@ -151,7 +151,6 @@ bits_headers = \
${bits_srcdir}/stl_multiset.h \
${bits_srcdir}/stl_numeric.h \
${bits_srcdir}/stl_pair.h \
- ${bits_srcdir}/stl_pthread_alloc.h \
${bits_srcdir}/stl_queue.h \
${bits_srcdir}/stl_raw_storage_iter.h \
${bits_srcdir}/stl_relops.h \
@@ -215,6 +214,7 @@ ext_srcdir = ${glibcpp_srcdir}/include/ext
ext_builddir = ./ext
ext_headers = \
${ext_srcdir}/algorithm \
+ ${ext_srcdir}/debug_allocator.h \
${ext_srcdir}/enc_filebuf.h \
${ext_srcdir}/stdio_filebuf.h \
${ext_srcdir}/stdio_sync_filebuf.h \
@@ -222,8 +222,12 @@ ext_headers = \
${ext_srcdir}/hash_map \
${ext_srcdir}/hash_set \
${ext_srcdir}/iterator \
+ ${ext_srcdir}/malloc_allocator.h \
${ext_srcdir}/memory \
+ ${ext_srcdir}/mt_allocator.h \
+ ${ext_srcdir}/new_allocator.h \
${ext_srcdir}/numeric \
+ ${ext_srcdir}/pool_allocator.h \
${ext_srcdir}/rb_tree \
${ext_srcdir}/rope \
${ext_srcdir}/ropeimpl.h \
diff --git a/libstdc++-v3/include/Makefile.in b/libstdc++-v3/include/Makefile.in
index 7dfd79311e1..33d5a81846c 100644
--- a/libstdc++-v3/include/Makefile.in
+++ b/libstdc++-v3/include/Makefile.in
@@ -222,6 +222,8 @@ std_headers_rename = \
bits_srcdir = ${glibcpp_srcdir}/include/bits
bits_builddir = ./bits
bits_headers = \
+ ${bits_srcdir}/allocator.h \
+ ${bits_srcdir}/allocator_traits.h \
${bits_srcdir}/basic_ios.h \
${bits_srcdir}/basic_ios.tcc \
${bits_srcdir}/basic_string.h \
@@ -248,14 +250,12 @@ bits_headers = \
${bits_srcdir}/localefwd.h \
${bits_srcdir}/mask_array.h \
${bits_srcdir}/ostream.tcc \
- ${bits_srcdir}/pthread_allocimpl.h \
${bits_srcdir}/stream_iterator.h \
${bits_srcdir}/streambuf_iterator.h \
${bits_srcdir}/slice_array.h \
${bits_srcdir}/sstream.tcc \
${bits_srcdir}/stl_algo.h \
${bits_srcdir}/stl_algobase.h \
- ${bits_srcdir}/stl_alloc.h \
${bits_srcdir}/stl_bvector.h \
${bits_srcdir}/stl_construct.h \
${bits_srcdir}/stl_deque.h \
@@ -270,7 +270,6 @@ bits_headers = \
${bits_srcdir}/stl_multiset.h \
${bits_srcdir}/stl_numeric.h \
${bits_srcdir}/stl_pair.h \
- ${bits_srcdir}/stl_pthread_alloc.h \
${bits_srcdir}/stl_queue.h \
${bits_srcdir}/stl_raw_storage_iter.h \
${bits_srcdir}/stl_relops.h \
@@ -336,6 +335,7 @@ ext_srcdir = ${glibcpp_srcdir}/include/ext
ext_builddir = ./ext
ext_headers = \
${ext_srcdir}/algorithm \
+ ${ext_srcdir}/debug_allocator.h \
${ext_srcdir}/enc_filebuf.h \
${ext_srcdir}/stdio_filebuf.h \
${ext_srcdir}/stdio_sync_filebuf.h \
@@ -343,8 +343,12 @@ ext_headers = \
${ext_srcdir}/hash_map \
${ext_srcdir}/hash_set \
${ext_srcdir}/iterator \
+ ${ext_srcdir}/malloc_allocator.h \
${ext_srcdir}/memory \
+ ${ext_srcdir}/mt_allocator.h \
+ ${ext_srcdir}/new_allocator.h \
${ext_srcdir}/numeric \
+ ${ext_srcdir}/pool_allocator.h \
${ext_srcdir}/rb_tree \
${ext_srcdir}/rope \
${ext_srcdir}/ropeimpl.h \
diff --git a/libstdc++-v3/include/backward/alloc.h b/libstdc++-v3/include/backward/alloc.h
index 6bcc421b7af..b748ef26c01 100644
--- a/libstdc++-v3/include/backward/alloc.h
+++ b/libstdc++-v3/include/backward/alloc.h
@@ -45,15 +45,15 @@
#include "backward_warning.h"
#include <bits/c++config.h>
-#include <bits/stl_alloc.h>
+#include <bits/allocator.h>
+#include <ext/debug_allocator.h>
+#include <ext/malloc_allocator.h>
-using std::__malloc_alloc;
-using std::__simple_alloc;
-using std::__debug_alloc;
+using __gnu_cxx::__malloc_alloc;
+using __gnu_cxx::__debug_alloc;
+using __gnu_cxx::__pool_alloc;
using std::__alloc;
-using std::__single_client_alloc;
-using std::__pool_alloc;
+using std::__simple_alloc;
using std::allocator;
-
#endif
diff --git a/libstdc++-v3/include/bits/allocator.h b/libstdc++-v3/include/bits/allocator.h
new file mode 100644
index 00000000000..b6dec02572a
--- /dev/null
+++ b/libstdc++-v3/include/bits/allocator.h
@@ -0,0 +1,215 @@
+// Allocators -*- C++ -*-
+
+// Copyright (C) 2001, 2002, 2003 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
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// As a special exception, you may use this file as part of a free software
+// library without restriction. Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License. This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+/*
+ * Copyright (c) 1996-1997
+ * Silicon Graphics Computer Systems, Inc.
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Silicon Graphics makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ */
+
+/** @file allocator.h
+ * This is an internal header file, included by other library headers.
+ * You should not attempt to use it directly.
+ */
+
+/**
+ * @defgroup Allocators Memory Allocators
+ * @if maint
+ * allocator.h implements some node allocators. These are NOT the same as
+ * allocators in the C++ standard, nor in the original H-P STL. They do not
+ * encapsulate different pointer types; we assume that there is only one
+ * pointer type. The C++ standard allocators are intended to allocate
+ * individual objects, not pools or arenas.
+ *
+ * In this file allocators are of two different styles: "standard" and
+ * "SGI" (quotes included). "Standard" allocators conform to 20.4. "SGI"
+ * allocators differ in AT LEAST the following ways (add to this list as you
+ * discover them):
+ *
+ * - "Standard" allocate() takes two parameters (n_count,hint=0) but "SGI"
+ * allocate() takes one paramter (n_size).
+ * - Likewise, "standard" deallocate()'s argument is a count, but in "SGI"
+ * is a byte size.
+ * - max_size(), construct(), and destroy() are missing in "SGI" allocators.
+ * - reallocate(p,oldsz,newsz) is added in "SGI", and behaves as
+ * if p=realloc(p,newsz).
+ *
+ * "SGI" allocators may be wrapped in __allocator to convert the interface
+ * into a "standard" one.
+ * @endif
+ *
+ * The canonical description of these classes is in docs/html/ext/howto.html
+ * or online at http://gcc.gnu.org/onlinedocs/libstdc++/ext/howto.html#3
+*/
+
+#ifndef _ALLOCATOR_H
+#define _ALLOCATOR_H 1
+
+#include <bits/functexcept.h> // For __throw_bad_alloc
+#include <bits/allocator_traits.h>
+
+// Pick a default underlying allocator.
+#include <ext/pool_allocator.h>
+
+namespace std
+{
+ typedef __gnu_cxx::__pool_alloc<true, 0> __alloc;
+
+ /// The version for the default allocator.
+ template<typename _Tp, typename _Tp1>
+ struct _Alloc_traits<_Tp, allocator<_Tp1> >
+ {
+ static const bool _S_instanceless = true;
+ typedef __simple_alloc<_Tp, __alloc> _Alloc_type;
+ typedef allocator<_Tp> allocator_type;
+ };
+ //@}
+}
+
+namespace std
+{
+ /**
+ * @brief The "standard" allocator, as per [20.4].
+ *
+ * The private _Alloc is "SGI" style. (See comments at the top
+ * of allocator.h.)
+ *
+ * The underlying allocator behaves as follows.
+ * - __pool_alloc is used via two typedefs
+ * - "__alloc" typedef is threadsafe via the locks
+ * - __new_alloc is used for memory requests
+ *
+ * (See @link Allocators allocators info @endlink for more.)
+ */
+ template<typename _Tp>
+ class allocator
+ {
+ // The underlying allocator.
+ typedef __alloc _Alloc;
+
+ public:
+ typedef size_t size_type;
+ typedef ptrdiff_t difference_type;
+ typedef _Tp* pointer;
+ typedef const _Tp* const_pointer;
+ typedef _Tp& reference;
+ typedef const _Tp& const_reference;
+ typedef _Tp value_type;
+
+ template<typename _Tp1>
+ struct rebind
+ { typedef allocator<_Tp1> other; };
+
+ allocator() throw() { }
+
+ allocator(const allocator&) throw() { }
+
+ template<typename _Tp1>
+ allocator(const allocator<_Tp1>&) throw() { }
+
+ ~allocator() throw() { }
+
+ pointer
+ address(reference __x) const { return &__x; }
+
+ const_pointer
+ address(const_reference __x) const { return &__x; }
+
+ // NB: __n is permitted to be 0. The C++ standard says nothing
+ // about what the return value is when __n == 0.
+ _Tp*
+ allocate(size_type __n, const void* = 0)
+ {
+ _Tp* __ret = 0;
+ if (__n)
+ {
+ if (__n <= this->max_size())
+ __ret = static_cast<_Tp*>(_Alloc::allocate(__n * sizeof(_Tp)));
+ else
+ __throw_bad_alloc();
+ }
+ return __ret;
+ }
+
+ // __p is not permitted to be a null pointer.
+ void
+ deallocate(pointer __p, size_type __n)
+ { _Alloc::deallocate(__p, __n * sizeof(_Tp)); }
+
+ size_type
+ max_size() const throw() { return size_t(-1) / sizeof(_Tp); }
+
+ void construct(pointer __p, const _Tp& __val) { new(__p) _Tp(__val); }
+
+ void destroy(pointer __p) { __p->~_Tp(); }
+ };
+
+ template<>
+ class allocator<void>
+ {
+ public:
+ typedef size_t size_type;
+ typedef ptrdiff_t difference_type;
+ typedef void* pointer;
+ typedef const void* const_pointer;
+ typedef void value_type;
+
+ template<typename _Tp1>
+ struct rebind
+ { typedef allocator<_Tp1> other; };
+ };
+
+
+ template<typename _T1, typename _T2>
+ inline bool
+ operator==(const allocator<_T1>&, const allocator<_T2>&)
+ { return true; }
+
+ template<typename _T1, typename _T2>
+ inline bool
+ operator!=(const allocator<_T1>&, const allocator<_T2>&)
+ { return false; }
+
+ // Inhibit implicit instantiations for required instantiations,
+ // which are defined via explicit instantiations elsewhere.
+ // NB: This syntax is a GNU extension.
+#if _GLIBCPP_EXTERN_TEMPLATE
+ extern template class allocator<char>;
+ extern template class allocator<wchar_t>;
+#endif
+} // namespace std
+
+#endif
diff --git a/libstdc++-v3/include/bits/allocator_traits.h b/libstdc++-v3/include/bits/allocator_traits.h
new file mode 100644
index 00000000000..be9a352fdd9
--- /dev/null
+++ b/libstdc++-v3/include/bits/allocator_traits.h
@@ -0,0 +1,236 @@
+// Allocators -*- C++ -*-
+
+// Copyright (C) 2001, 2002, 2003 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
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// As a special exception, you may use this file as part of a free software
+// library without restriction. Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License. This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+/*
+ * Copyright (c) 1996-1997
+ * Silicon Graphics Computer Systems, Inc.
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Silicon Graphics makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ */
+
+#ifndef _ALLOCATOR_TRAITS_H
+#define _ALLOCATOR_TRAITS_H 1
+
+#include <cstddef>
+
+namespace std
+{
+ /**
+ * @if maint
+ * This is used primarily (only?) in _Alloc_traits and other places to
+ * help provide the _Alloc_type typedef. All it does is forward the
+ * requests after some minimal checking.
+ *
+ * This is neither "standard"-conforming nor "SGI". The _Alloc parameter
+ * must be "SGI" style.
+ * @endif
+ * (See @link Allocators allocators info @endlink for more.)
+ */
+ template<typename _Tp, typename _Alloc>
+ class __simple_alloc
+ {
+ public:
+ static _Tp*
+ allocate(size_t __n)
+ {
+ _Tp* __ret = 0;
+ if (__n)
+ __ret = static_cast<_Tp*>(_Alloc::allocate(__n * sizeof(_Tp)));
+ return __ret;
+ }
+
+ static _Tp*
+ allocate()
+ { return (_Tp*) _Alloc::allocate(sizeof (_Tp)); }
+
+ static void
+ deallocate(_Tp* __p, size_t __n)
+ { if (0 != __n) _Alloc::deallocate(__p, __n * sizeof (_Tp)); }
+
+ static void
+ deallocate(_Tp* __p)
+ { _Alloc::deallocate(__p, sizeof (_Tp)); }
+ };
+
+
+ /**
+ * @if maint
+ * Allocator adaptor to turn an "SGI" style allocator (e.g.,
+ * __alloc, __malloc_alloc) into a "standard" conforming
+ * allocator. Note that this adaptor does *not* assume that all
+ * objects of the underlying alloc class are identical, nor does it
+ * assume that all of the underlying alloc's member functions are
+ * static member functions. Note, also, that __allocator<_Tp,
+ * __alloc> is essentially the same thing as allocator<_Tp>.
+ * @endif
+ * (See @link Allocators allocators info @endlink for more.)
+ */
+ template<typename _Tp, typename _Alloc>
+ struct __allocator
+ {
+ _Alloc __underlying_alloc;
+
+ typedef size_t size_type;
+ typedef ptrdiff_t difference_type;
+ typedef _Tp* pointer;
+ typedef const _Tp* const_pointer;
+ typedef _Tp& reference;
+ typedef const _Tp& const_reference;
+ typedef _Tp value_type;
+
+ template<typename _Tp1>
+ struct rebind
+ { typedef __allocator<_Tp1, _Alloc> other; };
+
+ __allocator() throw() { }
+
+ __allocator(const __allocator& __a) throw()
+ : __underlying_alloc(__a.__underlying_alloc) { }
+
+ template<typename _Tp1>
+ __allocator(const __allocator<_Tp1, _Alloc>& __a) throw()
+ : __underlying_alloc(__a.__underlying_alloc) { }
+
+ ~__allocator() throw() { }
+
+ pointer
+ address(reference __x) const { return &__x; }
+
+ const_pointer
+ address(const_reference __x) const { return &__x; }
+
+ // NB: __n is permitted to be 0. The C++ standard says nothing
+ // about what the return value is when __n == 0.
+ _Tp*
+ allocate(size_type __n, const void* = 0)
+ {
+ _Tp* __ret = 0;
+ if (__n)
+ __ret = static_cast<_Tp*>(_Alloc::allocate(__n * sizeof(_Tp)));
+ return __ret;
+ }
+
+ // __p is not permitted to be a null pointer.
+ void
+ deallocate(pointer __p, size_type __n)
+ { __underlying_alloc.deallocate(__p, __n * sizeof(_Tp)); }
+
+ size_type
+ max_size() const throw() { return size_t(-1) / sizeof(_Tp); }
+
+ void
+ construct(pointer __p, const _Tp& __val) { new(__p) _Tp(__val); }
+
+ void
+ destroy(pointer __p) { __p->~_Tp(); }
+ };
+
+ template<typename _Alloc>
+ struct __allocator<void, _Alloc>
+ {
+ typedef size_t size_type;
+ typedef ptrdiff_t difference_type;
+ typedef void* pointer;
+ typedef const void* const_pointer;
+ typedef void value_type;
+
+ template<typename _Tp1>
+ struct rebind
+ { typedef __allocator<_Tp1, _Alloc> other; };
+ };
+
+ template<typename _Tp, typename _Alloc>
+ inline bool
+ operator==(const __allocator<_Tp,_Alloc>& __a1,
+ const __allocator<_Tp,_Alloc>& __a2)
+ { return __a1.__underlying_alloc == __a2.__underlying_alloc; }
+
+ template<typename _Tp, typename _Alloc>
+ inline bool
+ operator!=(const __allocator<_Tp, _Alloc>& __a1,
+ const __allocator<_Tp, _Alloc>& __a2)
+ { return __a1.__underlying_alloc != __a2.__underlying_alloc; }
+
+
+ /**
+ * @if maint
+ * Another allocator adaptor: _Alloc_traits. This serves two purposes.
+ * First, make it possible to write containers that can use either "SGI"
+ * style allocators or "standard" allocators. Second, provide a mechanism
+ * so that containers can query whether or not the allocator has distinct
+ * instances. If not, the container can avoid wasting a word of memory to
+ * store an empty object. For examples of use, see stl_vector.h, etc, or
+ * any of the other classes derived from this one.
+ *
+ * This adaptor uses partial specialization. The general case of
+ * _Alloc_traits<_Tp, _Alloc> assumes that _Alloc is a
+ * standard-conforming allocator, possibly with non-equal instances and
+ * non-static members. (It still behaves correctly even if _Alloc has
+ * static member and if all instances are equal. Refinements affect
+ * performance, not correctness.)
+ *
+ * There are always two members: allocator_type, which is a standard-
+ * conforming allocator type for allocating objects of type _Tp, and
+ * _S_instanceless, a static const member of type bool. If
+ * _S_instanceless is true, this means that there is no difference
+ * between any two instances of type allocator_type. Furthermore, if
+ * _S_instanceless is true, then _Alloc_traits has one additional
+ * member: _Alloc_type. This type encapsulates allocation and
+ * deallocation of objects of type _Tp through a static interface; it
+ * has two member functions, whose signatures are
+ *
+ * - static _Tp* allocate(size_t)
+ * - static void deallocate(_Tp*, size_t)
+ *
+ * The size_t parameters are "standard" style (see top of
+ * allocator.h) in that they take counts, not sizes.
+ *
+ * @endif
+ * (See @link Allocators allocators info @endlink for more.)
+ */
+ //@{
+ // The fully general version.
+ template<typename _Tp, typename _Allocator>
+ struct _Alloc_traits
+ {
+ static const bool _S_instanceless = false;
+ typedef typename _Allocator::template rebind<_Tp>::other allocator_type;
+ };
+
+ template<typename _Tp, typename _Allocator>
+ const bool _Alloc_traits<_Tp, _Allocator>::_S_instanceless;
+} // namespace std
+
+#endif
diff --git a/libstdc++-v3/include/bits/pthread_allocimpl.h b/libstdc++-v3/include/bits/pthread_allocimpl.h
deleted file mode 100644
index 050b2060fc4..00000000000
--- a/libstdc++-v3/include/bits/pthread_allocimpl.h
+++ /dev/null
@@ -1,525 +0,0 @@
-// POSIX thread-related memory allocation -*- C++ -*-
-
-// Copyright (C) 2001 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
-// terms of the GNU General Public License as published by the
-// Free Software Foundation; either version 2, or (at your option)
-// any later version.
-
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-
-// You should have received a copy of the GNU General Public License along
-// with this library; see the file COPYING. If not, write to the Free
-// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
-// USA.
-
-// As a special exception, you may use this file as part of a free software
-// library without restriction. Specifically, if other files instantiate
-// templates or use macros or inline functions from this file, or you compile
-// this file and link it with other files to produce an executable, this
-// file does not by itself cause the resulting executable to be covered by
-// the GNU General Public License. This exception does not however
-// invalidate any other reasons why the executable file might be covered by
-// the GNU General Public License.
-
-/*
- * Copyright (c) 1996
- * Silicon Graphics Computer Systems, Inc.
- *
- * Permission to use, copy, modify, distribute and sell this software
- * and its documentation for any purpose is hereby granted without fee,
- * provided that the above copyright notice appear in all copies and
- * that both that copyright notice and this permission notice appear
- * in supporting documentation. Silicon Graphics makes no
- * representations about the suitability of this software for any
- * purpose. It is provided "as is" without express or implied warranty.
- */
-
-/** @file pthread_allocimpl.h
- * This is an internal header file, included by other library headers.
- * You should not attempt to use it directly.
- */
-
-#ifndef _CPP_BITS_PTHREAD_ALLOCIMPL_H
-#define _CPP_BITS_PTHREAD_ALLOCIMPL_H 1
-
-// Pthread-specific node allocator.
-// This is similar to the default allocator, except that free-list
-// information is kept separately for each thread, avoiding locking.
-// This should be reasonably fast even in the presence of threads.
-// The down side is that storage may not be well-utilized.
-// It is not an error to allocate memory in thread A and deallocate
-// it in thread B. But this effectively transfers ownership of the memory,
-// so that it can only be reallocated by thread B. Thus this can effectively
-// result in a storage leak if it's done on a regular basis.
-// It can also result in frequent sharing of
-// cache lines among processors, with potentially serious performance
-// consequences.
-
-#include <bits/c++config.h>
-#include <cerrno>
-#include <bits/stl_alloc.h>
-#ifndef __RESTRICT
-# define __RESTRICT
-#endif
-
-#include <new>
-
-namespace std
-{
-
-#define __STL_DATA_ALIGNMENT 8
-
-union _Pthread_alloc_obj {
- union _Pthread_alloc_obj * __free_list_link;
- char __client_data[__STL_DATA_ALIGNMENT]; /* The client sees this. */
-};
-
-// Pthread allocators don't appear to the client to have meaningful
-// instances. We do in fact need to associate some state with each
-// thread. That state is represented by
-// _Pthread_alloc_per_thread_state<_Max_size>.
-
-template<size_t _Max_size>
-struct _Pthread_alloc_per_thread_state {
- typedef _Pthread_alloc_obj __obj;
- enum { _S_NFREELISTS = _Max_size/__STL_DATA_ALIGNMENT };
- _Pthread_alloc_obj* volatile __free_list[_S_NFREELISTS];
- _Pthread_alloc_per_thread_state<_Max_size> * __next;
- // Free list link for list of available per thread structures.
- // When one of these becomes available for reuse due to thread
- // termination, any objects in its free list remain associated
- // with it. The whole structure may then be used by a newly
- // created thread.
- _Pthread_alloc_per_thread_state() : __next(0)
- {
- memset((void *)__free_list, 0, (size_t) _S_NFREELISTS * sizeof(__obj *));
- }
- // Returns an object of size __n, and possibly adds to size n free list.
- void *_M_refill(size_t __n);
-};
-
-// Pthread-specific allocator.
-// The argument specifies the largest object size allocated from per-thread
-// free lists. Larger objects are allocated using malloc_alloc.
-// Max_size must be a power of 2.
-template <size_t _Max_size = 128>
-class _Pthread_alloc_template {
-
-public: // but only for internal use:
-
- typedef _Pthread_alloc_obj __obj;
-
- // Allocates a chunk for nobjs of size size. nobjs may be reduced
- // if it is inconvenient to allocate the requested number.
- static char *_S_chunk_alloc(size_t __size, int &__nobjs);
-
- enum {_S_ALIGN = __STL_DATA_ALIGNMENT};
-
- static size_t _S_round_up(size_t __bytes) {
- return (((__bytes) + (int) _S_ALIGN-1) & ~((int) _S_ALIGN - 1));
- }
- static size_t _S_freelist_index(size_t __bytes) {
- return (((__bytes) + (int) _S_ALIGN-1)/(int)_S_ALIGN - 1);
- }
-
-private:
- // Chunk allocation state. And other shared state.
- // Protected by _S_chunk_allocator_lock.
- static pthread_mutex_t _S_chunk_allocator_lock;
- static char *_S_start_free;
- static char *_S_end_free;
- static size_t _S_heap_size;
- static _Pthread_alloc_per_thread_state<_Max_size>* _S_free_per_thread_states;
- static pthread_key_t _S_key;
- static bool _S_key_initialized;
- // Pthread key under which per thread state is stored.
- // Allocator instances that are currently unclaimed by any thread.
- static void _S_destructor(void *instance);
- // Function to be called on thread exit to reclaim per thread
- // state.
- static _Pthread_alloc_per_thread_state<_Max_size> *_S_new_per_thread_state();
- // Return a recycled or new per thread state.
- static _Pthread_alloc_per_thread_state<_Max_size> *_S_get_per_thread_state();
- // ensure that the current thread has an associated
- // per thread state.
- class _M_lock;
- friend class _M_lock;
- class _M_lock {
- public:
- _M_lock () { pthread_mutex_lock(&_S_chunk_allocator_lock); }
- ~_M_lock () { pthread_mutex_unlock(&_S_chunk_allocator_lock); }
- };
-
-public:
-
- /* n must be > 0 */
- static void * allocate(size_t __n)
- {
- __obj * volatile * __my_free_list;
- __obj * __RESTRICT __result;
- _Pthread_alloc_per_thread_state<_Max_size>* __a;
-
- if (__n > _Max_size) {
- return(malloc_alloc::allocate(__n));
- }
- if (!_S_key_initialized ||
- !(__a = (_Pthread_alloc_per_thread_state<_Max_size>*)
- pthread_getspecific(_S_key))) {
- __a = _S_get_per_thread_state();
- }
- __my_free_list = __a -> __free_list + _S_freelist_index(__n);
- __result = *__my_free_list;
- if (__result == 0) {
- void *__r = __a -> _M_refill(_S_round_up(__n));
- return __r;
- }
- *__my_free_list = __result -> __free_list_link;
- return (__result);
- };
-
- /* p may not be 0 */
- static void deallocate(void *__p, size_t __n)
- {
- __obj *__q = (__obj *)__p;
- __obj * volatile * __my_free_list;
- _Pthread_alloc_per_thread_state<_Max_size>* __a;
-
- if (__n > _Max_size) {
- malloc_alloc::deallocate(__p, __n);
- return;
- }
- if (!_S_key_initialized ||
- !(__a = (_Pthread_alloc_per_thread_state<_Max_size> *)
- pthread_getspecific(_S_key))) {
- __a = _S_get_per_thread_state();
- }
- __my_free_list = __a->__free_list + _S_freelist_index(__n);
- __q -> __free_list_link = *__my_free_list;
- *__my_free_list = __q;
- }
-
- static void * reallocate(void *__p, size_t __old_sz, size_t __new_sz);
-
-} ;
-
-typedef _Pthread_alloc_template<> pthread_alloc;
-
-
-template <size_t _Max_size>
-void _Pthread_alloc_template<_Max_size>::_S_destructor(void * __instance)
-{
- _M_lock __lock_instance; // Need to acquire lock here.
- _Pthread_alloc_per_thread_state<_Max_size>* __s =
- (_Pthread_alloc_per_thread_state<_Max_size> *)__instance;
- __s -> __next = _S_free_per_thread_states;
- _S_free_per_thread_states = __s;
-}
-
-template <size_t _Max_size>
-_Pthread_alloc_per_thread_state<_Max_size> *
-_Pthread_alloc_template<_Max_size>::_S_new_per_thread_state()
-{
- /* lock already held here. */
- if (0 != _S_free_per_thread_states) {
- _Pthread_alloc_per_thread_state<_Max_size> *__result =
- _S_free_per_thread_states;
- _S_free_per_thread_states = _S_free_per_thread_states -> __next;
- return __result;
- } else {
- return new _Pthread_alloc_per_thread_state<_Max_size>;
- }
-}
-
-template <size_t _Max_size>
-_Pthread_alloc_per_thread_state<_Max_size> *
-_Pthread_alloc_template<_Max_size>::_S_get_per_thread_state()
-{
- /*REFERENCED*/
- _M_lock __lock_instance; // Need to acquire lock here.
- int __ret_code;
- _Pthread_alloc_per_thread_state<_Max_size> * __result;
- if (!_S_key_initialized) {
- if (pthread_key_create(&_S_key, _S_destructor)) {
- std::__throw_bad_alloc(); // defined in funcexcept.h
- }
- _S_key_initialized = true;
- }
- __result = _S_new_per_thread_state();
- __ret_code = pthread_setspecific(_S_key, __result);
- if (__ret_code) {
- if (__ret_code == ENOMEM) {
- std::__throw_bad_alloc();
- } else {
- // EINVAL
- abort();
- }
- }
- return __result;
-}
-
-/* We allocate memory in large chunks in order to avoid fragmenting */
-/* the malloc heap too much. */
-/* We assume that size is properly aligned. */
-template <size_t _Max_size>
-char *_Pthread_alloc_template<_Max_size>
-::_S_chunk_alloc(size_t __size, int &__nobjs)
-{
- {
- char * __result;
- size_t __total_bytes;
- size_t __bytes_left;
- /*REFERENCED*/
- _M_lock __lock_instance; // Acquire lock for this routine
-
- __total_bytes = __size * __nobjs;
- __bytes_left = _S_end_free - _S_start_free;
- if (__bytes_left >= __total_bytes) {
- __result = _S_start_free;
- _S_start_free += __total_bytes;
- return(__result);
- } else if (__bytes_left >= __size) {
- __nobjs = __bytes_left/__size;
- __total_bytes = __size * __nobjs;
- __result = _S_start_free;
- _S_start_free += __total_bytes;
- return(__result);
- } else {
- size_t __bytes_to_get =
- 2 * __total_bytes + _S_round_up(_S_heap_size >> 4);
- // Try to make use of the left-over piece.
- if (__bytes_left > 0) {
- _Pthread_alloc_per_thread_state<_Max_size>* __a =
- (_Pthread_alloc_per_thread_state<_Max_size>*)
- pthread_getspecific(_S_key);
- __obj * volatile * __my_free_list =
- __a->__free_list + _S_freelist_index(__bytes_left);
-
- ((__obj *)_S_start_free) -> __free_list_link = *__my_free_list;
- *__my_free_list = (__obj *)_S_start_free;
- }
-# ifdef _SGI_SOURCE
- // Try to get memory that's aligned on something like a
- // cache line boundary, so as to avoid parceling out
- // parts of the same line to different threads and thus
- // possibly different processors.
- {
- const int __cache_line_size = 128; // probable upper bound
- __bytes_to_get &= ~(__cache_line_size-1);
- _S_start_free = (char *)memalign(__cache_line_size, __bytes_to_get);
- if (0 == _S_start_free) {
- _S_start_free = (char *)malloc_alloc::allocate(__bytes_to_get);
- }
- }
-# else /* !SGI_SOURCE */
- _S_start_free = (char *)malloc_alloc::allocate(__bytes_to_get);
-# endif
- _S_heap_size += __bytes_to_get;
- _S_end_free = _S_start_free + __bytes_to_get;
- }
- }
- // lock is released here
- return(_S_chunk_alloc(__size, __nobjs));
-}
-
-
-/* Returns an object of size n, and optionally adds to size n free list.*/
-/* We assume that n is properly aligned. */
-/* We hold the allocation lock. */
-template <size_t _Max_size>
-void *_Pthread_alloc_per_thread_state<_Max_size>
-::_M_refill(size_t __n)
-{
- int __nobjs = 128;
- char * __chunk =
- _Pthread_alloc_template<_Max_size>::_S_chunk_alloc(__n, __nobjs);
- __obj * volatile * __my_free_list;
- __obj * __result;
- __obj * __current_obj, * __next_obj;
- int __i;
-
- if (1 == __nobjs) {
- return(__chunk);
- }
- __my_free_list = __free_list
- + _Pthread_alloc_template<_Max_size>::_S_freelist_index(__n);
-
- /* Build free list in chunk */
- __result = (__obj *)__chunk;
- *__my_free_list = __next_obj = (__obj *)(__chunk + __n);
- for (__i = 1; ; __i++) {
- __current_obj = __next_obj;
- __next_obj = (__obj *)((char *)__next_obj + __n);
- if (__nobjs - 1 == __i) {
- __current_obj -> __free_list_link = 0;
- break;
- } else {
- __current_obj -> __free_list_link = __next_obj;
- }
- }
- return(__result);
-}
-
-template <size_t _Max_size>
-void *_Pthread_alloc_template<_Max_size>
-::reallocate(void *__p, size_t __old_sz, size_t __new_sz)
-{
- void * __result;
- size_t __copy_sz;
-
- if (__old_sz > _Max_size
- && __new_sz > _Max_size) {
- return(realloc(__p, __new_sz));
- }
- if (_S_round_up(__old_sz) == _S_round_up(__new_sz)) return(__p);
- __result = allocate(__new_sz);
- __copy_sz = __new_sz > __old_sz? __old_sz : __new_sz;
- memcpy(__result, __p, __copy_sz);
- deallocate(__p, __old_sz);
- return(__result);
-}
-
-template <size_t _Max_size>
-_Pthread_alloc_per_thread_state<_Max_size> *
-_Pthread_alloc_template<_Max_size>::_S_free_per_thread_states = 0;
-
-template <size_t _Max_size>
-pthread_key_t _Pthread_alloc_template<_Max_size>::_S_key;
-
-template <size_t _Max_size>
-bool _Pthread_alloc_template<_Max_size>::_S_key_initialized = false;
-
-template <size_t _Max_size>
-pthread_mutex_t _Pthread_alloc_template<_Max_size>::_S_chunk_allocator_lock
-= PTHREAD_MUTEX_INITIALIZER;
-
-template <size_t _Max_size>
-char *_Pthread_alloc_template<_Max_size>
-::_S_start_free = 0;
-
-template <size_t _Max_size>
-char *_Pthread_alloc_template<_Max_size>
-::_S_end_free = 0;
-
-template <size_t _Max_size>
-size_t _Pthread_alloc_template<_Max_size>
-::_S_heap_size = 0;
-
-
-template <class _Tp>
-class pthread_allocator {
- typedef pthread_alloc _S_Alloc; // The underlying allocator.
-public:
- typedef size_t size_type;
- typedef ptrdiff_t difference_type;
- typedef _Tp* pointer;
- typedef const _Tp* const_pointer;
- typedef _Tp& reference;
- typedef const _Tp& const_reference;
- typedef _Tp value_type;
-
- template <class _NewType> struct rebind {
- typedef pthread_allocator<_NewType> other;
- };
-
- pthread_allocator() throw() {}
- pthread_allocator(const pthread_allocator& a) throw() {}
- template <class _OtherType>
- pthread_allocator(const pthread_allocator<_OtherType>&)
- throw() {}
- ~pthread_allocator() throw() {}
-
- pointer address(reference __x) const { return &__x; }
- const_pointer address(const_reference __x) const { return &__x; }
-
- // __n is permitted to be 0. The C++ standard says nothing about what
- // the return value is when __n == 0.
- _Tp* allocate(size_type __n, const void* = 0) {
- return __n != 0 ? static_cast<_Tp*>(_S_Alloc::allocate(__n * sizeof(_Tp)))
- : 0;
- }
-
- // p is not permitted to be a null pointer.
- void deallocate(pointer __p, size_type __n)
- { _S_Alloc::deallocate(__p, __n * sizeof(_Tp)); }
-
- size_type max_size() const throw()
- { return size_t(-1) / sizeof(_Tp); }
-
- void construct(pointer __p, const _Tp& __val) { new(__p) _Tp(__val); }
- void destroy(pointer _p) { _p->~_Tp(); }
-};
-
-template<>
-class pthread_allocator<void> {
-public:
- typedef size_t size_type;
- typedef ptrdiff_t difference_type;
- typedef void* pointer;
- typedef const void* const_pointer;
- typedef void value_type;
-
- template <class _NewType> struct rebind {
- typedef pthread_allocator<_NewType> other;
- };
-};
-
-template <size_t _Max_size>
-inline bool operator==(const _Pthread_alloc_template<_Max_size>&,
- const _Pthread_alloc_template<_Max_size>&)
-{
- return true;
-}
-
-template <class _T1, class _T2>
-inline bool operator==(const pthread_allocator<_T1>&,
- const pthread_allocator<_T2>& a2)
-{
- return true;
-}
-
-template <class _T1, class _T2>
-inline bool operator!=(const pthread_allocator<_T1>&,
- const pthread_allocator<_T2>&)
-{
- return false;
-}
-
-template <class _Tp, size_t _Max_size>
-struct _Alloc_traits<_Tp, _Pthread_alloc_template<_Max_size> >
-{
- static const bool _S_instanceless = true;
- typedef simple_alloc<_Tp, _Pthread_alloc_template<_Max_size> > _Alloc_type;
- typedef __allocator<_Tp, _Pthread_alloc_template<_Max_size> >
- allocator_type;
-};
-
-template <class _Tp, class _Atype, size_t _Max>
-struct _Alloc_traits<_Tp, __allocator<_Atype, _Pthread_alloc_template<_Max> > >
-{
- static const bool _S_instanceless = true;
- typedef simple_alloc<_Tp, _Pthread_alloc_template<_Max> > _Alloc_type;
- typedef __allocator<_Tp, _Pthread_alloc_template<_Max> > allocator_type;
-};
-
-template <class _Tp, class _Atype>
-struct _Alloc_traits<_Tp, pthread_allocator<_Atype> >
-{
- static const bool _S_instanceless = true;
- typedef simple_alloc<_Tp, _Pthread_alloc_template<> > _Alloc_type;
- typedef pthread_allocator<_Tp> allocator_type;
-};
-
-
-} // namespace std
-
-#endif /* _CPP_BITS_PTHREAD_ALLOCIMPL_H */
-
-// Local Variables:
-// mode:C++
-// End:
diff --git a/libstdc++-v3/include/bits/stl_alloc.h b/libstdc++-v3/include/bits/stl_alloc.h
deleted file mode 100644
index 3d26d6d645d..00000000000
--- a/libstdc++-v3/include/bits/stl_alloc.h
+++ /dev/null
@@ -1,900 +0,0 @@
-// Allocators -*- C++ -*-
-
-// Copyright (C) 2001, 2002, 2003 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
-// terms of the GNU General Public License as published by the
-// Free Software Foundation; either version 2, or (at your option)
-// any later version.
-
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-
-// You should have received a copy of the GNU General Public License along
-// with this library; see the file COPYING. If not, write to the Free
-// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
-// USA.
-
-// As a special exception, you may use this file as part of a free software
-// library without restriction. Specifically, if other files instantiate
-// templates or use macros or inline functions from this file, or you compile
-// this file and link it with other files to produce an executable, this
-// file does not by itself cause the resulting executable to be covered by
-// the GNU General Public License. This exception does not however
-// invalidate any other reasons why the executable file might be covered by
-// the GNU General Public License.
-
-/*
- * Copyright (c) 1996-1997
- * Silicon Graphics Computer Systems, Inc.
- *
- * Permission to use, copy, modify, distribute and sell this software
- * and its documentation for any purpose is hereby granted without fee,
- * provided that the above copyright notice appear in all copies and
- * that both that copyright notice and this permission notice appear
- * in supporting documentation. Silicon Graphics makes no
- * representations about the suitability of this software for any
- * purpose. It is provided "as is" without express or implied warranty.
- */
-
-/** @file stl_alloc.h
- * This is an internal header file, included by other library headers.
- * You should not attempt to use it directly.
- */
-
-#ifndef __GLIBCPP_INTERNAL_ALLOC_H
-#define __GLIBCPP_INTERNAL_ALLOC_H
-
-/**
- * @defgroup Allocators Memory Allocators
- * @if maint
- * stl_alloc.h implements some node allocators. These are NOT the same as
- * allocators in the C++ standard, nor in the original H-P STL. They do not
- * encapsulate different pointer types; we assume that there is only one
- * pointer type. The C++ standard allocators are intended to allocate
- * individual objects, not pools or arenas.
- *
- * In this file allocators are of two different styles: "standard" and
- * "SGI" (quotes included). "Standard" allocators conform to 20.4. "SGI"
- * allocators differ in AT LEAST the following ways (add to this list as you
- * discover them):
- *
- * - "Standard" allocate() takes two parameters (n_count,hint=0) but "SGI"
- * allocate() takes one paramter (n_size).
- * - Likewise, "standard" deallocate()'s argument is a count, but in "SGI"
- * is a byte size.
- * - max_size(), construct(), and destroy() are missing in "SGI" allocators.
- * - reallocate(p,oldsz,newsz) is added in "SGI", and behaves as
- * if p=realloc(p,newsz).
- *
- * "SGI" allocators may be wrapped in __allocator to convert the interface
- * into a "standard" one.
- * @endif
- *
- * The canonical description of these classes is in docs/html/ext/howto.html
- * or online at http://gcc.gnu.org/onlinedocs/libstdc++/ext/howto.html#3
-*/
-
-#include <cstddef>
-#include <cstdlib>
-#include <cstring>
-#include <bits/functexcept.h> // For __throw_bad_alloc
-#include <bits/stl_threads.h>
-#include <bits/atomicity.h>
-
-namespace std
-{
- /**
- * @if maint
- * A new-based allocator, as required by the standard. Allocation and
- * deallocation forward to global new and delete. "SGI" style, minus
- * reallocate().
- * @endif
- * (See @link Allocators allocators info @endlink for more.)
- */
- class __new_alloc
- {
- public:
- static void*
- allocate(size_t __n)
- { return ::operator new(__n); }
-
- static void
- deallocate(void* __p, size_t)
- { ::operator delete(__p); }
- };
-
-
- /**
- * @if maint
- * A malloc-based allocator. Typically slower than the
- * __pool_alloc (below). Typically thread-safe and more
- * storage efficient. The template argument is unused and is only present
- * to permit multiple instantiations (but see __pool_alloc
- * for caveats). "SGI" style, plus __set_malloc_handler for OOM conditions.
- * @endif
- * (See @link Allocators allocators info @endlink for more.)
- */
- template<int __inst>
- class __malloc_alloc
- {
- private:
- static void* _S_oom_malloc(size_t);
- static void (* __malloc_alloc_oom_handler)();
-
- public:
- static void*
- allocate(size_t __n)
- {
- void* __result = malloc(__n);
- if (__builtin_expect(__result == 0, 0))
- __result = _S_oom_malloc(__n);
- return __result;
- }
-
- static void
- deallocate(void* __p, size_t /* __n */)
- { free(__p); }
-
- static void (* __set_malloc_handler(void (*__f)()))()
- {
- void (* __old)() = __malloc_alloc_oom_handler;
- __malloc_alloc_oom_handler = __f;
- return __old;
- }
- };
-
- // malloc_alloc out-of-memory handling
- template<int __inst>
- void (* __malloc_alloc<__inst>::__malloc_alloc_oom_handler)() = 0;
-
- template<int __inst>
- void*
- __malloc_alloc<__inst>::
- _S_oom_malloc(size_t __n)
- {
- void (* __my_malloc_handler)();
- void* __result;
-
- for (;;)
- {
- __my_malloc_handler = __malloc_alloc_oom_handler;
- if (__builtin_expect(__my_malloc_handler == 0, 0))
- __throw_bad_alloc();
- (*__my_malloc_handler)();
- __result = malloc(__n);
- if (__result)
- return __result;
- }
- }
-
-
- /**
- * @if maint
- * This is used primarily (only?) in _Alloc_traits and other places to
- * help provide the _Alloc_type typedef. All it does is forward the
- * requests after some minimal checking.
- *
- * This is neither "standard"-conforming nor "SGI". The _Alloc parameter
- * must be "SGI" style.
- * @endif
- * (See @link Allocators allocators info @endlink for more.)
- */
- template<typename _Tp, typename _Alloc>
- class __simple_alloc
- {
- public:
- static _Tp*
- allocate(size_t __n)
- {
- _Tp* __ret = 0;
- if (__n)
- __ret = static_cast<_Tp*>(_Alloc::allocate(__n * sizeof(_Tp)));
- return __ret;
- }
-
- static _Tp*
- allocate()
- { return (_Tp*) _Alloc::allocate(sizeof (_Tp)); }
-
- static void
- deallocate(_Tp* __p, size_t __n)
- { if (0 != __n) _Alloc::deallocate(__p, __n * sizeof (_Tp)); }
-
- static void
- deallocate(_Tp* __p)
- { _Alloc::deallocate(__p, sizeof (_Tp)); }
- };
-
-
- /**
- * @if maint
- * An adaptor for an underlying allocator (_Alloc) to check the size
- * arguments for debugging.
- *
- * "There is some evidence that this can confuse Purify." - SGI comment
- *
- * This adaptor is "SGI" style. The _Alloc parameter must also be "SGI".
- * @endif
- * (See @link Allocators allocators info @endlink for more.)
- */
- template<typename _Alloc>
- class __debug_alloc
- {
- private:
- // Size of space used to store size. Note that this must be
- // large enough to preserve alignment.
- enum {_S_extra = 8};
-
- public:
- static void*
- allocate(size_t __n)
- {
- char* __result = (char*)_Alloc::allocate(__n + (int) _S_extra);
- *(size_t*)__result = __n;
- return __result + (int) _S_extra;
- }
-
- static void
- deallocate(void* __p, size_t __n)
- {
- char* __real_p = (char*)__p - (int) _S_extra;
- if (*(size_t*)__real_p != __n)
- abort();
- _Alloc::deallocate(__real_p, __n + (int) _S_extra);
- }
- };
-
-
- /**
- * @if maint
- * Default node allocator. "SGI" style. Uses various allocators to
- * fulfill underlying requests (and makes as few requests as possible
- * when in default high-speed pool mode).
- *
- * Important implementation properties:
- * 0. If globally mandated, then allocate objects from __new_alloc
- * 1. If the clients request an object of size > _S_max_bytes, the resulting
- * object will be obtained directly from __new_alloc
- * 2. In all other cases, we allocate an object of size exactly
- * _S_round_up(requested_size). Thus the client has enough size
- * information that we can return the object to the proper free list
- * without permanently losing part of the object.
- *
- * The first template parameter specifies whether more than one thread may
- * use this allocator. It is safe to allocate an object from one instance
- * of a default_alloc and deallocate it with another one. This effectively
- * 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.
- *
- * @endif
- * (See @link Allocators allocators info @endlink for more.)
- */
- template<bool __threads, int __inst>
- class __pool_alloc
- {
- private:
- enum {_S_align = 8};
- enum {_S_max_bytes = 128};
- enum {_S_freelists = _S_max_bytes / _S_align};
-
- union _Obj
- {
- union _Obj* _M_free_list_link;
- char _M_client_data[1]; // The client sees this.
- };
-
- static _Obj* volatile _S_free_list[_S_freelists];
-
- // Chunk allocation state.
- static char* _S_start_free;
- static char* _S_end_free;
- static size_t _S_heap_size;
-
- static _STL_mutex_lock _S_lock;
- static _Atomic_word _S_force_new;
-
- static size_t
- _S_round_up(size_t __bytes)
- { return (((__bytes) + (size_t) _S_align-1) & ~((size_t) _S_align - 1)); }
-
- static size_t
- _S_freelist_index(size_t __bytes)
- { return (((__bytes) + (size_t)_S_align - 1)/(size_t)_S_align - 1); }
-
- // Returns an object of size __n, and optionally adds to size __n
- // free list.
- static void*
- _S_refill(size_t __n);
-
- // Allocates a chunk for nobjs of size size. nobjs may be reduced
- // if it is inconvenient to allocate the requested number.
- static char*
- _S_chunk_alloc(size_t __size, int& __nobjs);
-
- // It would be nice to use _STL_auto_lock here. But we need a
- // test whether threads are in use.
- struct _Lock
- {
- _Lock() { if (__threads) _S_lock._M_acquire_lock(); }
- ~_Lock() { if (__threads) _S_lock._M_release_lock(); }
- } __attribute__ ((__unused__));
- friend struct _Lock;
-
- public:
- // __n must be > 0
- static void*
- allocate(size_t __n)
- {
- void* __ret = 0;
-
- // If there is a race through here, assume answer from getenv
- // will resolve in same direction. Inspired by techniques
- // to efficiently support threading found in basic_string.h.
- if (_S_force_new == 0)
- {
- if (getenv("GLIBCPP_FORCE_NEW"))
- __atomic_add(&_S_force_new, 1);
- else
- __atomic_add(&_S_force_new, -1);
- }
-
- if ((__n > (size_t) _S_max_bytes) || (_S_force_new > 0))
- __ret = __new_alloc::allocate(__n);
- else
- {
- _Obj* volatile* __my_free_list = _S_free_list
- + _S_freelist_index(__n);
- // Acquire the lock here with a constructor call. This
- // ensures that it is released in exit or during stack
- // unwinding.
- _Lock __lock_instance;
- _Obj* __restrict__ __result = *__my_free_list;
- if (__builtin_expect(__result == 0, 0))
- __ret = _S_refill(_S_round_up(__n));
- else
- {
- *__my_free_list = __result -> _M_free_list_link;
- __ret = __result;
- }
- if (__builtin_expect(__ret == 0, 0))
- __throw_bad_alloc();
- }
- return __ret;
- }
-
- // __p may not be 0
- static void
- deallocate(void* __p, size_t __n)
- {
- if ((__n > (size_t) _S_max_bytes) || (_S_force_new > 0))
- __new_alloc::deallocate(__p, __n);
- else
- {
- _Obj* volatile* __my_free_list = _S_free_list
- + _S_freelist_index(__n);
- _Obj* __q = (_Obj*)__p;
-
- // Acquire the lock here with a constructor call. This
- // ensures that it is released in exit or during stack
- // unwinding.
- _Lock __lock_instance;
- __q -> _M_free_list_link = *__my_free_list;
- *__my_free_list = __q;
- }
- }
- };
-
- template<bool __threads, int __inst> _Atomic_word
- __pool_alloc<__threads, __inst>::_S_force_new = 0;
-
- template<bool __threads, int __inst>
- inline bool
- operator==(const __pool_alloc<__threads,__inst>&,
- const __pool_alloc<__threads,__inst>&)
- { return true; }
-
- template<bool __threads, int __inst>
- inline bool
- operator!=(const __pool_alloc<__threads,__inst>&,
- const __pool_alloc<__threads,__inst>&)
- { return false; }
-
-
- // We allocate memory in large chunks in order to avoid fragmenting the
- // heap too much. We assume that __size is properly aligned. We hold
- // the allocation lock.
- template<bool __threads, int __inst>
- char*
- __pool_alloc<__threads, __inst>::
- _S_chunk_alloc(size_t __size, int& __nobjs)
- {
- char* __result;
- size_t __total_bytes = __size * __nobjs;
- size_t __bytes_left = _S_end_free - _S_start_free;
-
- if (__bytes_left >= __total_bytes)
- {
- __result = _S_start_free;
- _S_start_free += __total_bytes;
- return __result ;
- }
- else if (__bytes_left >= __size)
- {
- __nobjs = (int)(__bytes_left/__size);
- __total_bytes = __size * __nobjs;
- __result = _S_start_free;
- _S_start_free += __total_bytes;
- return __result;
- }
- else
- {
- size_t __bytes_to_get =
- 2 * __total_bytes + _S_round_up(_S_heap_size >> 4);
- // Try to make use of the left-over piece.
- if (__bytes_left > 0)
- {
- _Obj* volatile* __my_free_list =
- _S_free_list + _S_freelist_index(__bytes_left);
-
- ((_Obj*)(void*)_S_start_free) -> _M_free_list_link = *__my_free_list;
- *__my_free_list = (_Obj*)(void*)_S_start_free;
- }
- _S_start_free = (char*) __new_alloc::allocate(__bytes_to_get);
- if (_S_start_free == 0)
- {
- size_t __i;
- _Obj* volatile* __my_free_list;
- _Obj* __p;
- // Try to make do with what we have. That can't hurt. We
- // do not try smaller requests, since that tends to result
- // in disaster on multi-process machines.
- __i = __size;
- for (; __i <= (size_t) _S_max_bytes; __i += (size_t) _S_align)
- {
- __my_free_list = _S_free_list + _S_freelist_index(__i);
- __p = *__my_free_list;
- if (__p != 0)
- {
- *__my_free_list = __p -> _M_free_list_link;
- _S_start_free = (char*)__p;
- _S_end_free = _S_start_free + __i;
- return _S_chunk_alloc(__size, __nobjs);
- // Any leftover piece will eventually make it to the
- // right free list.
- }
- }
- _S_end_free = 0; // In case of exception.
- _S_start_free = (char*)__new_alloc::allocate(__bytes_to_get);
- // This should either throw an exception or remedy the situation.
- // Thus we assume it succeeded.
- }
- _S_heap_size += __bytes_to_get;
- _S_end_free = _S_start_free + __bytes_to_get;
- return _S_chunk_alloc(__size, __nobjs);
- }
- }
-
-
- // Returns an object of size __n, and optionally adds to "size
- // __n"'s free list. We assume that __n is properly aligned. We
- // hold the allocation lock.
- template<bool __threads, int __inst>
- void*
- __pool_alloc<__threads, __inst>::_S_refill(size_t __n)
- {
- int __nobjs = 20;
- char* __chunk = _S_chunk_alloc(__n, __nobjs);
- _Obj* volatile* __my_free_list;
- _Obj* __result;
- _Obj* __current_obj;
- _Obj* __next_obj;
- int __i;
-
- if (1 == __nobjs)
- return __chunk;
- __my_free_list = _S_free_list + _S_freelist_index(__n);
-
- // Build free list in chunk.
- __result = (_Obj*)(void*)__chunk;
- *__my_free_list = __next_obj = (_Obj*)(void*)(__chunk + __n);
- for (__i = 1; ; __i++)
- {
- __current_obj = __next_obj;
- __next_obj = (_Obj*)(void*)((char*)__next_obj + __n);
- if (__nobjs - 1 == __i)
- {
- __current_obj -> _M_free_list_link = 0;
- break;
- }
- else
- __current_obj -> _M_free_list_link = __next_obj;
- }
- return __result;
- }
-
-
- template<bool __threads, int __inst>
- _STL_mutex_lock
- __pool_alloc<__threads,__inst>::_S_lock __STL_MUTEX_INITIALIZER;
-
- template<bool __threads, int __inst>
- char* __pool_alloc<__threads,__inst>::_S_start_free = 0;
-
- template<bool __threads, int __inst>
- char* __pool_alloc<__threads,__inst>::_S_end_free = 0;
-
- template<bool __threads, int __inst>
- size_t __pool_alloc<__threads,__inst>::_S_heap_size = 0;
-
- template<bool __threads, int __inst>
- typename __pool_alloc<__threads,__inst>::_Obj* volatile
- __pool_alloc<__threads,__inst>::_S_free_list[_S_freelists];
-
- typedef __pool_alloc<true,0> __alloc;
- typedef __pool_alloc<false,0> __single_client_alloc;
-
-
- /**
- * @brief The "standard" allocator, as per [20.4].
- *
- * The private _Alloc is "SGI" style. (See comments at the top
- * of stl_alloc.h.)
- *
- * The underlying allocator behaves as follows.
- * - __pool_alloc is used via two typedefs
- * - "__single_client_alloc" typedef does no locking for threads
- * - "__alloc" typedef is threadsafe via the locks
- * - __new_alloc is used for memory requests
- *
- * (See @link Allocators allocators info @endlink for more.)
- */
- template<typename _Tp>
- class allocator
- {
- typedef __alloc _Alloc; // The underlying allocator.
- public:
- typedef size_t size_type;
- typedef ptrdiff_t difference_type;
- typedef _Tp* pointer;
- typedef const _Tp* const_pointer;
- typedef _Tp& reference;
- typedef const _Tp& const_reference;
- typedef _Tp value_type;
-
- template<typename _Tp1>
- struct rebind
- { typedef allocator<_Tp1> other; };
-
- allocator() throw() {}
- allocator(const allocator&) throw() {}
- template<typename _Tp1>
- allocator(const allocator<_Tp1>&) throw() {}
- ~allocator() throw() {}
-
- pointer
- address(reference __x) const { return &__x; }
-
- const_pointer
- address(const_reference __x) const { return &__x; }
-
- // NB: __n is permitted to be 0. The C++ standard says nothing
- // about what the return value is when __n == 0.
- _Tp*
- allocate(size_type __n, const void* = 0)
- {
- _Tp* __ret = 0;
- if (__n)
- {
- if (__n <= this->max_size())
- __ret = static_cast<_Tp*>(_Alloc::allocate(__n * sizeof(_Tp)));
- else
- __throw_bad_alloc();
- }
- return __ret;
- }
-
- // __p is not permitted to be a null pointer.
- void
- deallocate(pointer __p, size_type __n)
- { _Alloc::deallocate(__p, __n * sizeof(_Tp)); }
-
- size_type
- max_size() const throw() { return size_t(-1) / sizeof(_Tp); }
-
- void construct(pointer __p, const _Tp& __val) { new(__p) _Tp(__val); }
- void destroy(pointer __p) { __p->~_Tp(); }
- };
-
- template<>
- class allocator<void>
- {
- public:
- typedef size_t size_type;
- typedef ptrdiff_t difference_type;
- typedef void* pointer;
- typedef const void* const_pointer;
- typedef void value_type;
-
- template<typename _Tp1>
- struct rebind
- { typedef allocator<_Tp1> other; };
- };
-
-
- template<typename _T1, typename _T2>
- inline bool
- operator==(const allocator<_T1>&, const allocator<_T2>&)
- { return true; }
-
- template<typename _T1, typename _T2>
- inline bool
- operator!=(const allocator<_T1>&, const allocator<_T2>&)
- { return false; }
-
-
- /**
- * @if maint
- * Allocator adaptor to turn an "SGI" style allocator (e.g.,
- * __alloc, __malloc_alloc) into a "standard" conforming
- * allocator. Note that this adaptor does *not* assume that all
- * objects of the underlying alloc class are identical, nor does it
- * assume that all of the underlying alloc's member functions are
- * static member functions. Note, also, that __allocator<_Tp,
- * __alloc> is essentially the same thing as allocator<_Tp>.
- * @endif
- * (See @link Allocators allocators info @endlink for more.)
- */
- template<typename _Tp, typename _Alloc>
- struct __allocator
- {
- _Alloc __underlying_alloc;
-
- typedef size_t size_type;
- typedef ptrdiff_t difference_type;
- typedef _Tp* pointer;
- typedef const _Tp* const_pointer;
- typedef _Tp& reference;
- typedef const _Tp& const_reference;
- typedef _Tp value_type;
-
- template<typename _Tp1>
- struct rebind
- { typedef __allocator<_Tp1, _Alloc> other; };
-
- __allocator() throw() {}
- __allocator(const __allocator& __a) throw()
- : __underlying_alloc(__a.__underlying_alloc) {}
-
- template<typename _Tp1>
- __allocator(const __allocator<_Tp1, _Alloc>& __a) throw()
- : __underlying_alloc(__a.__underlying_alloc) {}
-
- ~__allocator() throw() {}
-
- pointer
- address(reference __x) const { return &__x; }
-
- const_pointer
- address(const_reference __x) const { return &__x; }
-
- // NB: __n is permitted to be 0. The C++ standard says nothing
- // about what the return value is when __n == 0.
- _Tp*
- allocate(size_type __n, const void* = 0)
- {
- _Tp* __ret = 0;
- if (__n)
- __ret = static_cast<_Tp*>(_Alloc::allocate(__n * sizeof(_Tp)));
- return __ret;
- }
-
- // __p is not permitted to be a null pointer.
- void
- deallocate(pointer __p, size_type __n)
- { __underlying_alloc.deallocate(__p, __n * sizeof(_Tp)); }
-
- size_type
- max_size() const throw() { return size_t(-1) / sizeof(_Tp); }
-
- void
- construct(pointer __p, const _Tp& __val) { new(__p) _Tp(__val); }
-
- void
- destroy(pointer __p) { __p->~_Tp(); }
- };
-
- template<typename _Alloc>
- struct __allocator<void, _Alloc>
- {
- typedef size_t size_type;
- typedef ptrdiff_t difference_type;
- typedef void* pointer;
- typedef const void* const_pointer;
- typedef void value_type;
-
- template<typename _Tp1>
- struct rebind
- { typedef __allocator<_Tp1, _Alloc> other; };
- };
-
- template<typename _Tp, typename _Alloc>
- inline bool
- operator==(const __allocator<_Tp,_Alloc>& __a1,
- const __allocator<_Tp,_Alloc>& __a2)
- { return __a1.__underlying_alloc == __a2.__underlying_alloc; }
-
- template<typename _Tp, typename _Alloc>
- inline bool
- operator!=(const __allocator<_Tp, _Alloc>& __a1,
- const __allocator<_Tp, _Alloc>& __a2)
- { return __a1.__underlying_alloc != __a2.__underlying_alloc; }
-
-
- //@{
- /** Comparison operators for all of the predifined SGI-style allocators.
- * This ensures that __allocator<malloc_alloc> (for example) will work
- * correctly. As required, all allocators compare equal.
- */
- template<int inst>
- inline bool
- operator==(const __malloc_alloc<inst>&,
- const __malloc_alloc<inst>&)
- { return true; }
-
- template<int __inst>
- inline bool
- operator!=(const __malloc_alloc<__inst>&,
- const __malloc_alloc<__inst>&)
- { return false; }
-
- template<typename _Alloc>
- inline bool
- operator==(const __debug_alloc<_Alloc>&, const __debug_alloc<_Alloc>&)
- { return true; }
-
- template<typename _Alloc>
- inline bool
- operator!=(const __debug_alloc<_Alloc>&, const __debug_alloc<_Alloc>&)
- { return false; }
- //@}
-
-
- /**
- * @if maint
- * Another allocator adaptor: _Alloc_traits. This serves two purposes.
- * First, make it possible to write containers that can use either "SGI"
- * style allocators or "standard" allocators. Second, provide a mechanism
- * so that containers can query whether or not the allocator has distinct
- * instances. If not, the container can avoid wasting a word of memory to
- * store an empty object. For examples of use, see stl_vector.h, etc, or
- * any of the other classes derived from this one.
- *
- * This adaptor uses partial specialization. The general case of
- * _Alloc_traits<_Tp, _Alloc> assumes that _Alloc is a
- * standard-conforming allocator, possibly with non-equal instances and
- * non-static members. (It still behaves correctly even if _Alloc has
- * static member and if all instances are equal. Refinements affect
- * performance, not correctness.)
- *
- * There are always two members: allocator_type, which is a standard-
- * conforming allocator type for allocating objects of type _Tp, and
- * _S_instanceless, a static const member of type bool. If
- * _S_instanceless is true, this means that there is no difference
- * between any two instances of type allocator_type. Furthermore, if
- * _S_instanceless is true, then _Alloc_traits has one additional
- * member: _Alloc_type. This type encapsulates allocation and
- * deallocation of objects of type _Tp through a static interface; it
- * has two member functions, whose signatures are
- *
- * - static _Tp* allocate(size_t)
- * - static void deallocate(_Tp*, size_t)
- *
- * The size_t parameters are "standard" style (see top of stl_alloc.h) in
- * that they take counts, not sizes.
- *
- * @endif
- * (See @link Allocators allocators info @endlink for more.)
- */
- //@{
- // The fully general version.
- template<typename _Tp, typename _Allocator>
- struct _Alloc_traits
- {
- static const bool _S_instanceless = false;
- typedef typename _Allocator::template rebind<_Tp>::other allocator_type;
- };
-
- template<typename _Tp, typename _Allocator>
- const bool _Alloc_traits<_Tp, _Allocator>::_S_instanceless;
-
- /// The version for the default allocator.
- template<typename _Tp, typename _Tp1>
- struct _Alloc_traits<_Tp, allocator<_Tp1> >
- {
- static const bool _S_instanceless = true;
- typedef __simple_alloc<_Tp, __alloc> _Alloc_type;
- typedef allocator<_Tp> allocator_type;
- };
- //@}
-
- //@{
- /// Versions for the predefined "SGI" style allocators.
- template<typename _Tp, int __inst>
- struct _Alloc_traits<_Tp, __malloc_alloc<__inst> >
- {
- static const bool _S_instanceless = true;
- typedef __simple_alloc<_Tp, __malloc_alloc<__inst> > _Alloc_type;
- typedef __allocator<_Tp, __malloc_alloc<__inst> > allocator_type;
- };
-
- template<typename _Tp, bool __threads, int __inst>
- struct _Alloc_traits<_Tp, __pool_alloc<__threads, __inst> >
- {
- static const bool _S_instanceless = true;
- typedef __simple_alloc<_Tp, __pool_alloc<__threads, __inst> >
- _Alloc_type;
- typedef __allocator<_Tp, __pool_alloc<__threads, __inst> >
- allocator_type;
- };
-
- template<typename _Tp, typename _Alloc>
- struct _Alloc_traits<_Tp, __debug_alloc<_Alloc> >
- {
- static const bool _S_instanceless = true;
- typedef __simple_alloc<_Tp, __debug_alloc<_Alloc> > _Alloc_type;
- typedef __allocator<_Tp, __debug_alloc<_Alloc> > allocator_type;
- };
- //@}
-
- //@{
- /// Versions for the __allocator adaptor used with the predefined
- /// "SGI" style allocators.
- template<typename _Tp, typename _Tp1, int __inst>
- struct _Alloc_traits<_Tp,
- __allocator<_Tp1, __malloc_alloc<__inst> > >
- {
- static const bool _S_instanceless = true;
- typedef __simple_alloc<_Tp, __malloc_alloc<__inst> > _Alloc_type;
- typedef __allocator<_Tp, __malloc_alloc<__inst> > allocator_type;
- };
-
- template<typename _Tp, typename _Tp1, bool __thr, int __inst>
- struct _Alloc_traits<_Tp, __allocator<_Tp1, __pool_alloc<__thr, __inst> > >
- {
- static const bool _S_instanceless = true;
- typedef __simple_alloc<_Tp, __pool_alloc<__thr,__inst> >
- _Alloc_type;
- typedef __allocator<_Tp, __pool_alloc<__thr,__inst> >
- allocator_type;
- };
-
- template<typename _Tp, typename _Tp1, typename _Alloc>
- struct _Alloc_traits<_Tp, __allocator<_Tp1, __debug_alloc<_Alloc> > >
- {
- static const bool _S_instanceless = true;
- typedef __simple_alloc<_Tp, __debug_alloc<_Alloc> > _Alloc_type;
- typedef __allocator<_Tp, __debug_alloc<_Alloc> > allocator_type;
- };
- //@}
-
- // Inhibit implicit instantiations for required instantiations,
- // which are defined via explicit instantiations elsewhere.
- // NB: This syntax is a GNU extension.
-#if _GLIBCPP_EXTERN_TEMPLATE
- extern template class allocator<char>;
- extern template class allocator<wchar_t>;
- extern template class __pool_alloc<true,0>;
-#endif
-} // namespace std
-
-#endif
diff --git a/libstdc++-v3/include/bits/stl_deque.h b/libstdc++-v3/include/bits/stl_deque.h
index 8805b7589f6..5863af55a35 100644
--- a/libstdc++-v3/include/bits/stl_deque.h
+++ b/libstdc++-v3/include/bits/stl_deque.h
@@ -340,7 +340,7 @@ namespace std
* and destructor allocate (but don't initialize) storage. This makes
* %exception safety easier. Second, the base class encapsulates all of
* the differences between SGI-style allocators and standard-conforming
- * allocators. (See stl_alloc.h for more on this topic.) There are two
+ * allocators. (See allocator.h for more on this topic.) There are two
* versions: this ordinary one, and the space-saving specialization for
* instanceless allocators.
* @endif
diff --git a/libstdc++-v3/include/bits/stl_threads.h b/libstdc++-v3/include/bits/stl_threads.h
index a95fc38a423..1fb68f01e5f 100644
--- a/libstdc++-v3/include/bits/stl_threads.h
+++ b/libstdc++-v3/include/bits/stl_threads.h
@@ -48,6 +48,8 @@
#ifndef __SGI_STL_INTERNAL_THREADS_H
#define __SGI_STL_INTERNAL_THREADS_H
+#include <cstddef>
+
// The only supported threading model is GCC's own gthr.h abstraction layer.
#include "bits/gthr.h"
@@ -209,7 +211,6 @@ namespace std
void operator=(const _STL_auto_lock&);
_STL_auto_lock(const _STL_auto_lock&);
} __attribute__ ((__unused__));
-
} // namespace std
#endif
diff --git a/libstdc++-v3/include/bits/stl_tree.h b/libstdc++-v3/include/bits/stl_tree.h
index 2965d4caab5..895b98a6a52 100644
--- a/libstdc++-v3/include/bits/stl_tree.h
+++ b/libstdc++-v3/include/bits/stl_tree.h
@@ -84,7 +84,7 @@ iterators invalidated are those referring to the deleted node.
*/
#include <bits/stl_algobase.h>
-#include <bits/stl_alloc.h>
+#include <bits/allocator.h>
#include <bits/stl_construct.h>
#include <bits/stl_function.h>
diff --git a/libstdc++-v3/include/ext/debug_allocator.h b/libstdc++-v3/include/ext/debug_allocator.h
new file mode 100644
index 00000000000..0f7eb0c653d
--- /dev/null
+++ b/libstdc++-v3/include/ext/debug_allocator.h
@@ -0,0 +1,139 @@
+// Allocators -*- C++ -*-
+
+// Copyright (C) 2001, 2002, 2003 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
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// As a special exception, you may use this file as part of a free software
+// library without restriction. Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License. This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+/*
+ * Copyright (c) 1996-1997
+ * Silicon Graphics Computer Systems, Inc.
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Silicon Graphics makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ */
+
+/** @file ext/debug_allocator.h
+ * This file is a GNU extension to the Standard C++ Library.
+ * You should only include this header if you are using GCC 3 or later.
+ */
+
+#ifndef _DEBUG_ALLOCATOR_H
+#define _DEBUG_ALLOCATOR_H 1
+
+#include <bits/allocator_traits.h>
+
+namespace __gnu_cxx
+{
+ /**
+ * @if maint
+ * An adaptor for an underlying allocator (_Alloc) to check the size
+ * arguments for debugging.
+ *
+ * "There is some evidence that this can confuse Purify." - SGI comment
+ *
+ * This adaptor is "SGI" style. The _Alloc parameter must also be "SGI".
+ * @endif
+ * (See @link Allocators allocators info @endlink for more.)
+ */
+ template<typename _Alloc>
+ class __debug_alloc
+ {
+ private:
+ // Size of space used to store size. Note that this must be
+ // large enough to preserve alignment.
+ enum {_S_extra = 8};
+
+ public:
+ static void*
+ allocate(size_t __n)
+ {
+ char* __result = (char*)_Alloc::allocate(__n + (int) _S_extra);
+ *(size_t*)__result = __n;
+ return __result + (int) _S_extra;
+ }
+
+ static void
+ deallocate(void* __p, size_t __n)
+ {
+ char* __real_p = (char*)__p - (int) _S_extra;
+ if (*(size_t*)__real_p != __n)
+ abort();
+ _Alloc::deallocate(__real_p, __n + (int) _S_extra);
+ }
+ };
+
+ //@{
+ /** Comparison operators for all of the predifined SGI-style allocators.
+ * This ensures that __allocator<malloc_alloc> (for example) will work
+ * correctly. As required, all allocators compare equal.
+ */
+ template<typename _Alloc>
+ inline bool
+ operator==(const __debug_alloc<_Alloc>&, const __debug_alloc<_Alloc>&)
+ { return true; }
+
+ template<typename _Alloc>
+ inline bool
+ operator!=(const __debug_alloc<_Alloc>&, const __debug_alloc<_Alloc>&)
+ { return false; }
+ //@}
+} // namespace __gnu_cxx
+
+namespace std
+{
+ //@{
+ /// Versions for the predefined "SGI" style allocators.
+ template<typename _Tp, typename _Alloc>
+ struct _Alloc_traits<_Tp, __gnu_cxx::__debug_alloc<_Alloc> >
+ {
+ static const bool _S_instanceless = true;
+ typedef __gnu_cxx::__debug_alloc<_Alloc> base_alloc_type;
+ typedef __simple_alloc<_Tp, base_alloc_type> _Alloc_type;
+ typedef __allocator<_Tp, base_alloc_type> allocator_type;
+ };
+ //@}
+
+ //@{
+ /// Versions for the __allocator adaptor used with the predefined
+ /// "SGI" style allocators.
+ template<typename _Tp, typename _Tp1, typename _Alloc>
+ struct _Alloc_traits<_Tp, __allocator<_Tp1,
+ __gnu_cxx::__debug_alloc<_Alloc> > >
+ {
+ static const bool _S_instanceless = true;
+ typedef __gnu_cxx::__debug_alloc<_Alloc> base_alloc_type;
+ typedef __simple_alloc<_Tp, base_alloc_type> _Alloc_type;
+ typedef __allocator<_Tp, base_alloc_type> allocator_type;
+ };
+ //@}
+} // namespace std
+
+#endif
diff --git a/libstdc++-v3/include/ext/malloc_allocator.h b/libstdc++-v3/include/ext/malloc_allocator.h
new file mode 100644
index 00000000000..410b296e09d
--- /dev/null
+++ b/libstdc++-v3/include/ext/malloc_allocator.h
@@ -0,0 +1,163 @@
+// Allocators -*- C++ -*-
+
+// Copyright (C) 2001, 2002, 2003 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
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// As a special exception, you may use this file as part of a free software
+// library without restriction. Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License. This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+/*
+ * Copyright (c) 1996-1997
+ * Silicon Graphics Computer Systems, Inc.
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Silicon Graphics makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ */
+
+/** @file ext/debug_allocator.h
+ * This file is a GNU extension to the Standard C++ Library.
+ * You should only include this header if you are using GCC 3 or later.
+ */
+
+#ifndef _MALLOC_ALLOCATOR_H
+#define _MALLOC_ALLOCATOR_H 1
+
+#include <bits/allocator_traits.h>
+
+namespace __gnu_cxx
+{
+ /**
+ * @if maint
+ * A malloc-based allocator. Typically slower than the
+ * __pool_alloc (below). Typically thread-safe and more
+ * storage efficient. The template argument is unused and is only present
+ * to permit multiple instantiations (but see __pool_alloc
+ * for caveats). "SGI" style, plus __set_malloc_handler for OOM conditions.
+ * @endif
+ * (See @link Allocators allocators info @endlink for more.)
+ */
+ template<int __inst>
+ class __malloc_alloc
+ {
+ private:
+ static void* _S_oom_malloc(size_t);
+ static void (* __malloc_alloc_oom_handler)();
+
+ public:
+ static void*
+ allocate(size_t __n)
+ {
+ void* __result = malloc(__n);
+ if (__builtin_expect(__result == 0, 0))
+ __result = _S_oom_malloc(__n);
+ return __result;
+ }
+
+ static void
+ deallocate(void* __p, size_t /* __n */)
+ { free(__p); }
+
+ static void (* __set_malloc_handler(void (*__f)()))()
+ {
+ void (* __old)() = __malloc_alloc_oom_handler;
+ __malloc_alloc_oom_handler = __f;
+ return __old;
+ }
+ };
+
+ // malloc_alloc out-of-memory handling
+ template<int __inst>
+ void (* __malloc_alloc<__inst>::__malloc_alloc_oom_handler)() = 0;
+
+ template<int __inst>
+ void*
+ __malloc_alloc<__inst>::
+ _S_oom_malloc(size_t __n)
+ {
+ void (* __my_malloc_handler)();
+ void* __result;
+
+ for (;;)
+ {
+ __my_malloc_handler = __malloc_alloc_oom_handler;
+ if (__builtin_expect(__my_malloc_handler == 0, 0))
+ __throw_bad_alloc();
+ (*__my_malloc_handler)();
+ __result = malloc(__n);
+ if (__result)
+ return __result;
+ }
+ }
+ //@{
+ /** Comparison operators for all of the predifined SGI-style allocators.
+ * This ensures that __allocator<malloc_alloc> (for example) will work
+ * correctly. As required, all allocators compare equal.
+ */
+ template<int inst>
+ inline bool
+ operator==(const __malloc_alloc<inst>&, const __malloc_alloc<inst>&)
+ { return true; }
+
+ template<int __inst>
+ inline bool
+ operator!=(const __malloc_alloc<__inst>&, const __malloc_alloc<__inst>&)
+ { return false; }
+ //@}
+} // namespace __gnu_cxx
+
+namespace std
+{
+ //@{
+ /// Versions for the predefined "SGI" style allocators.
+ template<typename _Tp, int __inst>
+ struct _Alloc_traits<_Tp, __gnu_cxx::__malloc_alloc<__inst> >
+ {
+ static const bool _S_instanceless = true;
+ typedef __gnu_cxx:: __malloc_alloc<__inst> base_alloc_type;
+ typedef __simple_alloc<_Tp, base_alloc_type> _Alloc_type;
+ typedef __allocator<_Tp, base_alloc_type> allocator_type;
+ };
+ //@}
+
+ //@{
+ /// Versions for the __allocator adaptor used with the predefined
+ /// "SGI" style allocators.
+ template<typename _Tp, typename _Tp1, int __inst>
+ struct _Alloc_traits<_Tp, __allocator<_Tp1,
+ __gnu_cxx::__malloc_alloc<__inst> > >
+ {
+ static const bool _S_instanceless = true;
+ typedef __gnu_cxx:: __malloc_alloc<__inst> base_alloc_type;
+ typedef __simple_alloc<_Tp, base_alloc_type> _Alloc_type;
+ typedef __allocator<_Tp, base_alloc_type> allocator_type;
+ };
+ //@}
+} // namespace std
+
+#endif
diff --git a/libstdc++-v3/include/ext/mt_allocator.h b/libstdc++-v3/include/ext/mt_allocator.h
new file mode 100644
index 00000000000..1e95b55f467
--- /dev/null
+++ b/libstdc++-v3/include/ext/mt_allocator.h
@@ -0,0 +1,861 @@
+// MT-optimized allocator -*- C++ -*-
+
+// Copyright (C) 2003 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
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// As a special exception, you may use this file as part of a free software
+// library without restriction. Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License. This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+/** @file ext/mt_allocator.h
+ * This file is a GNU extension to the Standard C++ Library.
+ * You should only include this header if you are using GCC 3 or later.
+ */
+
+#ifndef _MT_ALLOCATOR_H
+#define _MT_ALLOCATOR_H 1
+
+#include <cstdlib>
+#include <bits/functexcept.h>
+#include <bits/stl_threads.h>
+#include <bits/atomicity.h>
+#include <bits/allocator_traits.h>
+
+/**
+ * This is a fixed size (power of 2) allocator which - when compiled
+ * with thread support - will maintain one freelist per size per thread
+ * plus a "global" one. Steps are taken to limit the per thread freelist
+ * sizes (by returning excess back to "global").
+ *
+ * Usage examples:
+ * vector<int, __gnu_cxx::__mt_alloc<0> > v1;
+ *
+ * typedef std::__allocator<char, __gnu_cxx::__mt_alloc<0> > string_alloc;
+ * std::basic_string<char, std::char_traits<char>, string_alloc> s1;
+ */
+
+namespace __gnu_cxx
+{
+ template<int __inst>
+ class __mt_alloc
+ {
+ private:
+ /*
+ * We need to create the initial lists and set up some variables
+ * before we can answer to the first request for memory.
+ * The initialization of these variables is done at file scope
+ * below class declaration.
+ */
+#ifdef __GTHREADS
+ static __gthread_once_t _S_once_mt;
+#endif
+ static bool _S_initialized;
+
+ /*
+ * Using short int as type for the binmap implies we are never caching
+ * blocks larger than 65535 with this allocator
+ */
+ typedef unsigned short int binmap_type;
+ static binmap_type* _S_binmap;
+
+ static void _S_init();
+
+ /*
+ * Variables used to "tune" the behavior of the allocator, assigned
+ * and explained in detail below.
+ */
+ static size_t _S_max_bytes;
+ static size_t _S_chunk_size;
+ static size_t _S_max_threads;
+ static size_t _S_no_of_bins;
+ static size_t _S_freelist_headroom;
+
+ /*
+ * Each requesting thread is assigned an id ranging from 1 to
+ * _S_max_threads. Thread id 0 is used as a global memory pool.
+ * In order to get constant performance on the thread assignment
+ * routine, we keep a list of free ids. When a thread first requests
+ * memory we remove the first record in this list and stores the address
+ * in a __gthread_key. When initializing the __gthread_key
+ * we specify a destructor. When this destructor (i.e. the thread dies)
+ * is called, we return the thread id to the back of this list.
+ */
+#ifdef __GTHREADS
+ struct thread_record
+ {
+ /*
+ * Points to next free thread id record. NULL if last record in list.
+ */
+ thread_record* next;
+
+ /*
+ * Thread id ranging from 1 to _S_max_threads.
+ */
+ size_t id;
+ };
+
+ static thread_record* _S_thread_freelist_first;
+ static thread_record* _S_thread_freelist_last;
+ static __gthread_mutex_t _S_thread_freelist_mutex;
+ static void _S_thread_key_destr(void* freelist_pos);
+ static __gthread_key_t _S_thread_key;
+ static size_t _S_get_thread_id();
+#endif
+
+ struct block_record
+ {
+ /*
+ * Points to the next block_record for its thread_id.
+ */
+ block_record* next;
+
+ /*
+ * The thread id of the thread which has requested this block.
+ * All blocks are initially "owned" by global pool thread id 0.
+ */
+ size_t thread_id;
+ };
+
+ struct bin_record
+ {
+ /*
+ * An "array" of pointers to the first/last free block for each
+ * thread id. Memory to these "arrays" is allocated in _S_init()
+ * for _S_max_threads + global pool 0.
+ */
+ block_record** first;
+ block_record** last;
+
+ /*
+ * An "array" of counters used to keep track of the amount of blocks
+ * that are on the freelist/used for each thread id.
+ * Memory to these "arrays" is allocated in _S_init()
+ * for _S_max_threads + global pool 0.
+ */
+ size_t* free;
+ size_t* used;
+
+ /*
+ * Each bin has its own mutex which is used to ensure data integrity
+ * while changing "ownership" on a block.
+ * The mutex is initialized in _S_init().
+ */
+#ifdef __GTHREADS
+ __gthread_mutex_t* mutex;
+#endif
+ };
+
+ /*
+ * An "array" of bin_records each of which represents a specific
+ * power of 2 size. Memory to this "array" is allocated in _S_init().
+ */
+ static bin_record* _S_bin;
+
+ public:
+ static void*
+ allocate(size_t __n)
+ {
+
+ /*
+ * Requests larger than _S_max_bytes are handled by
+ * malloc/free directly
+ */
+ if (__n > _S_max_bytes)
+ {
+ void* __ret = malloc(__n);
+ if (!__ret)
+ __throw_bad_alloc();
+
+ return __ret;
+ }
+
+ /*
+ * Although the test in __gthread_once() would suffice, we
+ * wrap test of the once condition in our own unlocked
+ * check. This saves one function call to pthread_once()
+ * (which itself only tests for the once value unlocked anyway
+ * and immediately returns if set)
+ */
+ if (!_S_initialized)
+ {
+#ifdef __GTHREADS
+ if (__gthread_active_p())
+ __gthread_once(&_S_once_mt, _S_init);
+ else
+#endif
+ {
+ _S_max_threads = 0;
+ _S_init();
+ }
+ }
+
+ /*
+ * Round up to power of 2 and figure out which bin to use
+ */
+ size_t bin = _S_binmap[__n];
+
+#ifdef __GTHREADS
+ size_t thread_id = _S_get_thread_id();
+#else
+ size_t thread_id = 0;
+#endif
+
+ block_record* block;
+
+ /*
+ * Find out if we have blocks on our freelist.
+ * If so, go ahead and use them directly without
+ * having to lock anything.
+ */
+ if (_S_bin[bin].first[thread_id] == NULL)
+ {
+ /*
+ * Are we using threads?
+ * - Yes, lock and check if there are free blocks on the global
+ * list (and if not add new ones), get the first one
+ * and change owner.
+ * - No, all operations are made directly to global pool 0
+ * no need to lock or change ownership but check for free
+ * blocks on global list (and if not add new ones) and
+ * get the first one.
+ */
+#ifdef __GTHREADS
+ if (__gthread_active_p())
+ {
+ __gthread_mutex_lock(_S_bin[bin].mutex);
+
+ if (_S_bin[bin].first[0] == NULL)
+ {
+ _S_bin[bin].first[0] =
+ (block_record*)malloc(_S_chunk_size);
+
+ if (!_S_bin[bin].first[0])
+ {
+ __gthread_mutex_unlock(_S_bin[bin].mutex);
+ __throw_bad_alloc();
+ }
+
+ size_t bin_t = 1 << bin;
+ size_t block_count =
+ _S_chunk_size /(bin_t + sizeof(block_record));
+
+ _S_bin[bin].free[0] = block_count;
+
+ block_count--;
+ block = _S_bin[bin].first[0];
+
+ while (block_count > 0)
+ {
+ block->next = (block_record*)((char*)block +
+ (bin_t + sizeof(block_record)));
+ block = block->next;
+ block_count--;
+ }
+
+ block->next = NULL;
+ _S_bin[bin].last[0] = block;
+ }
+
+ block = _S_bin[bin].first[0];
+
+ /*
+ * Remove from list and count down the available counter on
+ * global pool 0.
+ */
+ _S_bin[bin].first[0] = _S_bin[bin].first[0]->next;
+ _S_bin[bin].free[0]--;
+
+ __gthread_mutex_unlock(_S_bin[bin].mutex);
+
+ /*
+ * Now that we have removed the block from the global
+ * freelist we can change owner and update the used
+ * counter for this thread without locking.
+ */
+ block->thread_id = thread_id;
+ _S_bin[bin].used[thread_id]++;
+ }
+ else
+#endif
+ {
+ _S_bin[bin].first[0] = (block_record*)malloc(_S_chunk_size);
+
+ if (!_S_bin[bin].first[0])
+ __throw_bad_alloc();
+
+ size_t bin_t = 1 << bin;
+ size_t block_count =
+ _S_chunk_size / (bin_t + sizeof(block_record));
+
+ _S_bin[bin].free[0] = block_count;
+
+ block_count--;
+ block = _S_bin[bin].first[0];
+
+ while (block_count > 0)
+ {
+ block->next = (block_record*)((char*)block +
+ (bin_t + sizeof(block_record)));
+ block = block->next;
+ block_count--;
+ }
+
+ block->next = NULL;
+ _S_bin[bin].last[0] = block;
+
+ block = _S_bin[bin].first[0];
+
+ /*
+ * Remove from list and count down the available counter on
+ * global pool 0 and increase it's used counter.
+ */
+ _S_bin[bin].first[0] = _S_bin[bin].first[0]->next;
+ _S_bin[bin].free[0]--;
+ _S_bin[bin].used[0]++;
+ }
+ }
+ else
+ {
+ /*
+ * "Default" operation - we have blocks on our own freelist
+ * grab the first record and update the counters.
+ */
+ block = _S_bin[bin].first[thread_id];
+
+ _S_bin[bin].first[thread_id] = _S_bin[bin].first[thread_id]->next;
+ _S_bin[bin].free[thread_id]--;
+ _S_bin[bin].used[thread_id]++;
+ }
+
+ return (void*)((char*)block + sizeof(block_record));
+ }
+
+ static void
+ deallocate(void* __p, size_t __n)
+ {
+ /*
+ * Requests larger than _S_max_bytes are handled by
+ * malloc/free directly
+ */
+ if (__n > _S_max_bytes)
+ {
+ free(__p);
+ return;
+ }
+
+ /*
+ * Round up to power of 2 and figure out which bin to use
+ */
+ size_t bin = _S_binmap[__n];
+
+#ifdef __GTHREADS
+ size_t thread_id = _S_get_thread_id();
+#else
+ size_t thread_id = 0;
+#endif
+
+ block_record* block = (block_record*)((char*)__p
+ - sizeof(block_record));
+
+ /*
+ * This block will always be at the back of a list and thus
+ * we set its next pointer to NULL.
+ */
+ block->next = NULL;
+
+#ifdef __GTHREADS
+ if (__gthread_active_p())
+ {
+ /*
+ * Calculate the number of records to remove from our freelist
+ */
+ int remove = _S_bin[bin].free[thread_id] -
+ (_S_bin[bin].used[thread_id] / _S_freelist_headroom);
+
+ /*
+ * The calculation above will almost always tell us to
+ * remove one or two records at a time, but this creates
+ * too much contention when locking and therefore we
+ * wait until the number of records is "high enough".
+ */
+ if (remove > (int)(100 * (_S_no_of_bins - bin)) &&
+ remove > (int)(_S_bin[bin].free[thread_id] /
+ _S_freelist_headroom))
+ {
+ __gthread_mutex_lock(_S_bin[bin].mutex);
+
+ while (remove > 0)
+ {
+ if (_S_bin[bin].first[0] == NULL)
+ _S_bin[bin].first[0] = _S_bin[bin].first[thread_id];
+ else
+ _S_bin[bin].last[0]->next = _S_bin[bin].first[thread_id];
+
+ _S_bin[bin].last[0] = _S_bin[bin].first[thread_id];
+
+ _S_bin[bin].first[thread_id] =
+ _S_bin[bin].first[thread_id]->next;
+
+ _S_bin[bin].free[0]++;
+ _S_bin[bin].free[thread_id]--;
+
+ remove--;
+ }
+
+ _S_bin[bin].last[0]->next = NULL;
+
+ __gthread_mutex_unlock(_S_bin[bin].mutex);
+ }
+
+ /*
+ * Did we allocate this block?
+ * - Yes, return it to our freelist
+ * - No, return it to global pool
+ */
+ if (thread_id == block->thread_id)
+ {
+ if (_S_bin[bin].first[thread_id] == NULL)
+ _S_bin[bin].first[thread_id] = block;
+ else
+ _S_bin[bin].last[thread_id]->next = block;
+
+ _S_bin[bin].last[thread_id] = block;
+
+ _S_bin[bin].free[thread_id]++;
+ _S_bin[bin].used[thread_id]--;
+ }
+ else
+ {
+ __gthread_mutex_lock(_S_bin[bin].mutex);
+
+ if (_S_bin[bin].first[0] == NULL)
+ _S_bin[bin].first[0] = block;
+ else
+ _S_bin[bin].last[0]->next = block;
+
+ _S_bin[bin].last[0] = block;
+
+ _S_bin[bin].free[0]++;
+ _S_bin[bin].used[block->thread_id]--;
+
+ __gthread_mutex_unlock(_S_bin[bin].mutex);
+ }
+ }
+ else
+#endif
+ {
+ /*
+ * Single threaded application - return to global pool
+ */
+ if (_S_bin[bin].first[0] == NULL)
+ _S_bin[bin].first[0] = block;
+ else
+ _S_bin[bin].last[0]->next = block;
+
+ _S_bin[bin].last[0] = block;
+
+ _S_bin[bin].free[0]++;
+ _S_bin[bin].used[0]--;
+ }
+ }
+ };
+
+ template<int __inst>
+ void
+ __mt_alloc<__inst>::
+ _S_init()
+ {
+ /*
+ * Calculate the number of bins required based on _S_max_bytes,
+ * _S_no_of_bins is initialized to 1 below.
+ */
+ {
+ size_t bin_t = 1;
+ while (_S_max_bytes > bin_t)
+ {
+ bin_t = bin_t << 1;
+ _S_no_of_bins++;
+ }
+ }
+
+ /*
+ * Setup the bin map for quick lookup of the relevant bin
+ */
+ _S_binmap = (binmap_type*)
+ malloc ((_S_max_bytes + 1) * sizeof(binmap_type));
+
+ if (!_S_binmap)
+ __throw_bad_alloc();
+
+ binmap_type* bp_t = _S_binmap;
+ binmap_type bin_max_t = 1;
+ binmap_type bin_t = 0;
+ for (binmap_type ct = 0; ct <= _S_max_bytes; ct++)
+ {
+ if (ct > bin_max_t)
+ {
+ bin_max_t <<= 1;
+ bin_t++;
+ }
+ *bp_t++ = bin_t;
+ }
+
+ /*
+ * If __gthread_active_p() create and initialize the list of
+ * free thread ids. Single threaded applications use thread id 0
+ * directly and have no need for this.
+ */
+#ifdef __GTHREADS
+ if (__gthread_active_p())
+ {
+ _S_thread_freelist_first =
+ (thread_record*)malloc(sizeof(thread_record) * _S_max_threads);
+
+ if (!_S_thread_freelist_first)
+ __throw_bad_alloc();
+
+ /*
+ * NOTE! The first assignable thread id is 1 since the global
+ * pool uses id 0
+ */
+ size_t i;
+ for (i = 1; i < _S_max_threads; i++)
+ {
+ _S_thread_freelist_first[i - 1].next =
+ &_S_thread_freelist_first[i];
+
+ _S_thread_freelist_first[i - 1].id = i;
+ }
+
+ /*
+ * Set last record and pointer to this
+ */
+ _S_thread_freelist_first[i - 1].next = NULL;
+ _S_thread_freelist_first[i - 1].id = i;
+ _S_thread_freelist_last = &_S_thread_freelist_first[i - 1];
+
+ /*
+ * Initialize per thread key to hold pointer to
+ * _S_thread_freelist NOTE! Here's an ugly workaround - if
+ * _S_thread_key_destr is not explicitly called at least
+ * once it won't be linked into the application. This is the
+ * behavior of template methods and __gthread_key_create()
+ * takes only a pointer to the function and does not cause
+ * the compiler to create an instance.
+ */
+ _S_thread_key_destr(NULL);
+ __gthread_key_create(&_S_thread_key, _S_thread_key_destr);
+ }
+#endif
+
+ /*
+ * Initialize _S_bin and its members
+ */
+ _S_bin = (bin_record*)malloc(sizeof(bin_record) * _S_no_of_bins);
+
+ if (!_S_bin)
+ __throw_bad_alloc();
+
+ for (size_t bin = 0; bin < _S_no_of_bins; bin++)
+ {
+ _S_bin[bin].first = (block_record**)
+ malloc(sizeof(block_record*) * (_S_max_threads + 1));
+
+ if (!_S_bin[bin].first)
+ __throw_bad_alloc();
+
+ _S_bin[bin].last = (block_record**)
+ malloc(sizeof(block_record*) * (_S_max_threads + 1));
+
+ if (!_S_bin[bin].last)
+ __throw_bad_alloc();
+
+ _S_bin[bin].free = (size_t*)
+ malloc(sizeof(size_t) * (_S_max_threads + 1));
+
+ if (!_S_bin[bin].free)
+ __throw_bad_alloc();
+
+ _S_bin[bin].used = (size_t*)
+ malloc(sizeof(size_t) * (_S_max_threads + 1));
+
+ if (!_S_bin[bin].used)
+ __throw_bad_alloc();
+
+ /*
+ * Ugly workaround of what at the time of writing seems to be
+ * a parser problem - see PR c++/9779 for more info.
+ */
+#ifdef __GTHREADS
+ size_t s = sizeof(__gthread_mutex_t);
+ _S_bin[bin].mutex = (__gthread_mutex_t*)malloc(s);
+
+ if (!_S_bin[bin].mutex)
+ __throw_bad_alloc();
+
+ /*
+ * This is not only ugly - it's extremly non-portable!
+ * However gthr.h does not currently provide a
+ * __gthread_mutex_init() call. The correct solution to
+ * this problem needs to be discussed.
+ */
+ pthread_mutex_init(_S_bin[bin].mutex, NULL);
+#endif
+
+ for (size_t thread = 0; thread <= _S_max_threads; thread++)
+ {
+ _S_bin[bin].first[thread] = NULL;
+ _S_bin[bin].last[thread] = NULL;
+ _S_bin[bin].free[thread] = 0;
+ _S_bin[bin].used[thread] = 0;
+ }
+ }
+
+ _S_initialized = true;
+ }
+
+#ifdef __GTHREADS
+ template<int __inst>
+ void
+ __mt_alloc<__inst>::
+ _S_thread_key_destr(void* freelist_pos)
+ {
+ /*
+ * This is due to the ugly workaround mentioned in _S_init()
+ */
+ if (freelist_pos == NULL)
+ return;
+
+ /*
+ * If the thread - when it dies - still have records on its
+ * freelist we return them to the global pool here.
+ */
+ for (size_t bin = 0; bin < _S_no_of_bins; bin++)
+ {
+ block_record* block =
+ _S_bin[bin].first[((thread_record*)freelist_pos)->id];
+
+ if (block != NULL)
+ {
+ __gthread_mutex_lock(_S_bin[bin].mutex);
+
+ while (block != NULL)
+ {
+ if (_S_bin[bin].first[0] == NULL)
+ _S_bin[bin].first[0] = block;
+ else
+ _S_bin[bin].last[0]->next = block;
+
+ _S_bin[bin].last[0] = block;
+
+ block = block->next;
+
+ _S_bin[bin].free[0]++;
+ }
+
+ _S_bin[bin].last[0]->next = NULL;
+
+ __gthread_mutex_unlock(_S_bin[bin].mutex);
+ }
+ }
+
+ /*
+ * Return this thread id record to thread_freelist
+ */
+ __gthread_mutex_lock(&_S_thread_freelist_mutex);
+
+ _S_thread_freelist_last->next = (thread_record*)freelist_pos;
+ _S_thread_freelist_last = (thread_record*)freelist_pos;
+ _S_thread_freelist_last->next = NULL;
+
+ __gthread_mutex_unlock(&_S_thread_freelist_mutex);
+
+ }
+
+ template<int __inst>
+ size_t
+ __mt_alloc<__inst>::
+ _S_get_thread_id()
+ {
+ /*
+ * If we have thread support and it's active we check the thread
+ * key value and return it's id or if it's not set we take the
+ * first record from _S_thread_freelist and sets the key and
+ * returns it's id.
+ */
+ if (__gthread_active_p())
+ {
+ thread_record* freelist_pos;
+
+ if ((freelist_pos =
+ (thread_record*)__gthread_getspecific(_S_thread_key)) == NULL)
+ {
+ __gthread_mutex_lock(&_S_thread_freelist_mutex);
+
+ /*
+ * Since _S_max_threads must be larger than the
+ * theoretical max number of threads of the OS the list
+ * can never be empty.
+ */
+ freelist_pos = _S_thread_freelist_first;
+ _S_thread_freelist_first = _S_thread_freelist_first->next;
+
+ __gthread_mutex_unlock(&_S_thread_freelist_mutex);
+
+ __gthread_setspecific(_S_thread_key, (void*)freelist_pos);
+
+ /*
+ * Since thread_ids may/will be reused (espcially in
+ * producer/consumer applications) we make sure that the
+ * list pointers and free counter is reset BUT as the
+ * "old" thread may still be owner of some memory (which
+ * is referred to by other threads and thus not freed)
+ * we don't reset the used counter.
+ */
+ for (size_t bin = 0; bin < _S_no_of_bins; bin++)
+ {
+ _S_bin[bin].first[freelist_pos->id] = NULL;
+ _S_bin[bin].last[freelist_pos->id] = NULL;
+ _S_bin[bin].free[freelist_pos->id] = 0;
+ }
+ }
+
+ return freelist_pos->id;
+ }
+
+ /*
+ * Otherwise (no thread support or inactive) all requests are
+ * served from the global pool 0.
+ */
+ return 0;
+ }
+
+ template<int __inst> __gthread_once_t
+ __mt_alloc<__inst>::_S_once_mt = __GTHREAD_ONCE_INIT;
+#endif
+
+ template<int __inst> bool
+ __mt_alloc<__inst>::_S_initialized = false;
+
+ template<int __inst> typename __mt_alloc<__inst>::binmap_type*
+ __mt_alloc<__inst>::_S_binmap = NULL;
+
+ /*
+ * Allocation requests (after round-up to power of 2) below this
+ * value will be handled by the allocator. A raw malloc/free() call
+ * will be used for requests larger than this value.
+ */
+ template<int __inst> size_t
+ __mt_alloc<__inst>::_S_max_bytes = 128;
+
+ /*
+ * In order to avoid fragmenting and minimize the number of malloc()
+ * calls we always request new memory using this value. Based on
+ * previous discussions on the libstdc++ mailing list we have
+ * choosen the value below. See
+ * http://gcc.gnu.org/ml/libstdc++/2001-07/msg00077.html
+ */
+ template<int __inst> size_t
+ __mt_alloc<__inst>::_S_chunk_size = 4096 - 4 * sizeof(void*);
+
+ /*
+ * The maximum number of supported threads. Our Linux 2.4.18 reports
+ * 4070 in /proc/sys/kernel/threads-max
+ */
+ template<int __inst> size_t
+ __mt_alloc<__inst>::_S_max_threads = 4096;
+
+ /*
+ * Actual value calculated in _S_init()
+ */
+ template<int __inst> size_t
+ __mt_alloc<__inst>::_S_no_of_bins = 1;
+
+ /*
+ * Each time a deallocation occurs in a threaded application we make
+ * sure that there are no more than _S_freelist_headroom % of used
+ * memory on the freelist. If the number of additional records is
+ * more than _S_freelist_headroom % of the freelist, we move these
+ * records back to the global pool.
+ */
+ template<int __inst> size_t
+ __mt_alloc<__inst>::_S_freelist_headroom = 10;
+
+ /*
+ * Actual initialization in _S_init()
+ */
+#ifdef __GTHREADS
+ template<int __inst> typename __mt_alloc<__inst>::thread_record*
+ __mt_alloc<__inst>::_S_thread_freelist_first = NULL;
+
+ template<int __inst> typename __mt_alloc<__inst>::thread_record*
+ __mt_alloc<__inst>::_S_thread_freelist_last = NULL;
+
+ template<int __inst> __gthread_mutex_t
+ __mt_alloc<__inst>::_S_thread_freelist_mutex = __GTHREAD_MUTEX_INIT;
+
+ /*
+ * Actual initialization in _S_init()
+ */
+ template<int __inst> __gthread_key_t
+ __mt_alloc<__inst>::_S_thread_key;
+#endif
+
+ template<int __inst> typename __mt_alloc<__inst>::bin_record*
+ __mt_alloc<__inst>::_S_bin = NULL;
+
+ template<int __inst>
+ inline bool
+ operator==(const __mt_alloc<__inst>&, const __mt_alloc<__inst>&)
+ { return true; }
+
+ template<int __inst>
+ inline bool
+ operator!=(const __mt_alloc<__inst>&, const __mt_alloc<__inst>&)
+ { return false; }
+} // namespace __gnu_cxx
+
+namespace std
+{
+ template<typename _Tp, int __inst>
+ struct _Alloc_traits<_Tp, __gnu_cxx::__mt_alloc<__inst> >
+ {
+ static const bool _S_instanceless = true;
+ typedef __gnu_cxx:: __mt_alloc<__inst> base_alloc_type;
+ typedef __simple_alloc<_Tp, base_alloc_type> _Alloc_type;
+ typedef __allocator<_Tp, base_alloc_type> allocator_type;
+ };
+
+ template<typename _Tp, typename _Tp1, int __inst>
+ struct _Alloc_traits<_Tp,
+ __allocator<_Tp1, __gnu_cxx::__mt_alloc<__inst> > >
+ {
+ static const bool _S_instanceless = true;
+ typedef __gnu_cxx:: __mt_alloc<__inst> base_alloc_type;
+ typedef __simple_alloc<_Tp, base_alloc_type> _Alloc_type;
+ typedef __allocator<_Tp, base_alloc_type> allocator_type;
+ };
+} // namespace std
+
+#endif
+
diff --git a/libstdc++-v3/include/bits/stl_pthread_alloc.h b/libstdc++-v3/include/ext/new_allocator.h
index 09b7d727af6..794751d3c13 100644
--- a/libstdc++-v3/include/bits/stl_pthread_alloc.h
+++ b/libstdc++-v3/include/ext/new_allocator.h
@@ -1,6 +1,6 @@
-// Wrapper of pthread allocation header -*- C++ -*-
+// Allocators -*- C++ -*-
-// Copyright (C) 2001 Free Software Foundation, Inc.
+// Copyright (C) 2001, 2002, 2003 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
@@ -27,34 +27,32 @@
// invalidate any other reasons why the executable file might be covered by
// the GNU General Public License.
-/*
- * Copyright (c) 1996-1997
- * Silicon Graphics Computer Systems, Inc.
- *
- * Permission to use, copy, modify, distribute and sell this software
- * and its documentation for any purpose is hereby granted without fee,
- * provided that the above copyright notice appear in all copies and
- * that both that copyright notice and this permission notice appear
- * in supporting documentation. Silicon Graphics makes no
- * representations about the suitability of this software for any
- * purpose. It is provided "as is" without express or implied warranty.
- */
-
-/** @file stl_pthread_alloc.h
- * This is an internal header file, included by other library headers.
- * You should not attempt to use it directly.
- */
-
-#ifndef _CPP_BITS_STL_PTHREAD_ALLOC_H
-#define _CPP_BITS_STL_PTHREAD_ALLOC_H 1
-
-#include <bits/pthread_allocimpl.h>
-
-using std::_Pthread_alloc_template;
-using std::pthread_alloc;
-
-#endif /* _CPP_BITS_STL_PTHREAD_ALLOC_H */
-
-// Local Variables:
-// mode:C++
-// End:
+#ifndef _NEW_ALLOCATOR_H
+#define _NEW_ALLOCATOR_H 1
+
+#include <new>
+
+namespace __gnu_cxx
+{
+ /**
+ * @if maint
+ * A new-based allocator, as required by the standard. Allocation and
+ * deallocation forward to global new and delete. "SGI" style, minus
+ * reallocate().
+ * @endif
+ * (See @link Allocators allocators info @endlink for more.)
+ */
+ class __new_alloc
+ {
+ public:
+ static void*
+ allocate(size_t __n)
+ { return ::operator new(__n); }
+
+ static void
+ deallocate(void* __p, size_t)
+ { ::operator delete(__p); }
+ };
+} // namespace __gnu_cxx
+
+#endif
diff --git a/libstdc++-v3/include/ext/pool_allocator.h b/libstdc++-v3/include/ext/pool_allocator.h
new file mode 100644
index 00000000000..77d354faabb
--- /dev/null
+++ b/libstdc++-v3/include/ext/pool_allocator.h
@@ -0,0 +1,383 @@
+// Allocators -*- C++ -*-
+
+// Copyright (C) 2001, 2002, 2003 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
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// As a special exception, you may use this file as part of a free software
+// library without restriction. Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License. This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+/*
+ * Copyright (c) 1996-1997
+ * Silicon Graphics Computer Systems, Inc.
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Silicon Graphics makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ */
+
+/** @file ext/debug_allocator.h
+ * This file is a GNU extension to the Standard C++ Library.
+ * You should only include this header if you are using GCC 3 or later.
+ */
+
+#ifndef _POOL_ALLOCATOR_H
+#define _POOL_ALLOCATOR_H 1
+
+#include <bits/functexcept.h>
+#include <bits/stl_threads.h>
+#include <bits/atomicity.h>
+#include <bits/allocator_traits.h>
+#include <ext/new_allocator.h>
+
+namespace __gnu_cxx
+{
+ using std::_STL_mutex_lock;
+ using std::__throw_bad_alloc;
+
+ /**
+ * @if maint
+ * Default node allocator. "SGI" style. Uses various allocators to
+ * fulfill underlying requests (and makes as few requests as possible
+ * when in default high-speed pool mode).
+ *
+ * Important implementation properties:
+ * 0. If globally mandated, then allocate objects from __new_alloc
+ * 1. If the clients request an object of size > _S_max_bytes, the resulting
+ * object will be obtained directly from __new_alloc
+ * 2. In all other cases, we allocate an object of size exactly
+ * _S_round_up(requested_size). Thus the client has enough size
+ * information that we can return the object to the proper free list
+ * without permanently losing part of the object.
+ *
+ * The first template parameter specifies whether more than one thread may
+ * use this allocator. It is safe to allocate an object from one instance
+ * of a default_alloc and deallocate it with another one. This effectively
+ * 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.
+ *
+ * @endif
+ * (See @link Allocators allocators info @endlink for more.)
+ */
+ template<bool __threads, int __inst>
+ class __pool_alloc
+ {
+ private:
+ enum {_S_align = 8};
+ enum {_S_max_bytes = 128};
+ enum {_S_freelists = _S_max_bytes / _S_align};
+
+ union _Obj
+ {
+ union _Obj* _M_free_list_link;
+ char _M_client_data[1]; // The client sees this.
+ };
+
+ static _Obj* volatile _S_free_list[_S_freelists];
+
+ // Chunk allocation state.
+ static char* _S_start_free;
+ static char* _S_end_free;
+ static size_t _S_heap_size;
+
+ static _STL_mutex_lock _S_lock;
+ static _Atomic_word _S_force_new;
+
+ static size_t
+ _S_round_up(size_t __bytes)
+ { return ((__bytes + (size_t)_S_align - 1) & ~((size_t)_S_align - 1)); }
+
+ static size_t
+ _S_freelist_index(size_t __bytes)
+ { return ((__bytes + (size_t)_S_align - 1)/(size_t)_S_align - 1); }
+
+ // Returns an object of size __n, and optionally adds to size __n
+ // free list.
+ static void*
+ _S_refill(size_t __n);
+
+ // Allocates a chunk for nobjs of size size. nobjs may be reduced
+ // if it is inconvenient to allocate the requested number.
+ static char*
+ _S_chunk_alloc(size_t __size, int& __nobjs);
+
+ // It would be nice to use _STL_auto_lock here. But we need a
+ // test whether threads are in use.
+ struct _Lock
+ {
+ _Lock() { if (__threads) _S_lock._M_acquire_lock(); }
+ ~_Lock() { if (__threads) _S_lock._M_release_lock(); }
+ } __attribute__ ((__unused__));
+ friend struct _Lock;
+
+ public:
+ // __n must be > 0
+ static void*
+ allocate(size_t __n)
+ {
+ void* __ret = 0;
+
+ // If there is a race through here, assume answer from getenv
+ // will resolve in same direction. Inspired by techniques
+ // to efficiently support threading found in basic_string.h.
+ if (_S_force_new == 0)
+ {
+ if (getenv("GLIBCPP_FORCE_NEW"))
+ __atomic_add(&_S_force_new, 1);
+ else
+ __atomic_add(&_S_force_new, -1);
+ }
+
+ if ((__n > (size_t) _S_max_bytes) || (_S_force_new > 0))
+ __ret = __new_alloc::allocate(__n);
+ else
+ {
+ _Obj* volatile* __my_free_list = _S_free_list
+ + _S_freelist_index(__n);
+ // Acquire the lock here with a constructor call. This
+ // ensures that it is released in exit or during stack
+ // unwinding.
+ _Lock __lock_instance;
+ _Obj* __restrict__ __result = *__my_free_list;
+ if (__builtin_expect(__result == 0, 0))
+ __ret = _S_refill(_S_round_up(__n));
+ else
+ {
+ *__my_free_list = __result -> _M_free_list_link;
+ __ret = __result;
+ }
+ if (__builtin_expect(__ret == 0, 0))
+ __throw_bad_alloc();
+ }
+ return __ret;
+ }
+
+ // __p may not be 0
+ static void
+ deallocate(void* __p, size_t __n)
+ {
+ if ((__n > (size_t) _S_max_bytes) || (_S_force_new > 0))
+ __new_alloc::deallocate(__p, __n);
+ else
+ {
+ _Obj* volatile* __my_free_list = _S_free_list
+ + _S_freelist_index(__n);
+ _Obj* __q = (_Obj*)__p;
+
+ // Acquire the lock here with a constructor call. This
+ // ensures that it is released in exit or during stack
+ // unwinding.
+ _Lock __lock_instance;
+ __q -> _M_free_list_link = *__my_free_list;
+ *__my_free_list = __q;
+ }
+ }
+ };
+
+ template<bool __threads, int __inst> _Atomic_word
+ __pool_alloc<__threads, __inst>::_S_force_new = 0;
+
+ template<bool __threads, int __inst>
+ inline bool
+ operator==(const __pool_alloc<__threads,__inst>&,
+ const __pool_alloc<__threads,__inst>&)
+ { return true; }
+
+ template<bool __threads, int __inst>
+ inline bool
+ operator!=(const __pool_alloc<__threads,__inst>&,
+ const __pool_alloc<__threads,__inst>&)
+ { return false; }
+
+
+ // We allocate memory in large chunks in order to avoid fragmenting the
+ // heap too much. We assume that __size is properly aligned. We hold
+ // the allocation lock.
+ template<bool __threads, int __inst>
+ char*
+ __pool_alloc<__threads, __inst>::
+ _S_chunk_alloc(size_t __size, int& __nobjs)
+ {
+ char* __result;
+ size_t __total_bytes = __size * __nobjs;
+ size_t __bytes_left = _S_end_free - _S_start_free;
+
+ if (__bytes_left >= __total_bytes)
+ {
+ __result = _S_start_free;
+ _S_start_free += __total_bytes;
+ return __result ;
+ }
+ else if (__bytes_left >= __size)
+ {
+ __nobjs = (int)(__bytes_left/__size);
+ __total_bytes = __size * __nobjs;
+ __result = _S_start_free;
+ _S_start_free += __total_bytes;
+ return __result;
+ }
+ else
+ {
+ size_t __bytes_to_get =
+ 2 * __total_bytes + _S_round_up(_S_heap_size >> 4);
+ // Try to make use of the left-over piece.
+ if (__bytes_left > 0)
+ {
+ _Obj* volatile* __my_free_list =
+ _S_free_list + _S_freelist_index(__bytes_left);
+
+ ((_Obj*)(void*)_S_start_free) -> _M_free_list_link = *__my_free_list;
+ *__my_free_list = (_Obj*)(void*)_S_start_free;
+ }
+ _S_start_free = (char*) __new_alloc::allocate(__bytes_to_get);
+ if (_S_start_free == 0)
+ {
+ size_t __i;
+ _Obj* volatile* __my_free_list;
+ _Obj* __p;
+ // Try to make do with what we have. That can't hurt. We
+ // do not try smaller requests, since that tends to result
+ // in disaster on multi-process machines.
+ __i = __size;
+ for (; __i <= (size_t) _S_max_bytes; __i += (size_t) _S_align)
+ {
+ __my_free_list = _S_free_list + _S_freelist_index(__i);
+ __p = *__my_free_list;
+ if (__p != 0)
+ {
+ *__my_free_list = __p -> _M_free_list_link;
+ _S_start_free = (char*)__p;
+ _S_end_free = _S_start_free + __i;
+ return _S_chunk_alloc(__size, __nobjs);
+ // Any leftover piece will eventually make it to the
+ // right free list.
+ }
+ }
+ _S_end_free = 0; // In case of exception.
+ _S_start_free = (char*)__new_alloc::allocate(__bytes_to_get);
+ // This should either throw an exception or remedy the situation.
+ // Thus we assume it succeeded.
+ }
+ _S_heap_size += __bytes_to_get;
+ _S_end_free = _S_start_free + __bytes_to_get;
+ return _S_chunk_alloc(__size, __nobjs);
+ }
+ }
+
+
+ // Returns an object of size __n, and optionally adds to "size
+ // __n"'s free list. We assume that __n is properly aligned. We
+ // hold the allocation lock.
+ template<bool __threads, int __inst>
+ void*
+ __pool_alloc<__threads, __inst>::_S_refill(size_t __n)
+ {
+ int __nobjs = 20;
+ char* __chunk = _S_chunk_alloc(__n, __nobjs);
+ _Obj* volatile* __my_free_list;
+ _Obj* __result;
+ _Obj* __current_obj;
+ _Obj* __next_obj;
+ int __i;
+
+ if (1 == __nobjs)
+ return __chunk;
+ __my_free_list = _S_free_list + _S_freelist_index(__n);
+
+ // Build free list in chunk.
+ __result = (_Obj*)(void*)__chunk;
+ *__my_free_list = __next_obj = (_Obj*)(void*)(__chunk + __n);
+ for (__i = 1; ; __i++)
+ {
+ __current_obj = __next_obj;
+ __next_obj = (_Obj*)(void*)((char*)__next_obj + __n);
+ if (__nobjs - 1 == __i)
+ {
+ __current_obj -> _M_free_list_link = 0;
+ break;
+ }
+ else
+ __current_obj -> _M_free_list_link = __next_obj;
+ }
+ return __result;
+ }
+
+
+ template<bool __threads, int __inst>
+ _STL_mutex_lock
+ __pool_alloc<__threads, __inst>::_S_lock __STL_MUTEX_INITIALIZER;
+
+ template<bool __threads, int __inst>
+ char* __pool_alloc<__threads, __inst>::_S_start_free = 0;
+
+ template<bool __threads, int __inst>
+ char* __pool_alloc<__threads, __inst>::_S_end_free = 0;
+
+ template<bool __threads, int __inst>
+ size_t __pool_alloc<__threads, __inst>::_S_heap_size = 0;
+
+ template<bool __threads, int __inst>
+ typename __pool_alloc<__threads, __inst>::_Obj* volatile
+ __pool_alloc<__threads, __inst>::_S_free_list[_S_freelists];
+} // namespace __gnu_cxx
+
+namespace std
+{
+ //@{
+ /// Versions for the predefined "SGI" style allocators.
+ template<typename _Tp, bool __thr, int __inst>
+ struct _Alloc_traits<_Tp, __gnu_cxx::__pool_alloc<__thr, __inst> >
+ {
+ static const bool _S_instanceless = true;
+ typedef __gnu_cxx::__pool_alloc<__thr, __inst> base_alloc_type;
+ typedef __simple_alloc<_Tp, base_alloc_type> _Alloc_type;
+ typedef __allocator<_Tp, base_alloc_type> allocator_type;
+ };
+ //@}
+
+ //@{
+ /// Versions for the __allocator adaptor used with the predefined
+ /// "SGI" style allocators.
+ template<typename _Tp, typename _Tp1, bool __thr, int __inst>
+ struct _Alloc_traits<_Tp, __allocator<_Tp1,
+ __gnu_cxx::__pool_alloc<__thr, __inst> > >
+ {
+ static const bool _S_instanceless = true;
+ typedef __gnu_cxx::__pool_alloc<__thr, __inst> base_alloc_type;
+ typedef __simple_alloc<_Tp, base_alloc_type> _Alloc_type;
+ typedef __allocator<_Tp, base_alloc_type> allocator_type;
+ };
+ //@}
+} // namespace std
+
+#endif
diff --git a/libstdc++-v3/include/ext/rope b/libstdc++-v3/include/ext/rope
index d621ba84aa0..9ba261845b3 100644
--- a/libstdc++-v3/include/ext/rope
+++ b/libstdc++-v3/include/ext/rope
@@ -53,7 +53,7 @@
#include <bits/stl_algo.h>
#include <bits/stl_function.h>
#include <bits/stl_numeric.h>
-#include <bits/stl_alloc.h>
+#include <bits/allocator.h>
#include <bits/stl_construct.h>
#include <bits/stl_uninitialized.h>
#include <ext/hash_fun.h>
diff --git a/libstdc++-v3/include/ext/slist b/libstdc++-v3/include/ext/slist
index 780e2c2d693..875f7604de5 100644
--- a/libstdc++-v3/include/ext/slist
+++ b/libstdc++-v3/include/ext/slist
@@ -51,7 +51,7 @@
#define _SLIST 1
#include <bits/stl_algobase.h>
-#include <bits/stl_alloc.h>
+#include <bits/allocator.h>
#include <bits/stl_construct.h>
#include <bits/stl_uninitialized.h>
#include <bits/concept_check.h>
diff --git a/libstdc++-v3/include/std/std_deque.h b/libstdc++-v3/include/std/std_deque.h
index 921c25fa493..774d334e8d7 100644
--- a/libstdc++-v3/include/std/std_deque.h
+++ b/libstdc++-v3/include/std/std_deque.h
@@ -65,7 +65,7 @@
#include <bits/functexcept.h>
#include <bits/stl_algobase.h>
-#include <bits/stl_alloc.h>
+#include <bits/allocator.h>
#include <bits/stl_construct.h>
#include <bits/stl_uninitialized.h>
#include <bits/stl_deque.h>
diff --git a/libstdc++-v3/include/std/std_list.h b/libstdc++-v3/include/std/std_list.h
index 84523ad8e4f..61c6dfa88eb 100644
--- a/libstdc++-v3/include/std/std_list.h
+++ b/libstdc++-v3/include/std/std_list.h
@@ -65,7 +65,7 @@
#include <bits/functexcept.h>
#include <bits/stl_algobase.h>
-#include <bits/stl_alloc.h>
+#include <bits/allocator.h>
#include <bits/stl_construct.h>
#include <bits/stl_uninitialized.h>
#include <bits/stl_list.h>
diff --git a/libstdc++-v3/include/std/std_memory.h b/libstdc++-v3/include/std/std_memory.h
index 47c3ede8995..b508351c8b5 100644
--- a/libstdc++-v3/include/std/std_memory.h
+++ b/libstdc++-v3/include/std/std_memory.h
@@ -52,7 +52,7 @@
#pragma GCC system_header
#include <bits/stl_algobase.h>
-#include <bits/stl_alloc.h>
+#include <bits/allocator.h>
#include <bits/stl_construct.h>
#include <bits/stl_iterator_base_types.h> //for iterator_traits
#include <bits/stl_uninitialized.h>
diff --git a/libstdc++-v3/include/std/std_queue.h b/libstdc++-v3/include/std/std_queue.h
index 60636e6f0dd..33eb9449727 100644
--- a/libstdc++-v3/include/std/std_queue.h
+++ b/libstdc++-v3/include/std/std_queue.h
@@ -65,7 +65,7 @@
#include <bits/c++config.h>
#include <bits/functexcept.h>
#include <bits/stl_algobase.h>
-#include <bits/stl_alloc.h>
+#include <bits/allocator.h>
#include <bits/stl_construct.h>
#include <bits/stl_uninitialized.h>
#include <bits/stl_vector.h>
diff --git a/libstdc++-v3/include/std/std_stack.h b/libstdc++-v3/include/std/std_stack.h
index ddae7e78fc6..fb111d4d4df 100644
--- a/libstdc++-v3/include/std/std_stack.h
+++ b/libstdc++-v3/include/std/std_stack.h
@@ -64,7 +64,7 @@
#pragma GCC system_header
#include <bits/stl_algobase.h>
-#include <bits/stl_alloc.h>
+#include <bits/allocator.h>
#include <bits/stl_construct.h>
#include <bits/stl_uninitialized.h>
#include <bits/stl_deque.h>
diff --git a/libstdc++-v3/include/std/std_vector.h b/libstdc++-v3/include/std/std_vector.h
index 5738ef7ade8..5f700495b4c 100644
--- a/libstdc++-v3/include/std/std_vector.h
+++ b/libstdc++-v3/include/std/std_vector.h
@@ -65,7 +65,7 @@
#include <bits/functexcept.h>
#include <bits/stl_algobase.h>
-#include <bits/stl_alloc.h>
+#include <bits/allocator.h>
#include <bits/stl_construct.h>
#include <bits/stl_uninitialized.h>
#include <bits/stl_vector.h>
diff --git a/libstdc++-v3/src/Makefile.am b/libstdc++-v3/src/Makefile.am
index a788cb9369b..6876e288925 100644
--- a/libstdc++-v3/src/Makefile.am
+++ b/libstdc++-v3/src/Makefile.am
@@ -117,6 +117,7 @@ basic_file.cc: ${glibcpp_srcdir}/@BASIC_FILE_CC@
# Sources present in the src directory.
sources = \
+ allocator-inst.cc \
codecvt.cc \
complex_io.cc \
concept-inst.cc \
@@ -137,7 +138,6 @@ sources = \
ostream-inst.cc \
sstream-inst.cc \
stdexcept.cc \
- stl-inst.cc \
streambuf-inst.cc \
string-inst.cc \
strstream.cc \
diff --git a/libstdc++-v3/src/Makefile.in b/libstdc++-v3/src/Makefile.in
index 8e01572be71..5662b6c502f 100644
--- a/libstdc++-v3/src/Makefile.in
+++ b/libstdc++-v3/src/Makefile.in
@@ -121,6 +121,7 @@ enable_shared = @enable_shared@
enable_static = @enable_static@
glibcpp_CXX = @glibcpp_CXX@
glibcpp_MOFILES = @glibcpp_MOFILES@
+glibcpp_PCHFLAGS = @glibcpp_PCHFLAGS@
glibcpp_POFILES = @glibcpp_POFILES@
glibcpp_basedir = @glibcpp_basedir@
glibcpp_localedir = @glibcpp_localedir@
@@ -199,6 +200,7 @@ target_sources_extra = \
# Sources present in the src directory.
sources = \
+ allocator-inst.cc \
codecvt.cc \
complex_io.cc \
concept-inst.cc \
@@ -219,7 +221,6 @@ sources = \
ostream-inst.cc \
sstream-inst.cc \
stdexcept.cc \
- stl-inst.cc \
streambuf-inst.cc \
string-inst.cc \
strstream.cc \
@@ -304,15 +305,15 @@ DEFS = @DEFS@ -I. -I$(srcdir) -I..
CPPFLAGS = @CPPFLAGS@
LDFLAGS = @LDFLAGS@
LIBS = @LIBS@
-libstdc___la_OBJECTS = codecvt.lo complex_io.lo concept-inst.lo \
-ctype.lo demangle.lo ext-inst.lo fstream-inst.lo functexcept.lo \
-globals.lo io-inst.lo ios.lo istream-inst.lo limits.lo locale.lo \
-locale-inst.lo localename.lo misc-inst.lo ostream-inst.lo \
-sstream-inst.lo stdexcept.lo stl-inst.lo streambuf-inst.lo \
-string-inst.lo strstream.lo valarray-inst.lo wstring-inst.lo \
-codecvt_members.lo collate_members.lo ctype_members.lo \
-messages_members.lo monetary_members.lo numeric_members.lo \
-time_members.lo basic_file.lo c++locale.lo
+libstdc___la_OBJECTS = allocator-inst.lo codecvt.lo complex_io.lo \
+concept-inst.lo ctype.lo demangle.lo ext-inst.lo fstream-inst.lo \
+functexcept.lo globals.lo io-inst.lo ios.lo istream-inst.lo limits.lo \
+locale.lo locale-inst.lo localename.lo misc-inst.lo ostream-inst.lo \
+sstream-inst.lo stdexcept.lo streambuf-inst.lo string-inst.lo \
+strstream.lo valarray-inst.lo wstring-inst.lo codecvt_members.lo \
+collate_members.lo ctype_members.lo messages_members.lo \
+monetary_members.lo numeric_members.lo time_members.lo basic_file.lo \
+c++locale.lo
CXXFLAGS = @CXXFLAGS@
CXXCOMPILE = $(CXX) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
CXXLD = $(CXX)
diff --git a/libstdc++-v3/src/allocator-inst.cc b/libstdc++-v3/src/allocator-inst.cc
new file mode 100644
index 00000000000..da8aeda2452
--- /dev/null
+++ b/libstdc++-v3/src/allocator-inst.cc
@@ -0,0 +1,41 @@
+// Explicit instantiation file.
+
+// Copyright (C) 1999, 2001, 2002, 2003 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
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// As a special exception, you may use this file as part of a free software
+// library without restriction. Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License. This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+//
+// ISO C++ 14882:
+//
+
+#include <bits/c++config.h>
+#include <memory>
+
+namespace std
+{
+ template class allocator<char>;
+ template class allocator<wchar_t>;
+} // namespace std
diff --git a/libstdc++-v3/testsuite/ext/allocators.cc b/libstdc++-v3/testsuite/ext/allocators.cc
index 3102c91bcde..34188c47328 100644
--- a/libstdc++-v3/testsuite/ext/allocators.cc
+++ b/libstdc++-v3/testsuite/ext/allocators.cc
@@ -1,6 +1,6 @@
// 2001-11-25 Phil Edwards <pme@gcc.gnu.org>
//
-// Copyright (C) 2001 Free Software Foundation, Inc.
+// Copyright (C) 2001, 2003 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
@@ -20,27 +20,25 @@
// 20.4.1.1 allocator members
-#include <memory>
#include <cstdlib>
+#include <memory>
+#include <ext/pool_allocator.h>
+#include <ext/debug_allocator.h>
+#include <ext/malloc_allocator.h>
#include <testsuite_hooks.h>
-typedef std::__malloc_alloc<3> weird_alloc;
-template class std::__malloc_alloc<3>;
-
-typedef std::__debug_alloc<weird_alloc> debug_weird_alloc;
-template class std::__debug_alloc<weird_alloc>;
-
-typedef std::__pool_alloc<true, 3> unshared_normal_alloc;
-template class std::__pool_alloc<true, 3>;
-
-typedef std::__pool_alloc<false, 3> unshared_singlethreaded;
-template class std::__pool_alloc<false, 3>;
+using __gnu_cxx::__malloc_alloc;
+using __gnu_cxx::__debug_alloc;
+using __gnu_cxx::__pool_alloc;
-//std::malloc_alloc test_malloc_alloc;
+template class __malloc_alloc<3>;
+template class __debug_alloc<__malloc_alloc<3> >;
+template class __pool_alloc<true, 3>;
+template class __pool_alloc<false, 3>;
struct big
{
- long f[15];
+ long f[15];
};
@@ -63,32 +61,32 @@ operator delete(void *v) throw()
return std::free(v);
}
-
-template <typename arbitrary_SGIstyle_allocator,
- bool uses_global_new_and_delete>
-void test()
+template<typename Alloc, bool uses_global_new_and_delete>
+void check_allocator()
{
+ bool test = true;
new_called = false;
delete_called = false;
requested = 0;
- std::__allocator<big, arbitrary_SGIstyle_allocator> a;
+ std::__allocator<big, Alloc> a;
big *p = a.allocate(10);
- if (uses_global_new_and_delete) VERIFY (requested >= (10*15*sizeof(long)));
+ if (uses_global_new_and_delete)
+ VERIFY( requested >= (10 * 15 * sizeof(long)) );
+
// Touch the far end of supposedly-allocated memory to check that we got
// all of it. Why "3"? Because it's my favorite integer between e and pi.
p[9].f[14] = 3;
- VERIFY (new_called == uses_global_new_and_delete );
+ VERIFY( new_called == uses_global_new_and_delete );
a.deallocate(p,10);
- VERIFY (delete_called == uses_global_new_and_delete );
+ VERIFY( delete_called == uses_global_new_and_delete );
}
-
// These just help tracking down error messages.
-void test01() { test<weird_alloc,false>(); }
-void test02() { test<debug_weird_alloc,false>(); }
-void test03() { test<unshared_normal_alloc,true>(); }
-void test04() { test<unshared_singlethreaded,true>(); }
+void test01() { check_allocator<__malloc_alloc<3>, false>(); }
+void test02() { check_allocator<__debug_alloc<__malloc_alloc<3> >, false>(); }
+void test03() { check_allocator<__pool_alloc<true, 3>, true>(); }
+void test04() { check_allocator<__pool_alloc<false, 3>, true>(); }
int main()
{
@@ -96,7 +94,6 @@ int main()
test02();
test03();
test04();
-
return 0;
}
diff --git a/libstdc++-v3/testsuite/ext/headers.cc b/libstdc++-v3/testsuite/ext/headers.cc
index a2c1233302d..52f6028bd12 100644
--- a/libstdc++-v3/testsuite/ext/headers.cc
+++ b/libstdc++-v3/testsuite/ext/headers.cc
@@ -1,6 +1,6 @@
// 1999-06-23 bkoz
-// Copyright (C) 1999, 2001 Free Software Foundation, Inc.
+// Copyright (C) 1999, 2001, 2003 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
@@ -33,5 +33,11 @@
#include <ext/rb_tree>
#include <ext/rope>
#include <ext/slist>
+#include <ext/debug_allocator.h>
+#include <ext/malloc_allocator.h>
+#include <ext/mt_allocator.h>
+#include <ext/pool_allocator.h>
+#include <ext/stdio_filebuf.h>
+#include <ext/stdio_sync_filebuf.h>
int main() { }