re PR libstdc++/48760 (std::complex constructor buggy in the face of NaN's)
[gcc.git] / libstdc++-v3 / include / parallel / partial_sum.h
index 10673af04ba6b634f06d3d01db34fb859dbae2b7..1a7697a6cefc83622c19157f63a9c1dbbb40f822 100644 (file)
@@ -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
@@ -124,15 +124,18 @@ namespace __gnu_parallel
          __borders = new _DifferenceType[__num_threads + 2];
 
          if (__s.partial_sum_dilation == 1.0f)
-           equally_split(__n, __num_threads + 1, __borders);
+           __equally_split(__n, __num_threads + 1, __borders);
          else
            {
+             _DifferenceType __first_part_length =
+                 std::max<_DifferenceType>(1,
+                   __n / (1.0f + __s.partial_sum_dilation * __num_threads));
              _DifferenceType __chunk_length =
-               ((double)__n
-                / ((double)__num_threads + __s.partial_sum_dilation)),
-               __borderstart = __n - __num_threads * __chunk_length;
+                 (__n - __first_part_length) / __num_threads;
+             _DifferenceType __borderstart =
+                 __n - __num_threads * __chunk_length;
              __borders[0] = 0;
-             for (int __i = 1; __i < (__num_threads + 1); ++__i)
+             for (_ThreadIndex __i = 1; __i < (__num_threads + 1); ++__i)
                {
                  __borders[__i] = __borderstart;
                  __borderstart += __chunk_length;
@@ -149,15 +152,17 @@ namespace __gnu_parallel
         if (__iam == 0)
           {
             *__result = *__begin;
-            __parallel_partial_sum_basecase(
-                __begin + 1, __begin + __borders[1], __result + 1,
-                __bin_op, *__begin);
+            __parallel_partial_sum_basecase(__begin + 1,
+                                           __begin + __borders[1],
+                                           __result + 1,
+                                           __bin_op, *__begin);
             ::new(&(__sums[__iam])) _ValueType(*(__result + __borders[1] - 1));
           }
         else
           {
             ::new(&(__sums[__iam]))
-              _ValueType(std::accumulate(__begin + __borders[__iam] + 1,
+              _ValueType(__gnu_parallel::accumulate(
+                                         __begin + __borders[__iam] + 1,
                                          __begin + __borders[__iam + 1],
                                          *(__begin + __borders[__iam]),
                                          __bin_op,
@@ -168,7 +173,7 @@ namespace __gnu_parallel
 
 #       pragma omp single
        __parallel_partial_sum_basecase(__sums + 1, __sums + __num_threads,
-                                          __sums + 1, __bin_op, __sums[0]);
+                                       __sums + 1, __bin_op, __sums[0]);
 
 #       pragma omp barrier
 
@@ -179,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;