aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpaolo <paolo@138bc75d-0d04-0410-961f-82ee72b054a4>2011-05-03 17:54:35 +0000
committerpaolo <paolo@138bc75d-0d04-0410-961f-82ee72b054a4>2011-05-03 17:54:35 +0000
commit6cc36bf90838d09b0a4899228bde2b009dd7c7dc (patch)
tree71909e23b272c04fac453885b29750d48f29a16c
parentab9047340859545251be5c074524d69327901407 (diff)
2011-05-03 Paolo Carlini <paolo.carlini@oracle.com>
PR libstdc++/48750 * include/parallel/multiway_merge.h: Run _ValueType destructors. * include/parallel/multiway_mergesort.h: Likewise. * include/parallel/quicksort.h: Likewise. * include/parallel/random_shuffle.h: Likewise. * include/parallel/partial_sum.h: Likewise. * include/parallel/losertree.h: Run destructors; minor tweaks. * include/parallel/par_loop.h: Run destructors, fix memory allocations and deallocations. * testsuite/26_numerics/accumulate/48750.cc: New. * testsuite/ext/profile/mutex_extensions_neg.cc: Do not run in parallel-mode to avoid spurious multiple errors. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/gcc-4_6-branch@173335 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--libstdc++-v3/ChangeLog16
-rw-r--r--libstdc++-v3/include/parallel/losertree.h43
-rw-r--r--libstdc++-v3/include/parallel/multiway_merge.h19
-rw-r--r--libstdc++-v3/include/parallel/multiway_mergesort.h11
-rw-r--r--libstdc++-v3/include/parallel/par_loop.h19
-rw-r--r--libstdc++-v3/include/parallel/partial_sum.h3
-rw-r--r--libstdc++-v3/include/parallel/quicksort.h4
-rw-r--r--libstdc++-v3/include/parallel/random_shuffle.h13
-rw-r--r--libstdc++-v3/testsuite/26_numerics/accumulate/48750.cc70
-rw-r--r--libstdc++-v3/testsuite/ext/profile/mutex_extensions_neg.cc3
10 files changed, 166 insertions, 35 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index c42540f4527..26f49996255 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,3 +1,19 @@
+2011-05-03 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR libstdc++/48750
+ * include/parallel/multiway_merge.h: Run _ValueType destructors.
+ * include/parallel/multiway_mergesort.h: Likewise.
+ * include/parallel/quicksort.h: Likewise.
+ * include/parallel/random_shuffle.h: Likewise.
+ * include/parallel/partial_sum.h: Likewise.
+ * include/parallel/losertree.h: Run destructors; minor tweaks.
+ * include/parallel/par_loop.h: Run destructors, fix memory
+ allocations and deallocations.
+ * testsuite/26_numerics/accumulate/48750.cc: New.
+
+ * testsuite/ext/profile/mutex_extensions_neg.cc: Do not run in
+ parallel-mode to avoid spurious multiple errors.
+
2011-04-30 Doug Kwan <dougkwan@google.com>
* include/Makefile.am (install-freestanding-headers): Also install
diff --git a/libstdc++-v3/include/parallel/losertree.h b/libstdc++-v3/include/parallel/losertree.h
index 8d7b137aaf5..cb24f7f6771 100644
--- a/libstdc++-v3/include/parallel/losertree.h
+++ b/libstdc++-v3/include/parallel/losertree.h
@@ -1,6 +1,6 @@
// -*- C++ -*-
-// Copyright (C) 2007, 2008, 2009 Free Software Foundation, Inc.
+// Copyright (C) 2007, 2008, 2009, 2010, 2011 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
@@ -116,7 +116,11 @@ namespace __gnu_parallel
* @brief The destructor.
*/
~_LoserTreeBase()
- { ::operator delete(_M_losers); }
+ {
+ for (unsigned int __i = 0; __i < (2 * _M_k); ++__i)
+ _M_losers[__i].~_Loser();
+ ::operator delete(_M_losers);
+ }
/**
* @brief Initializes the sequence "_M_source" with the element "__key".
@@ -131,15 +135,15 @@ namespace __gnu_parallel
{
unsigned int __pos = _M_k + __source;
- if(_M_first_insert)
+ if (_M_first_insert)
{
- // Construct all keys, so we can easily deconstruct them.
+ // Construct all keys, so we can easily destruct them.
for (unsigned int __i = 0; __i < (2 * _M_k); ++__i)
- new(&(_M_losers[__i]._M_key)) _Tp(__key);
+ ::new(&(_M_losers[__i]._M_key)) _Tp(__key);
_M_first_insert = false;
}
else
- new(&(_M_losers[__pos]._M_key)) _Tp(__key);
+ _M_losers[__pos]._M_key = __key;
_M_losers[__pos]._M_sup = __sup;
_M_losers[__pos]._M_source = __source;
@@ -379,7 +383,7 @@ namespace __gnu_parallel
}
~_LoserTreePointerBase()
- { ::operator delete[](_M_losers); }
+ { delete[] _M_losers; }
int __get_min_source()
{ return _M_losers[0]._M_source; }
@@ -577,7 +581,7 @@ namespace __gnu_parallel
_Compare _M_comp;
public:
- _LoserTreeUnguardedBase(unsigned int __k, const _Tp __sentinel,
+ _LoserTreeUnguardedBase(unsigned int __k, const _Tp& __sentinel,
_Compare __comp = std::less<_Tp>())
: _M_comp(__comp)
{
@@ -590,15 +594,24 @@ namespace __gnu_parallel
_M_losers = static_cast<_Loser*>(::operator new(2 * _M_k
* sizeof(_Loser)));
- for (unsigned int __i = _M_k + _M_ik - 1; __i < (2 * _M_k); ++__i)
- {
- _M_losers[__i]._M_key = __sentinel;
+ for (unsigned int __i = 0; __i < _M_k; ++__i)
+ {
+ ::new(&(_M_losers[__i]._M_key)) _Tp(__sentinel);
+ _M_losers[__i]._M_source = -1;
+ }
+ for (unsigned int __i = _M_k + _M_ik - 1; __i < (2 * _M_k); ++__i)
+ {
+ ::new(&(_M_losers[__i]._M_key)) _Tp(__sentinel);
_M_losers[__i]._M_source = -1;
}
}
~_LoserTreeUnguardedBase()
- { ::operator delete(_M_losers); }
+ {
+ for (unsigned int __i = 0; __i < (2 * _M_k); ++__i)
+ _M_losers[__i].~_Loser();
+ ::operator delete(_M_losers);
+ }
int
__get_min_source()
@@ -615,7 +628,7 @@ namespace __gnu_parallel
{
unsigned int __pos = _M_k + __source;
- new(&(_M_losers[__pos]._M_key)) _Tp(__key);
+ ::new(&(_M_losers[__pos]._M_key)) _Tp(__key);
_M_losers[__pos]._M_source = __source;
}
};
@@ -634,7 +647,7 @@ namespace __gnu_parallel
using _Base::_M_losers;
public:
- _LoserTreeUnguarded(unsigned int __k, const _Tp __sentinel,
+ _LoserTreeUnguarded(unsigned int __k, const _Tp& __sentinel,
_Compare __comp = std::less<_Tp>())
: _Base::_LoserTreeUnguardedBase(__k, __sentinel, __comp)
{ }
@@ -721,7 +734,7 @@ namespace __gnu_parallel
using _Base::_M_losers;
public:
- _LoserTreeUnguarded(unsigned int __k, const _Tp __sentinel,
+ _LoserTreeUnguarded(unsigned int __k, const _Tp& __sentinel,
_Compare __comp = std::less<_Tp>())
: _Base::_LoserTreeUnguardedBase(__k, __sentinel, __comp)
{ }
diff --git a/libstdc++-v3/include/parallel/multiway_merge.h b/libstdc++-v3/include/parallel/multiway_merge.h
index 0fd3da2d656..00df31c131c 100644
--- a/libstdc++-v3/include/parallel/multiway_merge.h
+++ b/libstdc++-v3/include/parallel/multiway_merge.h
@@ -1045,11 +1045,12 @@ namespace __gnu_parallel
_ValueType;
// __k sequences.
- _SeqNumber __k = static_cast<_SeqNumber>(__seqs_end - __seqs_begin);
+ const _SeqNumber __k
+ = static_cast<_SeqNumber>(__seqs_end - __seqs_begin);
- _ThreadIndex __num_threads = omp_get_num_threads();
+ const _ThreadIndex __num_threads = omp_get_num_threads();
- _DifferenceType __num_samples =
+ const _DifferenceType __num_samples =
__gnu_parallel::_Settings::get().merge_oversampling * __num_threads;
_ValueType* __samples = static_cast<_ValueType*>
@@ -1096,6 +1097,10 @@ namespace __gnu_parallel
__pieces[__slab][__seq].second =
_GLIBCXX_PARALLEL_LENGTH(__seqs_begin[__seq]);
}
+
+ for (_SeqNumber __s = 0; __s < __k; ++__s)
+ for (_DifferenceType __i = 0; __i < __num_samples; ++__i)
+ __samples[__s * __num_samples + __i].~_ValueType();
::operator delete(__samples);
}
@@ -1258,10 +1263,10 @@ namespace __gnu_parallel
__length = std::min<_DifferenceTp>(__length, __total_length);
if (__total_length == 0 || __k == 0)
- {
- delete[] __ne_seqs;
- return __target;
- }
+ {
+ delete[] __ne_seqs;
+ return __target;
+ }
std::vector<std::pair<_DifferenceType, _DifferenceType> >* __pieces;
diff --git a/libstdc++-v3/include/parallel/multiway_mergesort.h b/libstdc++-v3/include/parallel/multiway_mergesort.h
index c0dab63f140..af7c10ac119 100644
--- a/libstdc++-v3/include/parallel/multiway_mergesort.h
+++ b/libstdc++-v3/include/parallel/multiway_mergesort.h
@@ -378,6 +378,8 @@ namespace __gnu_parallel
# pragma omp barrier
+ for (_DifferenceType __i = 0; __i < __length_local; ++__i)
+ __sd->_M_temporary[__iam][__i].~_ValueType();
::operator delete(__sd->_M_temporary[__iam]);
}
@@ -413,6 +415,7 @@ namespace __gnu_parallel
// shared variables
_PMWMSSortingData<_RAIter> __sd;
_DifferenceType* __starts;
+ _DifferenceType __size;
# pragma omp parallel num_threads(__num_threads)
{
@@ -427,7 +430,7 @@ namespace __gnu_parallel
if (!__exact)
{
- _DifferenceType __size =
+ __size =
(_Settings::get().sort_mwms_oversampling * __num_threads - 1)
* __num_threads;
__sd._M_samples = static_cast<_ValueType*>
@@ -463,7 +466,11 @@ namespace __gnu_parallel
delete[] __sd._M_temporary;
if (!__exact)
- ::operator delete(__sd._M_samples);
+ {
+ for (_DifferenceType __i = 0; __i < __size; ++__i)
+ __sd._M_samples[__i].~_ValueType();
+ ::operator delete(__sd._M_samples);
+ }
delete[] __sd._M_offsets;
delete[] __sd._M_pieces;
diff --git a/libstdc++-v3/include/parallel/par_loop.h b/libstdc++-v3/include/parallel/par_loop.h
index 1e21d3ad042..b776df4b7cb 100644
--- a/libstdc++-v3/include/parallel/par_loop.h
+++ b/libstdc++-v3/include/parallel/par_loop.h
@@ -91,8 +91,7 @@ namespace __gnu_parallel
_ThreadIndex __iam = omp_get_thread_num();
// Neutral element.
- _Result* __reduct = static_cast<_Result*>
- (::operator new(sizeof(_Result)));
+ _Result* __reduct;
_DifferenceType
__start = equally_split_point(__length, __num_threads, __iam),
@@ -100,7 +99,7 @@ namespace __gnu_parallel
if (__start < __stop)
{
- new(__reduct) _Result(__f(__o, __begin + __start));
+ __reduct = new _Result(__f(__o, __begin + __start));
++__start;
__constructed[__iam] = true;
}
@@ -110,18 +109,26 @@ namespace __gnu_parallel
for (; __start < __stop; ++__start)
*__reduct = __r(*__reduct, __f(__o, __begin + __start));
- __thread_results[__iam] = *__reduct;
+ if (__constructed[__iam])
+ {
+ ::new(&__thread_results[__iam]) _Result(*__reduct);
+ delete __reduct;
+ }
} //parallel
for (_ThreadIndex __i = 0; __i < __num_threads; ++__i)
if (__constructed[__i])
- __output = __r(__output, __thread_results[__i]);
+ {
+ __output = __r(__output, __thread_results[__i]);
+ __thread_results[__i].~_Result();
+ }
// Points to last element processed (needed as return value for
// some algorithms like transform).
__f._M_finish_iterator = __begin + __length;
- delete[] __thread_results;
+ ::operator delete(__thread_results);
+
delete[] __constructed;
return __o;
diff --git a/libstdc++-v3/include/parallel/partial_sum.h b/libstdc++-v3/include/parallel/partial_sum.h
index 5513c2f9375..0be98817816 100644
--- a/libstdc++-v3/include/parallel/partial_sum.h
+++ b/libstdc++-v3/include/parallel/partial_sum.h
@@ -184,7 +184,10 @@ namespace __gnu_parallel
__bin_op, __sums[__iam]);
} //parallel
+ for (_ThreadIndex __i = 0; __i < __num_threads; ++__i)
+ __sums[__i].~_ValueType();
::operator delete(__sums);
+
delete[] __borders;
return __result + __n;
diff --git a/libstdc++-v3/include/parallel/quicksort.h b/libstdc++-v3/include/parallel/quicksort.h
index 1884eb867fa..1b4d5983d06 100644
--- a/libstdc++-v3/include/parallel/quicksort.h
+++ b/libstdc++-v3/include/parallel/quicksort.h
@@ -1,6 +1,6 @@
// -*- C++ -*-
-// Copyright (C) 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
+// Copyright (C) 2007, 2008, 2009, 2010, 2011 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
@@ -82,6 +82,8 @@ namespace __gnu_parallel
_DifferenceType __split = __parallel_partition(__begin, __end,
__pred, __num_threads);
+ for (_DifferenceType __s = 0; __s < __num_samples; ++__s)
+ __samples[__s].~_ValueType();
::operator delete(__samples);
return __split;
diff --git a/libstdc++-v3/include/parallel/random_shuffle.h b/libstdc++-v3/include/parallel/random_shuffle.h
index bae95724966..c3967c22880 100644
--- a/libstdc++-v3/include/parallel/random_shuffle.h
+++ b/libstdc++-v3/include/parallel/random_shuffle.h
@@ -1,6 +1,6 @@
// -*- C++ -*-
-// Copyright (C) 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
+// Copyright (C) 2007, 2008, 2009, 2010, 2011 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
@@ -209,7 +209,7 @@ namespace __gnu_parallel
_ThreadIndex __target_p = __bin_proc[__target_bin];
// Last column [__d->_M_num_threads] stays unchanged.
- ::new(&(__temporaries[__target_p][__dist[__target_bin + 1]++]))
+ ::new(&(__temporaries[__target_p][__dist[__target_bin + 1]++]))
_ValueType(*(__source + __i + __start));
}
@@ -227,8 +227,8 @@ namespace __gnu_parallel
(__sd->_M_temporaries[__iam]
+ (__b == __d->_M_bins_begin
? 0 : __sd->_M_dist[__b][__d->_M_num_threads])),
- * __end = (__sd->_M_temporaries[__iam]
- + __sd->_M_dist[__b + 1][__d->_M_num_threads]);
+ *__end = (__sd->_M_temporaries[__iam]
+ + __sd->_M_dist[__b + 1][__d->_M_num_threads]);
__sequential_random_shuffle(__begin, __end, __rng);
std::copy(__begin, __end, __sd->_M_source + __global_offset
@@ -236,6 +236,8 @@ namespace __gnu_parallel
? 0 : __sd->_M_dist[__b][__d->_M_num_threads]));
}
+ for (_SequenceIndex __i = 0; __i < __offset; ++__i)
+ __sd->_M_temporaries[__iam][__i].~_ValueType();
::operator delete(__sd->_M_temporaries[__iam]);
}
@@ -501,6 +503,9 @@ namespace __gnu_parallel
delete[] __dist0;
delete[] __dist1;
delete[] __oracles;
+
+ for (_DifferenceType __i = 0; __i < __n; ++__i)
+ __target[__i].~_ValueType();
::operator delete(__target);
}
else
diff --git a/libstdc++-v3/testsuite/26_numerics/accumulate/48750.cc b/libstdc++-v3/testsuite/26_numerics/accumulate/48750.cc
new file mode 100644
index 00000000000..450382c3c39
--- /dev/null
+++ b/libstdc++-v3/testsuite/26_numerics/accumulate/48750.cc
@@ -0,0 +1,70 @@
+// Copyright (C) 2011 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 3, 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 COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+#include <vector>
+#include <numeric>
+
+class NaturalParameters
+{
+public:
+
+ NaturalParameters()
+ : m_data(2)
+ { }
+
+ std::vector<double>::const_iterator
+ begin() const
+ { return m_data.begin(); }
+
+ std::vector<double>::const_iterator
+ end() const
+ { return m_data.begin(); }
+
+ NaturalParameters&
+ operator+=(const NaturalParameters&)
+ { return *this; }
+
+private:
+ std::vector<double> m_data;
+};
+
+inline
+NaturalParameters
+operator+(const NaturalParameters& a, const NaturalParameters& b)
+{
+ NaturalParameters tmp = a;
+ return tmp += b;
+}
+
+// libstdc++/48750
+void test01()
+{
+ // Used to fail in parallel-mode with a segfault.
+ for (std::size_t i = 0; i < 1000; ++i)
+ {
+ std::vector<NaturalParameters> ChildrenNP(1000);
+ NaturalParameters init;
+ NaturalParameters NP = std::accumulate(ChildrenNP.begin(),
+ ChildrenNP.end(), init);
+ }
+}
+
+int main()
+{
+ test01();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/ext/profile/mutex_extensions_neg.cc b/libstdc++-v3/testsuite/ext/profile/mutex_extensions_neg.cc
index 174a8af556c..c0b1f688ab6 100644
--- a/libstdc++-v3/testsuite/ext/profile/mutex_extensions_neg.cc
+++ b/libstdc++-v3/testsuite/ext/profile/mutex_extensions_neg.cc
@@ -3,6 +3,9 @@
// -*- C++ -*-
+// Otherwise we may get *multiple* errors.
+#undef _GLIBCXX_PARALLEL
+
// Copyright (C) 2006, 2007, 2009, 2010, 2011 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free