
When a nested parallel region ends, the runtime calls __kmp_join_call(). During this call, the primary thread of the nested parallel region will reset its tid (retval of omp_get_thread_num()) to what it was in the outer parallel region. A data race occurs with the current code when another worker thread from the nested inner parallel region tries to steal tasks from the primary thread's task deque. The worker thread reads the tid value directly from the primary thread's data structure and may read the wrong value. This change just uses the calculated victim_tid from execute_tasks() directly in the steal_task() routine rather than reading tid from the data structure. Fixes: #87307
44 lines
730 B
C
44 lines
730 B
C
// RUN: %libomp-compile-and-run
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <omp.h>
|
|
|
|
int a;
|
|
|
|
void inc_a() {
|
|
#pragma omp task
|
|
{
|
|
#pragma omp atomic
|
|
a++;
|
|
}
|
|
}
|
|
|
|
int main() {
|
|
int n;
|
|
int nth_outer;
|
|
omp_set_max_active_levels(2);
|
|
omp_set_dynamic(0);
|
|
|
|
for (n = 0; n < 200; ++n) {
|
|
a = 0;
|
|
#pragma omp parallel num_threads(8)
|
|
{
|
|
if (omp_get_thread_num() == 0)
|
|
nth_outer = omp_get_num_threads();
|
|
#pragma omp parallel num_threads(2)
|
|
{
|
|
int i;
|
|
#pragma omp master
|
|
for (i = 0; i < 50; ++i)
|
|
inc_a();
|
|
}
|
|
}
|
|
if (a != nth_outer * 50) {
|
|
fprintf(stderr, "error: a (%d) != %d\n", a, nth_outer * 50);
|
|
return EXIT_FAILURE;
|
|
}
|
|
}
|
|
|
|
return EXIT_SUCCESS;
|
|
}
|