Commit 59b567fb by Johannes Singler Committed by Johannes Singler

re PR libstdc++/33892 ([libstdc++ v3 parallel mode] Parallel mode algorithms use…

re PR libstdc++/33892 ([libstdc++ v3 parallel mode] Parallel mode algorithms use critical sections with global scope)

2007-11-02  Johannes Singler  <singler@ira.uka.de>

      PR libstdc++/33892

      * include/parallel/workstealing.h: Replaced pragma by function
        call lock.
      * include/parallel/search.h: Same
      * include/parallel/partition.h: Same
      * include/parallel/find.h: Same

From-SVN: r129852
parent f3a032e9
2007-11-02 Johannes Singler <singler@ira.uka.de>
* include/parallel/workstealing.h: Replaced pragma by function
call lock.
* include/parallel/search.h: Same
* include/parallel/partition.h: Same
* include/parallel/find.h: Same
2007-11-01 Janis Johnson <janis187@us.ibm.com> 2007-11-01 Janis Johnson <janis187@us.ibm.com>
PR testsuite/25352 PR testsuite/25352
......
...@@ -104,6 +104,8 @@ namespace __gnu_parallel ...@@ -104,6 +104,8 @@ namespace __gnu_parallel
difference_type result = length; difference_type result = length;
const thread_index_t num_threads = get_max_threads(); const thread_index_t num_threads = get_max_threads();
omp_lock_t result_lock;
omp_init_lock(&result_lock);
difference_type* borders = static_cast<difference_type*>(__builtin_alloca(sizeof(difference_type) * (num_threads + 1))); difference_type* borders = static_cast<difference_type*>(__builtin_alloca(sizeof(difference_type) * (num_threads + 1)));
...@@ -119,21 +121,24 @@ namespace __gnu_parallel ...@@ -119,21 +121,24 @@ namespace __gnu_parallel
for (; pos < limit; pos++) for (; pos < limit; pos++)
{ {
#pragma omp flush(result) #pragma omp flush(result)
// Result has been set to something lower. // Result has been set to something lower.
if (result < pos) if (result < pos)
break; break;
if (selector(i1, i2, pred)) if (selector(i1, i2, pred))
{ {
#pragma omp critical (result) omp_set_lock(&result_lock);
if (result > pos) if (result > pos)
result = pos; result = pos;
break; omp_unset_lock(&result_lock);
} break;
i1++; }
i2++; i1++;
} i2++;
}
} }
omp_destroy_lock(&result_lock);
return std::pair<RandomAccessIterator1, RandomAccessIterator2>(begin1 + result, begin2 + result); return std::pair<RandomAccessIterator1, RandomAccessIterator2>(begin1 + result, begin2 + result);
} }
...@@ -191,6 +196,9 @@ namespace __gnu_parallel ...@@ -191,6 +196,9 @@ namespace __gnu_parallel
difference_type result = length; difference_type result = length;
const thread_index_t num_threads = get_max_threads(); const thread_index_t num_threads = get_max_threads();
omp_lock_t result_lock;
omp_init_lock(&result_lock);
#pragma omp parallel shared(result) num_threads(num_threads) #pragma omp parallel shared(result) num_threads(num_threads)
{ {
// Not within first k elements -> start parallel. // Not within first k elements -> start parallel.
...@@ -217,7 +225,7 @@ namespace __gnu_parallel ...@@ -217,7 +225,7 @@ namespace __gnu_parallel
local_result = selector.sequential_algorithm(begin1 + start, begin1 + stop, begin2 + start, pred); local_result = selector.sequential_algorithm(begin1 + start, begin1 + stop, begin2 + start, pred);
if (local_result.first != (begin1 + stop)) if (local_result.first != (begin1 + stop))
{ {
#pragma omp critical(result) omp_set_lock(&result_lock);
if ((local_result.first - begin1) < result) if ((local_result.first - begin1) < result)
{ {
result = local_result.first - begin1; result = local_result.first - begin1;
...@@ -225,6 +233,7 @@ namespace __gnu_parallel ...@@ -225,6 +233,7 @@ namespace __gnu_parallel
// Result cannot be in future blocks, stop algorithm. // Result cannot be in future blocks, stop algorithm.
fetch_and_add<difference_type>(&next_block_pos, length); fetch_and_add<difference_type>(&next_block_pos, length);
} }
omp_unset_lock(&result_lock);
} }
block_size = std::min<difference_type>(block_size * Settings::find_increasing_factor, Settings::find_maximum_block_size); block_size = std::min<difference_type>(block_size * Settings::find_increasing_factor, Settings::find_maximum_block_size);
...@@ -235,6 +244,8 @@ namespace __gnu_parallel ...@@ -235,6 +244,8 @@ namespace __gnu_parallel
} }
} }
omp_destroy_lock(&result_lock);
// Return iterator on found element. // Return iterator on found element.
return std::pair<RandomAccessIterator1, RandomAccessIterator2>(begin1 + result, begin2 + result); return std::pair<RandomAccessIterator1, RandomAccessIterator2>(begin1 + result, begin2 + result);
} }
...@@ -286,6 +297,9 @@ namespace __gnu_parallel ...@@ -286,6 +297,9 @@ namespace __gnu_parallel
difference_type result = length; difference_type result = length;
const thread_index_t num_threads = get_max_threads(); const thread_index_t num_threads = get_max_threads();
omp_lock_t result_lock;
omp_init_lock(&result_lock);
// Not within first sequential_search_size elements -> start parallel. // Not within first sequential_search_size elements -> start parallel.
#pragma omp parallel shared(result) num_threads(num_threads) #pragma omp parallel shared(result) num_threads(num_threads)
{ {
...@@ -314,10 +328,10 @@ namespace __gnu_parallel ...@@ -314,10 +328,10 @@ namespace __gnu_parallel
local_result = selector.sequential_algorithm(begin1 + start, begin1 + stop, begin2 + start, pred); local_result = selector.sequential_algorithm(begin1 + start, begin1 + stop, begin2 + start, pred);
if (local_result.first != (begin1 + stop)) if (local_result.first != (begin1 + stop))
{ {
#pragma omp critical(result) omp_set_lock(&result_lock);
if ((local_result.first - begin1) < result) if ((local_result.first - begin1) < result)
result = local_result.first - begin1; result = local_result.first - begin1;
omp_unset_lock(&result_lock);
// Will not find better value in its interval. // Will not find better value in its interval.
break; break;
} }
...@@ -330,6 +344,8 @@ namespace __gnu_parallel ...@@ -330,6 +344,8 @@ namespace __gnu_parallel
} }
} }
omp_destroy_lock(&result_lock);
// Return iterator on found element. // Return iterator on found element.
return std::pair<RandomAccessIterator1, RandomAccessIterator2>(begin1 + result, begin2 + result); return std::pair<RandomAccessIterator1, RandomAccessIterator2>(begin1 + result, begin2 + result);
} }
......
...@@ -84,6 +84,9 @@ namespace __gnu_parallel ...@@ -84,6 +84,9 @@ namespace __gnu_parallel
else else
chunk_size = Settings::partition_chunk_size; chunk_size = Settings::partition_chunk_size;
omp_lock_t result_lock;
omp_init_lock(&result_lock);
// At least good for two processors. // At least good for two processors.
while (right - left + 1 >= 2 * max_num_threads * chunk_size) while (right - left + 1 >= 2 * max_num_threads * chunk_size)
{ {
...@@ -113,8 +116,8 @@ namespace __gnu_parallel ...@@ -113,8 +116,8 @@ namespace __gnu_parallel
while (!iam_finished) while (!iam_finished)
{ {
if (thread_left > thread_left_border) if (thread_left > thread_left_border)
#pragma omp critical
{ {
omp_set_lock(&result_lock);
if (left + (chunk_size - 1) > right) if (left + (chunk_size - 1) > right)
iam_finished = true; iam_finished = true;
else else
...@@ -123,11 +126,12 @@ namespace __gnu_parallel ...@@ -123,11 +126,12 @@ namespace __gnu_parallel
thread_left_border = left + (chunk_size - 1); thread_left_border = left + (chunk_size - 1);
left += chunk_size; left += chunk_size;
} }
omp_unset_lock(&result_lock);
} }
if (thread_right < thread_right_border) if (thread_right < thread_right_border)
#pragma omp critical
{ {
omp_set_lock(&result_lock);
if (left > right - (chunk_size - 1)) if (left > right - (chunk_size - 1))
iam_finished = true; iam_finished = true;
else else
...@@ -136,6 +140,7 @@ namespace __gnu_parallel ...@@ -136,6 +140,7 @@ namespace __gnu_parallel
thread_right_border = right - (chunk_size - 1); thread_right_border = right - (chunk_size - 1);
right -= chunk_size; right -= chunk_size;
} }
omp_unset_lock(&result_lock);
} }
if (iam_finished) if (iam_finished)
...@@ -199,16 +204,15 @@ namespace __gnu_parallel ...@@ -199,16 +204,15 @@ namespace __gnu_parallel
{ {
// Find spot and swap. // Find spot and swap.
difference_type swapstart = -1; difference_type swapstart = -1;
#pragma omp critical omp_set_lock(&result_lock);
{ for (int r = 0; r < leftover_left; r++)
for (int r = 0; r < leftover_left; r++) if (!reserved_left[r])
if (!reserved_left[r]) {
{ reserved_left[r] = true;
reserved_left[r] = true; swapstart = left - (r + 1) * chunk_size;
swapstart = left - (r + 1) * chunk_size; break;
break; }
} omp_unset_lock(&result_lock);
}
#if _GLIBCXX_ASSERTIONS #if _GLIBCXX_ASSERTIONS
_GLIBCXX_PARALLEL_ASSERT(swapstart != -1); _GLIBCXX_PARALLEL_ASSERT(swapstart != -1);
...@@ -222,16 +226,15 @@ namespace __gnu_parallel ...@@ -222,16 +226,15 @@ namespace __gnu_parallel
{ {
// Find spot and swap // Find spot and swap
difference_type swapstart = -1; difference_type swapstart = -1;
#pragma omp critical omp_set_lock(&result_lock);
{ for (int r = 0; r < leftover_right; r++)
for (int r = 0; r < leftover_right; r++)
if (!reserved_right[r]) if (!reserved_right[r])
{ {
reserved_right[r] = true; reserved_right[r] = true;
swapstart = right + r * chunk_size + 1; swapstart = right + r * chunk_size + 1;
break; break;
} }
} omp_unset_lock(&result_lock);
#if _GLIBCXX_ASSERTIONS #if _GLIBCXX_ASSERTIONS
_GLIBCXX_PARALLEL_ASSERT(swapstart != -1); _GLIBCXX_PARALLEL_ASSERT(swapstart != -1);
...@@ -283,6 +286,8 @@ namespace __gnu_parallel ...@@ -283,6 +286,8 @@ namespace __gnu_parallel
delete[] reserved_left; delete[] reserved_left;
delete[] reserved_right; delete[] reserved_right;
omp_destroy_lock(&result_lock);
// Element "between" final_left and final_right might not have // Element "between" final_left and final_right might not have
// been regarded yet // been regarded yet
if (final_left < n && !pred(begin[final_left])) if (final_left < n && !pred(begin[final_left]))
......
...@@ -102,7 +102,7 @@ namespace __gnu_parallel ...@@ -102,7 +102,7 @@ namespace __gnu_parallel
difference_type input_length = (end1 - begin1) - pattern_length; difference_type input_length = (end1 - begin1) - pattern_length;
// Where is first occurrence of pattern? defaults to end. // Where is first occurrence of pattern? defaults to end.
difference_type res = (end1 - begin1); difference_type result = (end1 - begin1);
// Pattern too long. // Pattern too long.
if (input_length < 0) if (input_length < 0)
...@@ -110,6 +110,9 @@ namespace __gnu_parallel ...@@ -110,6 +110,9 @@ namespace __gnu_parallel
thread_index_t num_threads = std::max<difference_type>(1, std::min<difference_type>(input_length, __gnu_parallel::get_max_threads())); thread_index_t num_threads = std::max<difference_type>(1, std::min<difference_type>(input_length, __gnu_parallel::get_max_threads()));
omp_lock_t result_lock;
omp_init_lock(&result_lock);
difference_type borders[num_threads + 1]; difference_type borders[num_threads + 1];
__gnu_parallel::equally_split(input_length, num_threads, borders); __gnu_parallel::equally_split(input_length, num_threads, borders);
...@@ -127,19 +130,21 @@ namespace __gnu_parallel ...@@ -127,19 +130,21 @@ namespace __gnu_parallel
while (start <= stop && !found_pattern) while (start <= stop && !found_pattern)
{ {
// Get new value of res. // Get new value of result.
#pragma omp flush(res) #pragma omp flush(result)
// No chance for this thread to find first occurrence. // No chance for this thread to find first occurrence.
if (res < start) if (result < start)
break; break;
while (pred(begin1[start + pos_in_pattern], begin2[pos_in_pattern])) while (pred(begin1[start + pos_in_pattern], begin2[pos_in_pattern]))
{ {
++pos_in_pattern; ++pos_in_pattern;
if (pos_in_pattern == pattern_length) if (pos_in_pattern == pattern_length)
{ {
// Found new candidate for res. // Found new candidate for result.
#pragma omp critical (res) omp_set_lock(&result_lock);
res = std::min(res, start); result = std::min(result, start);
omp_unset_lock(&result_lock);
found_pattern = true; found_pattern = true;
break; break;
} }
...@@ -150,8 +155,10 @@ namespace __gnu_parallel ...@@ -150,8 +155,10 @@ namespace __gnu_parallel
} }
} }
omp_destroy_lock(&result_lock);
// Return iterator on found element. // Return iterator on found element.
return (begin1 + res); return (begin1 + result);
} }
} // end namespace } // end namespace
......
...@@ -123,6 +123,9 @@ namespace __gnu_parallel ...@@ -123,6 +123,9 @@ namespace __gnu_parallel
thread_index_t num_threads = get_max_threads(); thread_index_t num_threads = get_max_threads();
difference_type num_threads_min = num_threads < end - begin ? num_threads : end - begin; difference_type num_threads_min = num_threads < end - begin ? num_threads : end - begin;
omp_lock_t output_lock;
omp_init_lock(&output_lock);
// No more threads than jobs, at least one thread. // No more threads than jobs, at least one thread.
difference_type num_threads_max = num_threads_min > 1 ? num_threads_min : 1; difference_type num_threads_max = num_threads_min > 1 ? num_threads_min : 1;
num_threads = static_cast<thread_index_t>(num_threads_max); num_threads = static_cast<thread_index_t>(num_threads_max);
...@@ -276,9 +279,10 @@ namespace __gnu_parallel ...@@ -276,9 +279,10 @@ namespace __gnu_parallel
} }
#pragma omp flush(busy) #pragma omp flush(busy)
} // end while busy > 0 } // end while busy > 0
#pragma omp critical(writeOutput)
// Add accumulated result to output. // Add accumulated result to output.
omp_set_lock(&output_lock);
output = r(output, result); output = r(output, result);
omp_unset_lock(&output_lock);
//omp_destroy_lock(&(my_job.lock)); //omp_destroy_lock(&(my_job.lock));
} }
...@@ -289,6 +293,8 @@ namespace __gnu_parallel ...@@ -289,6 +293,8 @@ namespace __gnu_parallel
// some algorithms like transform) // some algorithms like transform)
f.finish_iterator = begin + length; f.finish_iterator = begin + length;
omp_destroy_lock(&output_lock);
return op; return op;
} }
} // end namespace } // end namespace
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment