openmp: Notify team barrier of pending tasks in omp_fulfill_event

The team barrier should be notified of any new tasks that become runnable
as the result of a completing task, otherwise the barrier threads might
not resume processing available tasks, resulting in a hang.

2021-05-17  Kwok Cheung Yeung  <kcy@codesourcery.com>

	libgomp/
	* task.c (omp_fulfill_event): Call gomp_team_barrier_set_task_pending
	if new tasks generated.
	* testsuite/libgomp.c-c++-common/task-detach-13.c: New.
This commit is contained in:
Kwok Cheung Yeung 2021-05-14 09:59:11 -07:00
parent 5d93261bc0
commit ba886d0c48
2 changed files with 60 additions and 0 deletions

View File

@ -2460,6 +2460,7 @@ omp_fulfill_event (omp_event_handle_t event)
if (new_tasks > 0)
{
/* Wake up threads to run new tasks. */
gomp_team_barrier_set_task_pending (&team->barrier);
do_wake = team->nthreads - team->task_running_count;
if (do_wake > new_tasks)
do_wake = new_tasks;

View File

@ -0,0 +1,59 @@
/* { dg-do run { target *-*-linux* *-*-gnu* *-*-freebsd* } } */
/* { dg-timeout 10 } */
/* Test that omp_fulfill_event works when called from an external
non-OpenMP thread. */
#include <omp.h>
#include <unistd.h>
#include <pthread.h>
#include <stdio.h>
int finished = 0;
int event_pending = 0;
omp_event_handle_t detach_event;
void *
fulfill_thread (void *)
{
while (!__atomic_load_n (&finished, __ATOMIC_RELAXED))
{
if (__atomic_load_n (&event_pending, __ATOMIC_ACQUIRE))
{
omp_fulfill_event (detach_event);
__atomic_store_n (&event_pending, 0, __ATOMIC_RELEASE);
}
sleep(1);
}
return 0;
}
int
main (void)
{
pthread_t thr;
int dep;
pthread_create (&thr, NULL, fulfill_thread, 0);
#pragma omp parallel
#pragma omp single
{
omp_event_handle_t ev;
#pragma omp task depend (out: dep) detach (ev)
{
detach_event = ev;
__atomic_store_n (&event_pending, 1, __ATOMIC_RELEASE);
}
#pragma omp task depend (in: dep)
{
__atomic_store_n (&finished, 1, __ATOMIC_RELAXED);
}
}
pthread_join (thr, 0);
return 0;
}