From 5a1e5472f5864b2a31d3ccee2c08fc26496dfeab Mon Sep 17 00:00:00 2001 From: Benjamin Kosnik Date: Tue, 12 Oct 2004 01:10:39 +0000 Subject: [PATCH] re PR libstdc++/17937 (Critical ~__pool troubles) 2004-10-11 Benjamin Kosnik * include/bits/stl_deque.h: Correct for over-long lines. 2004-10-11 Benjamin Kosnik PR libstdc++/17937 * include/ext/mt_allocator.h (__pool::_M_destroy): New. * src/mt_allocator.cc (__pool::~__pool): Change definitions to _M_destroy. * acconfig.h: Remove _GLIBCXX_USE___CXA_ATEXIT. * acinclude.m4 (GLIBCXX_ENABLE_CXA_ATEXIT): Remove. * configure.ac: Remove call to GLIBCXX_ENABLE_CXA_EXIT. * configure: Regenerate. * config/linker-map.gnu: Tweak exports. * docs/html/ext/mt_allocator.html: Update docs. * testsuite/ext/mt_allocator/deallocate_global-2.cc: Fix. * testsuite/ext/mt_allocator/deallocate_global-4.cc: Fix. * testsuite/ext/mt_allocator/deallocate_global_thread-1.cc: Fix. * testsuite/ext/mt_allocator/deallocate_global_thread-3.cc: Fix. * testsuite/ext/mt_allocator/deallocate_local-2.cc: Fix. * testsuite/ext/mt_allocator/deallocate_local-4.cc: Fix. * testsuite/ext/mt_allocator/deallocate_local_thread-3.cc: Fix. * testsuite/ext/mt_allocator/deallocate_local_thread-1.cc: Fix. From-SVN: r88913 --- libstdc++-v3/ChangeLog | 25 +++ libstdc++-v3/acconfig.h | 3 - libstdc++-v3/acinclude.m4 | 15 -- libstdc++-v3/config.h.in | 3 - libstdc++-v3/config/linker-map.gnu | 2 +- libstdc++-v3/configure | 29 +-- libstdc++-v3/configure.ac | 1 - libstdc++-v3/docs/html/ext/mt_allocator.html | 33 ++- libstdc++-v3/include/bits/stl_deque.h | 211 ++++++++++-------- libstdc++-v3/include/ext/mt_allocator.h | 13 +- libstdc++-v3/src/mt_allocator.cc | 10 +- .../ext/mt_allocator/deallocate_global-2.cc | 23 +- .../ext/mt_allocator/deallocate_global-4.cc | 23 +- .../deallocate_global_thread-1.cc | 23 +- .../deallocate_global_thread-3.cc | 23 +- .../ext/mt_allocator/deallocate_local-2.cc | 17 +- .../ext/mt_allocator/deallocate_local-4.cc | 17 +- .../mt_allocator/deallocate_local_thread-1.cc | 17 +- .../mt_allocator/deallocate_local_thread-3.cc | 17 +- .../testsuite/ext/mt_allocator/tune-3.cc | 2 +- .../testsuite/ext/mt_allocator/tune-4.cc | 2 +- 21 files changed, 270 insertions(+), 239 deletions(-) diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index c90171e3d21..f736c640fa8 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,28 @@ +2004-10-11 Benjamin Kosnik + + * include/bits/stl_deque.h: Correct for over-long lines. + +2004-10-11 Benjamin Kosnik + + PR libstdc++/17937 + * include/ext/mt_allocator.h (__pool::_M_destroy): New. + * src/mt_allocator.cc (__pool::~__pool): Change definitions to + _M_destroy. + * acconfig.h: Remove _GLIBCXX_USE___CXA_ATEXIT. + * acinclude.m4 (GLIBCXX_ENABLE_CXA_ATEXIT): Remove. + * configure.ac: Remove call to GLIBCXX_ENABLE_CXA_EXIT. + * configure: Regenerate. + * config/linker-map.gnu: Tweak exports. + * docs/html/ext/mt_allocator.html: Update docs. + * testsuite/ext/mt_allocator/deallocate_global-2.cc: Fix. + * testsuite/ext/mt_allocator/deallocate_global-4.cc: Fix. + * testsuite/ext/mt_allocator/deallocate_global_thread-1.cc: Fix. + * testsuite/ext/mt_allocator/deallocate_global_thread-3.cc: Fix. + * testsuite/ext/mt_allocator/deallocate_local-2.cc: Fix. + * testsuite/ext/mt_allocator/deallocate_local-4.cc: Fix. + * testsuite/ext/mt_allocator/deallocate_local_thread-3.cc: Fix. + * testsuite/ext/mt_allocator/deallocate_local_thread-1.cc: Fix. + 2004-10-11 Benjamin Kosnik PR libstdc++/16614 continued. diff --git a/libstdc++-v3/acconfig.h b/libstdc++-v3/acconfig.h index 6a2ba98887d..cffecbd172f 100644 --- a/libstdc++-v3/acconfig.h +++ b/libstdc++-v3/acconfig.h @@ -28,9 +28,6 @@ // Define to use concept checking code from the boost libraries. #undef _GLIBCXX_CONCEPT_CHECKS -// Define to use __cxa_atexit. -#undef _GLIBCXX_USE___CXA_ATEXIT - // Define to use symbol versioning in the shared library. #undef _GLIBCXX_SYMVER diff --git a/libstdc++-v3/acinclude.m4 b/libstdc++-v3/acinclude.m4 index ff775e5b199..5f744ceb4f4 100644 --- a/libstdc++-v3/acinclude.m4 +++ b/libstdc++-v3/acinclude.m4 @@ -611,21 +611,6 @@ AC_DEFUN([GLIBCXX_ENABLE_FULLY_DYNAMIC_STRING], [ fi ]) -dnl -dnl Check for --enable-__cxa_atexit -dnl -dnl --enable-__cxa_atexit defines _GLIBCXX_USE___CXA_ATEXIT -dnl --disable-__cxa_atexit doesn't define _GLIBCXX_USE___CXA_ATEXIT -dnl + Usage: GLIBCXX_ENABLE_FULLY_DYNAMIC_STRING[(DEFAULT)] -dnl Where DEFAULT is either `yes' or `no'. -dnl -AC_DEFUN([GLIBCXX_ENABLE_CXA_ATEXIT], [ - GLIBCXX_ENABLE(__cxa_atexit,$1,, - [Define if __cxa_atexit is to be used instead of atexit.]) - if test $enable___cxa_atexit = yes; then - AC_DEFINE(_GLIBCXX_USE___CXA_ATEXIT) - fi -]) dnl dnl Does any necessary configuration of the testsuite directory. Generates diff --git a/libstdc++-v3/config.h.in b/libstdc++-v3/config.h.in index be444e50187..acb7d732abc 100644 --- a/libstdc++-v3/config.h.in +++ b/libstdc++-v3/config.h.in @@ -29,9 +29,6 @@ // Define to use concept checking code from the boost libraries. #undef _GLIBCXX_CONCEPT_CHECKS -// Define to use __cxa_atexit. -#undef _GLIBCXX_USE___CXA_ATEXIT - // Define to use symbol versioning in the shared library. #undef _GLIBCXX_SYMVER diff --git a/libstdc++-v3/config/linker-map.gnu b/libstdc++-v3/config/linker-map.gnu index f6861c87b6f..d47368e7f6d 100644 --- a/libstdc++-v3/config/linker-map.gnu +++ b/libstdc++-v3/config/linker-map.gnu @@ -269,7 +269,7 @@ GLIBCXX_3.4.3 { _ZN9__gnu_cxx6__poolILb1EE16_M_get_thread_idEv; _ZN9__gnu_cxx6__poolILb[01]EE16_M_reserve_blockE[jm][jm]; _ZN9__gnu_cxx6__poolILb[01]EE16_M_reclaim_blockEPc[jm]; - _ZN9__gnu_cxx6__poolILb[01]EED[12]Ev; + _ZN9__gnu_cxx6__poolILb[01]EE10_M_destroyEv; # stub functions from libmath acosf; diff --git a/libstdc++-v3/configure b/libstdc++-v3/configure index caf27b1b049..b34c7dfc60e 100755 --- a/libstdc++-v3/configure +++ b/libstdc++-v3/configure @@ -856,8 +856,6 @@ Optional Features: --enable-sjlj-exceptions force use of builtin_setjmp for exceptions [default=auto] - --enable-__cxa_atexit Define if __cxa_atexit is to be used instead of - atexit. [default=no] --enable-libstdcxx-pch build pre-compiled libstdc++ headers [default=$is_hosted] --enable-cstdio=PACKAGE use target-specific I/O package @@ -4399,7 +4397,7 @@ test x"$pic_mode" = xno && libtool_flags="$libtool_flags --prefer-non-pic" case $host in *-*-irix6*) # Find out which ABI we are using. - echo '#line 4402 "configure"' > conftest.$ac_ext + echo '#line 4400 "configure"' > conftest.$ac_ext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? @@ -5020,7 +5018,7 @@ fi; # # Fake what AC_TRY_COMPILE does. XXX Look at redoing this new-style. cat > conftest.$ac_ext << EOF -#line 5023 "configure" +#line 5021 "configure" struct S { ~S(); }; void bar(); void foo() @@ -5076,29 +5074,6 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu echo "${ECHO_T}$ac_exception_model_name" >&6 - # Check whether --enable-__cxa_atexit or --disable-__cxa_atexit was given. -if test "${enable___cxa_atexit+set}" = set; then - enableval="$enable___cxa_atexit" - - case "$enableval" in - yes|no) ;; - *) { { echo "$as_me:$LINENO: error: Argument to enable/disable __cxa_atexit must be yes or no" >&5 -echo "$as_me: error: Argument to enable/disable __cxa_atexit must be yes or no" >&2;} - { (exit 1); exit 1; }; } ;; - esac - -else - enable___cxa_atexit=no -fi; - - if test $enable___cxa_atexit = yes; then - cat >>confdefs.h <<\_ACEOF -#define _GLIBCXX_USE___CXA_ATEXIT 1 -_ACEOF - - fi - - echo "$as_me:$LINENO: checking for enabled PCH" >&5 echo $ECHO_N "checking for enabled PCH... $ECHO_C" >&6 # Check whether --enable-libstdcxx-pch or --disable-libstdcxx-pch was given. diff --git a/libstdc++-v3/configure.ac b/libstdc++-v3/configure.ac index 9978891ff9b..a11f034120b 100644 --- a/libstdc++-v3/configure.ac +++ b/libstdc++-v3/configure.ac @@ -78,7 +78,6 @@ GLIBCXX_ENABLE_HOSTED # Check for support bits and g++ features that don't require linking. GLIBCXX_ENABLE_SJLJ_EXCEPTIONS -GLIBCXX_ENABLE_CXA_ATEXIT([no]) GLIBCXX_ENABLE_PCH($is_hosted) # Enable all the variable C++ runtime options. diff --git a/libstdc++-v3/docs/html/ext/mt_allocator.html b/libstdc++-v3/docs/html/ext/mt_allocator.html index f2f8348ca25..6c3c2700014 100644 --- a/libstdc++-v3/docs/html/ext/mt_allocator.html +++ b/libstdc++-v3/docs/html/ext/mt_allocator.html @@ -275,16 +275,29 @@ The _S_initialize() function: a thread decides to return some blocks to the global freelist.

-

Notes about deallocation. On systems with the function -__cxa_atexit, the allocator will free all memory -allocated before program termination. However, because this relies on -the precise and exactly-conforming ordering of static destructors, -including those of a static local __pool object, it is -not available on systems that don't have the necessary underlying -support. On those systems, memory debugging programs like valgrind or -purify may notice leaks: sorry about this inconvenience. However, most -operating systems actually reclaim this memory at program termination -anyway. +

Notes about deallocation. This allocator does not explicitly +release memory. Because of this, memory debugging programs like +valgrind or purify may notice leaks: sorry about this +inconvenience. Operating systems will reclaim allocated memory at +program termination anyway. If sidestepping this kind of noise is +desired, there are two options: use an allocator, like +new_allocator that releases memory while debugging, or +use GLIBCXX_FORCE_NEW to bypass the allocator's internal pools.

+ +

On systems with the function __cxa_atexit, the +allocator can be forced to free all memory allocated before program +termination with the member function +__pool_type::_M_destroy. However, because this member +function relies on the precise and exactly-conforming ordering of +static destructors, including those of a static local +__pool object, it should not be used, ever, on systems +that don't have the necessary underlying support. In addition, in +practice, forcing deallocation can be tricky, as it requires the +__pool object to be fully-constructed before the object +that uses it is fully constructed. For most (but not all) STL +containers, this works, as an instance of the allocator is constructed +as part of a container's constructor. However, this assumption is +implementation-specific, and subject to change.

diff --git a/libstdc++-v3/include/bits/stl_deque.h b/libstdc++-v3/include/bits/stl_deque.h index 36a7f39799e..8b50fb51bb5 100644 --- a/libstdc++-v3/include/bits/stl_deque.h +++ b/libstdc++-v3/include/bits/stl_deque.h @@ -87,10 +87,11 @@ namespace _GLIBCXX_STD /** * @brief A deque::iterator. * - * Quite a bit of intelligence here. Much of the functionality of deque is - * actually passed off to this class. A deque holds two of these internally, - * marking its valid range. Access to elements is done as offsets of either - * of those two, relying on operator overloading in this class. + * Quite a bit of intelligence here. Much of the functionality of + * deque is actually passed off to this class. A deque holds two + * of these internally, marking its valid range. Access to + * elements is done as offsets of either of those two, relying on + * operator overloading in this class. * * @if maint * All the functions are op overloads except for _M_set_node. @@ -219,9 +220,9 @@ namespace _GLIBCXX_STD { return *(*this + __n); } /** @if maint - * Prepares to traverse new_node. Sets everything except _M_cur, which - * should therefore be set by the caller immediately afterwards, based on - * _M_first and _M_last. + * Prepares to traverse new_node. Sets everything except + * _M_cur, which should therefore be set by the caller + * immediately afterwards, based on _M_first and _M_last. * @endif */ void @@ -445,7 +446,7 @@ namespace _GLIBCXX_STD _Deque_base<_Tp, _Alloc>:: _M_initialize_map(size_t __num_elements) { - const size_t __num_nodes = (__num_elements / __deque_buf_size(sizeof(_Tp)) + const size_t __num_nodes = (__num_elements/ __deque_buf_size(sizeof(_Tp)) + 1); this->_M_impl._M_map_size = std::max((size_t) _S_initial_map_size, @@ -530,28 +531,27 @@ namespace _GLIBCXX_STD * - size_t _M_map_size * - iterator _M_start, _M_finish * - * map_size is at least 8. %map is an array of map_size pointers-to-"nodes". - * (The name %map has nothing to do with the std::map class, and "nodes" - * should not be confused with std::list's usage of "node".) + * map_size is at least 8. %map is an array of map_size + * pointers-to-"nodes". (The name %map has nothing to do with the + * std::map class, and "nodes" should not be confused with + * std::list's usage of "node".) * - * A "node" has no specific type name as such, but it is referred to as - * "node" in this file. It is a simple array-of-Tp. If Tp is very large, - * there will be one Tp element per node (i.e., an "array" of one). - * For non-huge Tp's, node size is inversely related to Tp size: the - * larger the Tp, the fewer Tp's will fit in a node. The goal here is to - * keep the total size of a node relatively small and constant over different - * Tp's, to improve allocator efficiency. + * A "node" has no specific type name as such, but it is referred + * to as "node" in this file. It is a simple array-of-Tp. If Tp + * is very large, there will be one Tp element per node (i.e., an + * "array" of one). For non-huge Tp's, node size is inversely + * related to Tp size: the larger the Tp, the fewer Tp's will fit + * in a node. The goal here is to keep the total size of a node + * relatively small and constant over different Tp's, to improve + * allocator efficiency. * - * **** As I write this, the nodes are /not/ allocated using the high-speed - * memory pool. There are 20 hours left in the year; perhaps I can fix - * this before 2002. - * - * Not every pointer in the %map array will point to a node. If the initial - * number of elements in the deque is small, the /middle/ %map pointers will - * be valid, and the ones at the edges will be unused. This same situation - * will arise as the %map grows: available %map pointers, if any, will be on - * the ends. As new nodes are created, only a subset of the %map's pointers - * need to be copied "outward". + * Not every pointer in the %map array will point to a node. If + * the initial number of elements in the deque is small, the + * /middle/ %map pointers will be valid, and the ones at the edges + * will be unused. This same situation will arise as the %map + * grows: available %map pointers, if any, will be on the ends. As + * new nodes are created, only a subset of the %map's pointers need + * to be copied "outward". * * Class invariants: * - For any nonsingular iterator i: @@ -563,16 +563,17 @@ namespace _GLIBCXX_STD * - i.cur is a pointer in the range [i.first, i.last). NOTE: * the implication of this is that i.cur is always a dereferenceable * pointer, even if i is a past-the-end iterator. - * - Start and Finish are always nonsingular iterators. NOTE: this means that - * an empty deque must have one node, a deque with _M_impl._M_start, + { std::__uninitialized_copy_a(__x.begin(), __x.end(), + this->_M_impl._M_start, this->get_allocator()); } /** @@ -728,10 +730,10 @@ namespace _GLIBCXX_STD * @param n Number of elements to be assigned. * @param val Value to be assigned. * - * This function fills a %deque with @a n copies of the given value. - * Note that the assignment completely changes the %deque and that the - * resulting %deque's size is the same as the number of elements assigned. - * Old data may be lost. + * This function fills a %deque with @a n copies of the given + * value. Note that the assignment completely changes the + * %deque and that the resulting %deque's size is the same as + * the number of elements assigned. Old data may be lost. */ void assign(size_type __n, const value_type& __val) @@ -780,50 +782,53 @@ namespace _GLIBCXX_STD { return this->_M_impl._M_start; } /** - * Returns a read/write iterator that points one past the last element in - * the %deque. Iteration is done in ordinary element order. + * Returns a read/write iterator that points one past the last + * element in the %deque. Iteration is done in ordinary + * element order. */ iterator end() { return this->_M_impl._M_finish; } /** - * Returns a read-only (constant) iterator that points one past the last - * element in the %deque. Iteration is done in ordinary element order. + * Returns a read-only (constant) iterator that points one past + * the last element in the %deque. Iteration is done in + * ordinary element order. */ const_iterator end() const { return this->_M_impl._M_finish; } /** - * Returns a read/write reverse iterator that points to the last element - * in the %deque. Iteration is done in reverse element order. + * Returns a read/write reverse iterator that points to the + * last element in the %deque. Iteration is done in reverse + * element order. */ reverse_iterator rbegin() { return reverse_iterator(this->_M_impl._M_finish); } /** - * Returns a read-only (constant) reverse iterator that points to the - * last element in the %deque. Iteration is done in reverse element - * order. + * Returns a read-only (constant) reverse iterator that points + * to the last element in the %deque. Iteration is done in + * reverse element order. */ const_reverse_iterator rbegin() const { return const_reverse_iterator(this->_M_impl._M_finish); } /** - * Returns a read/write reverse iterator that points to one before the - * first element in the %deque. Iteration is done in reverse element - * order. + * Returns a read/write reverse iterator that points to one + * before the first element in the %deque. Iteration is done + * in reverse element order. */ reverse_iterator rend() { return reverse_iterator(this->_M_impl._M_start); } /** - * Returns a read-only (constant) reverse iterator that points to one - * before the first element in the %deque. Iteration is done in reverse - * element order. + * Returns a read-only (constant) reverse iterator that points + * to one before the first element in the %deque. Iteration is + * done in reverse element order. */ const_reverse_iterator rend() const @@ -845,10 +850,11 @@ namespace _GLIBCXX_STD * @param new_size Number of elements the %deque should contain. * @param x Data with which new elements should be populated. * - * This function will %resize the %deque to the specified number of - * elements. If the number is smaller than the %deque's current size the - * %deque is truncated, otherwise the %deque is extended and new elements - * are populated with given data. + * This function will %resize the %deque to the specified + * number of elements. If the number is smaller than the + * %deque's current size the %deque is truncated, otherwise the + * %deque is extended and new elements are populated with given + * data. */ void resize(size_type __new_size, const value_type& __x) @@ -864,17 +870,18 @@ namespace _GLIBCXX_STD * @brief Resizes the %deque to the specified number of elements. * @param new_size Number of elements the %deque should contain. * - * This function will resize the %deque to the specified number of - * elements. If the number is smaller than the %deque's current size the - * %deque is truncated, otherwise the %deque is extended and new elements - * are default-constructed. + * This function will resize the %deque to the specified number + * of elements. If the number is smaller than the %deque's + * current size the %deque is truncated, otherwise the %deque + * is extended and new elements are default-constructed. */ void resize(size_type new_size) { resize(new_size, value_type()); } /** - * Returns true if the %deque is empty. (Thus begin() would equal end().) + * Returns true if the %deque is empty. (Thus begin() would + * equal end().) */ bool empty() const @@ -882,26 +889,30 @@ namespace _GLIBCXX_STD // element access /** - * @brief Subscript access to the data contained in the %deque. - * @param n The index of the element for which data should be accessed. + * @brief Subscript access to the data contained in the %deque. + * @param n The index of the element for which data should be + * accessed. * @return Read/write reference to data. * * This operator allows for easy, array-style, data access. - * Note that data access with this operator is unchecked and out_of_range - * lookups are not defined. (For checked lookups see at().) + * Note that data access with this operator is unchecked and + * out_of_range lookups are not defined. (For checked lookups + * see at().) */ reference operator[](size_type __n) { return this->_M_impl._M_start[difference_type(__n)]; } /** - * @brief Subscript access to the data contained in the %deque. - * @param n The index of the element for which data should be accessed. + * @brief Subscript access to the data contained in the %deque. + * @param n The index of the element for which data should be + * accessed. * @return Read-only (constant) reference to data. * * This operator allows for easy, array-style, data access. - * Note that data access with this operator is unchecked and out_of_range - * lookups are not defined. (For checked lookups see at().) + * Note that data access with this operator is unchecked and + * out_of_range lookups are not defined. (For checked lookups + * see at().) */ const_reference operator[](size_type __n) const @@ -919,13 +930,14 @@ namespace _GLIBCXX_STD public: /** * @brief Provides access to the data contained in the %deque. - * @param n The index of the element for which data should be accessed. + * @param n The index of the element for which data should be + * accessed. * @return Read/write reference to data. * @throw std::out_of_range If @a n is an invalid index. * - * This function provides for safer data access. The parameter is first - * checked that it is in the range of the deque. The function throws - * out_of_range if the check fails. + * This function provides for safer data access. The parameter + * is first checked that it is in the range of the deque. The + * function throws out_of_range if the check fails. */ reference at(size_type __n) @@ -936,7 +948,8 @@ namespace _GLIBCXX_STD /** * @brief Provides access to the data contained in the %deque. - * @param n The index of the element for which data should be accessed. + * @param n The index of the element for which data should be + * accessed. * @return Read-only (constant) reference to data. * @throw std::out_of_range If @a n is an invalid index. * @@ -952,8 +965,8 @@ namespace _GLIBCXX_STD } /** - * Returns a read/write reference to the data at the first element of the - * %deque. + * Returns a read/write reference to the data at the first + * element of the %deque. */ reference front() @@ -996,9 +1009,10 @@ namespace _GLIBCXX_STD * @brief Add data to the front of the %deque. * @param x Data to be added. * - * This is a typical stack operation. The function creates an element at - * the front of the %deque and assigns the given data to it. Due to the - * nature of a %deque this operation can be done in constant time. + * This is a typical stack operation. The function creates an + * element at the front of the %deque and assigns the given + * data to it. Due to the nature of a %deque this operation + * can be done in constant time. */ void push_front(const value_type& __x) @@ -1016,9 +1030,10 @@ namespace _GLIBCXX_STD * @brief Add data to the end of the %deque. * @param x Data to be added. * - * This is a typical stack operation. The function creates an element at - * the end of the %deque and assigns the given data to it. Due to the - * nature of a %deque this operation can be done in constant time. + * This is a typical stack operation. The function creates an + * element at the end of the %deque and assigns the given data + * to it. Due to the nature of a %deque this operation can be + * done in constant time. */ void push_back(const value_type& __x) @@ -1106,9 +1121,9 @@ namespace _GLIBCXX_STD * @param first An input iterator. * @param last An input iterator. * - * This function will insert copies of the data in the range [first,last) - * into the %deque before the location specified by @a pos. This is - * known as "range insert." + * This function will insert copies of the data in the range + * [first,last) into the %deque before the location specified + * by @a pos. This is known as "range insert." */ template void @@ -1235,8 +1250,8 @@ namespace _GLIBCXX_STD * @brief Fills the %deque with copies of value. * @param value Initial value. * @return Nothing. - * @pre _M_start and _M_finish have already been initialized, but none of - * the %deque's elements have yet been constructed. + * @pre _M_start and _M_finish have already been initialized, + * but none of the %deque's elements have yet been constructed. * * This function is called only when the user provides an explicit size * (with or without an explicit exemplar value). @@ -1292,8 +1307,8 @@ namespace _GLIBCXX_STD erase(std::copy(__first, __last, begin()), end()); } - // Called by assign(n,t), and the range assign when it turns out to be the - // same thing. + // Called by assign(n,t), and the range assign when it turns out + // to be the same thing. void _M_fill_assign(size_type __n, const value_type& __val) { @@ -1419,9 +1434,9 @@ namespace _GLIBCXX_STD * @if maint * @brief Memory-handling helpers for the major %map. * - * Makes sure the _M_map has space for new nodes. Does not actually add - * the nodes. Can invalidate _M_map pointers. (And consequently, %deque - * iterators.) + * Makes sure the _M_map has space for new nodes. Does not + * actually add the nodes. Can invalidate _M_map pointers. + * (And consequently, %deque iterators.) * @endif */ void diff --git a/libstdc++-v3/include/ext/mt_allocator.h b/libstdc++-v3/include/ext/mt_allocator.h index 5803f5a835b..115ade7c284 100644 --- a/libstdc++-v3/include/ext/mt_allocator.h +++ b/libstdc++-v3/include/ext/mt_allocator.h @@ -274,6 +274,9 @@ namespace __gnu_cxx } } + void + _M_destroy() throw(); + char* _M_reserve_block(size_t __bytes, const size_t __thread_id); @@ -319,7 +322,7 @@ namespace __gnu_cxx _M_once = __tmp; } - ~__pool(); + ~__pool() { } private: // An "array" of bin_records each of which represents a specific @@ -364,6 +367,9 @@ namespace __gnu_cxx _M_initialize(); } + void + _M_destroy() throw(); + char* _M_reserve_block(size_t __bytes, const size_t __thread_id); @@ -387,7 +393,7 @@ namespace __gnu_cxx explicit __pool(const __pool_base::_Tune& __tune) : __pool_base(__tune), _M_bin(NULL), _M_bin_size(1) { } - ~__pool(); + ~__pool() { } private: // An "array" of bin_records each of which represents a specific @@ -638,9 +644,6 @@ namespace __gnu_cxx typedef __mt_alloc<_Tp1, pol_type> other; }; - // Create pool instance so that order of construction will be - // pool_type first, then allocator. This is necessary for - // correct global and static object construction/destruction. __mt_alloc() throw() { __policy_type::_S_get_pool(); } diff --git a/libstdc++-v3/src/mt_allocator.cc b/libstdc++-v3/src/mt_allocator.cc index 7c3f5a4fa64..373217d9ebc 100644 --- a/libstdc++-v3/src/mt_allocator.cc +++ b/libstdc++-v3/src/mt_allocator.cc @@ -46,9 +46,9 @@ namespace __gnu_internal namespace __gnu_cxx { - __pool::~__pool() + void + __pool::_M_destroy() throw() { -#ifdef _GLIBCXX_USE___CXA_ATEXIT if (_M_init && !_M_options._M_force_new) { for (size_t __n = 0; __n < _M_bin_size; ++__n) @@ -66,7 +66,6 @@ namespace __gnu_cxx delete _M_bin; delete _M_binmap; } -#endif } void @@ -174,9 +173,9 @@ namespace __gnu_cxx } #ifdef __GTHREADS - __pool::~__pool() + void + __pool::_M_destroy() throw() { -#ifdef _GLIBCXX_USE___CXA_ATEXIT if (_M_init && !_M_options._M_force_new) { if (__gthread_active_p()) @@ -216,7 +215,6 @@ namespace __gnu_cxx delete _M_bin; delete _M_binmap; } -#endif } void diff --git a/libstdc++-v3/testsuite/ext/mt_allocator/deallocate_global-2.cc b/libstdc++-v3/testsuite/ext/mt_allocator/deallocate_global-2.cc index 01baada5470..625cbc94cf1 100644 --- a/libstdc++-v3/testsuite/ext/mt_allocator/deallocate_global-2.cc +++ b/libstdc++-v3/testsuite/ext/mt_allocator/deallocate_global-2.cc @@ -19,6 +19,7 @@ // 20.4.1.1 allocator members +#include #include #include #include @@ -31,13 +32,15 @@ struct count_check count_check() {} ~count_check() { -#ifdef _GLIBCXX_USE___CXA_ATEXIT if (count != 0) - throw std::exception(); -#endif + { + // NB: __mt_allocator doesn't clean itself up. Thus, this will + // not be zero. + } } }; +// First. static count_check check; void* operator new(size_t size) throw(std::bad_alloc) @@ -63,15 +66,17 @@ void operator delete(void* p) throw() free(p); } -typedef char char_t; -typedef std::char_traits traits_t; -typedef __gnu_cxx::__common_pool_policy pool_t; -typedef __gnu_cxx::__mt_alloc allocator_t; -typedef std::basic_string string_t; +typedef std::string value_t; +typedef __gnu_cxx::__common_pool_policy policy_t; +typedef __gnu_cxx::__mt_alloc allocator_t; +typedef std::char_traits traits_t; +typedef std::list list_t; -string_t s("bayou bend"); +// Second. +list_t l; int main() { + l.push_back("bayou bend"); return 0; } diff --git a/libstdc++-v3/testsuite/ext/mt_allocator/deallocate_global-4.cc b/libstdc++-v3/testsuite/ext/mt_allocator/deallocate_global-4.cc index 3d5b96233f5..8d048bbeaaf 100644 --- a/libstdc++-v3/testsuite/ext/mt_allocator/deallocate_global-4.cc +++ b/libstdc++-v3/testsuite/ext/mt_allocator/deallocate_global-4.cc @@ -19,6 +19,7 @@ // 20.4.1.1 allocator members +#include #include #include #include @@ -31,13 +32,15 @@ struct count_check count_check() {} ~count_check() { -#ifdef _GLIBCXX_USE___CXA_ATEXIT if (count != 0) - throw std::runtime_error("count isn't zero"); -#endif + { + // NB: __mt_allocator doesn't clean itself up. Thus, this will + // not be zero. + } } }; +// First. static count_check check; void* operator new(size_t size) throw(std::bad_alloc) @@ -63,15 +66,17 @@ void operator delete(void* p) throw() free(p); } -typedef char char_t; -typedef std::char_traits traits_t; -typedef __gnu_cxx::__per_type_pool_policy pool_t; -typedef __gnu_cxx::__mt_alloc allocator_t; -typedef std::basic_string string_t; +typedef std::string value_t; +typedef __gnu_cxx::__per_type_pool_policy policy_t; +typedef __gnu_cxx::__mt_alloc allocator_t; +typedef std::char_traits traits_t; +typedef std::list list_t; -string_t s("bayou bend"); +// Second. +list_t l; int main() { + l.push_back("bayou bend"); return 0; } diff --git a/libstdc++-v3/testsuite/ext/mt_allocator/deallocate_global_thread-1.cc b/libstdc++-v3/testsuite/ext/mt_allocator/deallocate_global_thread-1.cc index 3ec3abcd6b6..0a6904171d0 100644 --- a/libstdc++-v3/testsuite/ext/mt_allocator/deallocate_global_thread-1.cc +++ b/libstdc++-v3/testsuite/ext/mt_allocator/deallocate_global_thread-1.cc @@ -19,6 +19,7 @@ // 20.4.1.1 allocator members +#include #include #include #include @@ -31,13 +32,15 @@ struct count_check count_check() {} ~count_check() { -#ifdef _GLIBCXX_USE___CXA_ATEXIT if (count != 0) - throw std::runtime_error("count isn't zero"); -#endif + { + // NB: __mt_allocator doesn't clean itself up. Thus, this will + // not be zero. + } } }; +// First. static count_check check; void* operator new(size_t size) throw(std::bad_alloc) @@ -63,15 +66,17 @@ void operator delete(void* p) throw() free(p); } -typedef char char_t; -typedef std::char_traits traits_t; -typedef __gnu_cxx::__common_pool_policy pool_t; -typedef __gnu_cxx::__mt_alloc allocator_t; -typedef std::basic_string string_t; +typedef std::string value_t; +typedef __gnu_cxx::__common_pool_policy policy_t; +typedef __gnu_cxx::__mt_alloc allocator_t; +typedef std::char_traits traits_t; +typedef std::list list_t; -string_t s("bayou bend"); +// Second. +list_t l; int main() { + l.push_back("bayou bend"); return 0; } diff --git a/libstdc++-v3/testsuite/ext/mt_allocator/deallocate_global_thread-3.cc b/libstdc++-v3/testsuite/ext/mt_allocator/deallocate_global_thread-3.cc index 398ef31d39d..d764d41c9a0 100644 --- a/libstdc++-v3/testsuite/ext/mt_allocator/deallocate_global_thread-3.cc +++ b/libstdc++-v3/testsuite/ext/mt_allocator/deallocate_global_thread-3.cc @@ -19,6 +19,7 @@ // 20.4.1.1 allocator members +#include #include #include #include @@ -31,13 +32,15 @@ struct count_check count_check() {} ~count_check() { -#ifdef _GLIBCXX_USE___CXA_ATEXIT if (count != 0) - throw std::runtime_error("count isn't zero"); -#endif + { + // NB: __mt_allocator doesn't clean itself up. Thus, this will + // not be zero. + } } }; +// First. static count_check check; void* operator new(size_t size) throw(std::bad_alloc) @@ -63,15 +66,17 @@ void operator delete(void* p) throw() free(p); } -typedef char char_t; -typedef std::char_traits traits_t; -typedef __gnu_cxx::__per_type_pool_policy pool_t; -typedef __gnu_cxx::__mt_alloc allocator_t; -typedef std::basic_string string_t; +typedef std::string value_t; +typedef __gnu_cxx::__per_type_pool_policy policy_t; +typedef __gnu_cxx::__mt_alloc allocator_t; +typedef std::char_traits traits_t; +typedef std::list list_t; -string_t s("bayou bend"); +// Second. +list_t l; int main() { + l.push_back("bayou bend"); return 0; } diff --git a/libstdc++-v3/testsuite/ext/mt_allocator/deallocate_local-2.cc b/libstdc++-v3/testsuite/ext/mt_allocator/deallocate_local-2.cc index b8e2784f484..ae1ca528ee0 100644 --- a/libstdc++-v3/testsuite/ext/mt_allocator/deallocate_local-2.cc +++ b/libstdc++-v3/testsuite/ext/mt_allocator/deallocate_local-2.cc @@ -31,10 +31,11 @@ struct count_check count_check() {} ~count_check() { -#ifdef _GLIBCXX_USE___CXA_ATEXIT if (count != 0) - throw std::runtime_error("count isn't zero"); -#endif + { + // NB: __mt_allocator doesn't clean itself up. Thus, this will + // not be zero. + } } }; @@ -63,11 +64,11 @@ void operator delete(void* p) throw() free(p); } -typedef char char_t; -typedef std::char_traits traits_t; -typedef __gnu_cxx::__common_pool_policy pool_t; -typedef __gnu_cxx::__mt_alloc allocator_t; -typedef std::basic_string string_t; +typedef char value_t; +typedef std::char_traits traits_t; +typedef __gnu_cxx::__common_pool_policy policy_t; +typedef __gnu_cxx::__mt_alloc allocator_t; +typedef std::basic_string string_t; int main() { diff --git a/libstdc++-v3/testsuite/ext/mt_allocator/deallocate_local-4.cc b/libstdc++-v3/testsuite/ext/mt_allocator/deallocate_local-4.cc index 1df7fb500cd..5321b8d61fa 100644 --- a/libstdc++-v3/testsuite/ext/mt_allocator/deallocate_local-4.cc +++ b/libstdc++-v3/testsuite/ext/mt_allocator/deallocate_local-4.cc @@ -31,10 +31,11 @@ struct count_check count_check() {} ~count_check() { -#ifdef _GLIBCXX_USE___CXA_ATEXIT if (count != 0) - throw std::runtime_error("count isn't zero"); -#endif + { + // NB: __mt_allocator doesn't clean itself up. Thus, this will + // not be zero. + } } }; @@ -63,11 +64,11 @@ void operator delete(void* p) throw() free(p); } -typedef char char_t; -typedef std::char_traits traits_t; -typedef __gnu_cxx::__per_type_pool_policy pool_t; -typedef __gnu_cxx::__mt_alloc allocator_t; -typedef std::basic_string string_t; +typedef char value_t; +typedef std::char_traits traits_t; +typedef __gnu_cxx::__per_type_pool_policy policy_t; +typedef __gnu_cxx::__mt_alloc allocator_t; +typedef std::basic_string string_t; int main() { diff --git a/libstdc++-v3/testsuite/ext/mt_allocator/deallocate_local_thread-1.cc b/libstdc++-v3/testsuite/ext/mt_allocator/deallocate_local_thread-1.cc index 2191264e942..0f3a57a4c8b 100644 --- a/libstdc++-v3/testsuite/ext/mt_allocator/deallocate_local_thread-1.cc +++ b/libstdc++-v3/testsuite/ext/mt_allocator/deallocate_local_thread-1.cc @@ -31,10 +31,11 @@ struct count_check count_check() {} ~count_check() { -#ifdef _GLIBCXX_USE___CXA_ATEXIT if (count != 0) - throw std::runtime_error("count isn't zero"); -#endif + { + // NB: __mt_allocator doesn't clean itself up. Thus, this will + // not be zero. + } } }; @@ -63,11 +64,11 @@ void operator delete(void* p) throw() free(p); } -typedef char char_t; -typedef std::char_traits traits_t; -typedef __gnu_cxx::__common_pool_policy pool_t; -typedef __gnu_cxx::__mt_alloc allocator_t; -typedef std::basic_string string_t; +typedef char value_t; +typedef std::char_traits traits_t; +typedef __gnu_cxx::__common_pool_policy policy_t; +typedef __gnu_cxx::__mt_alloc allocator_t; +typedef std::basic_string string_t; int main() { diff --git a/libstdc++-v3/testsuite/ext/mt_allocator/deallocate_local_thread-3.cc b/libstdc++-v3/testsuite/ext/mt_allocator/deallocate_local_thread-3.cc index 6094a718a0e..e293b5c5193 100644 --- a/libstdc++-v3/testsuite/ext/mt_allocator/deallocate_local_thread-3.cc +++ b/libstdc++-v3/testsuite/ext/mt_allocator/deallocate_local_thread-3.cc @@ -31,10 +31,11 @@ struct count_check count_check() {} ~count_check() { -#ifdef _GLIBCXX_USE___CXA_ATEXIT if (count != 0) - throw std::runtime_error("count isn't zero"); -#endif + { + // NB: __mt_allocator doesn't clean itself up. Thus, this will + // not be zero. + } } }; @@ -63,11 +64,11 @@ void operator delete(void* p) throw() free(p); } -typedef char char_t; -typedef std::char_traits traits_t; -typedef __gnu_cxx::__per_type_pool_policy pool_t; -typedef __gnu_cxx::__mt_alloc allocator_t; -typedef std::basic_string string_t; +typedef char value_t; +typedef std::char_traits traits_t; +typedef __gnu_cxx::__per_type_pool_policy policy_t; +typedef __gnu_cxx::__mt_alloc allocator_t; +typedef std::basic_string string_t; int main() { diff --git a/libstdc++-v3/testsuite/ext/mt_allocator/tune-3.cc b/libstdc++-v3/testsuite/ext/mt_allocator/tune-3.cc index c7049fc8e23..6e8098a609d 100644 --- a/libstdc++-v3/testsuite/ext/mt_allocator/tune-3.cc +++ b/libstdc++-v3/testsuite/ext/mt_allocator/tune-3.cc @@ -30,7 +30,7 @@ struct test_policy template struct test_policy<__gnu_cxx::__common_pool_policy<_Thread> > { - typedef __gnu_cxx::__common_pool_policy<_Thread> pool_type; + typedef __gnu_cxx::__common_pool_policy<_Thread> policy_type; static bool per_type() { return false; } }; diff --git a/libstdc++-v3/testsuite/ext/mt_allocator/tune-4.cc b/libstdc++-v3/testsuite/ext/mt_allocator/tune-4.cc index 90c0c4a709c..993f7b3a52e 100644 --- a/libstdc++-v3/testsuite/ext/mt_allocator/tune-4.cc +++ b/libstdc++-v3/testsuite/ext/mt_allocator/tune-4.cc @@ -30,7 +30,7 @@ struct test_policy template struct test_policy<__gnu_cxx::__common_pool_policy<_Thread> > { - typedef __gnu_cxx::__common_pool_policy<_Thread> pool_type; + typedef __gnu_cxx::__common_pool_policy<_Thread> policy_type; static bool per_type() { return false; } };