-/* Copyright (C) 2005-2013 Free Software Foundation, Inc.
+/* Copyright (C) 2005-2024 Free Software Foundation, Inc.
Contributed by Richard Henderson <rth@redhat.com>.
- This file is part of the GNU OpenMP Library (libgomp).
+ This file is part of the GNU Offloading and Multi Processing Library
+ (libgomp).
Libgomp is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
if (specified == 1)
return 1;
- else if (thr->ts.active_level >= 1 && !icv->nest_var)
+
+ if (thr->ts.active_level >= 1
+ /* Accelerators with fixed thread counts require this to return 1 for
+ nested parallel regions. */
+#if !defined(__AMDGCN__) && !defined(__nvptx__)
+ && icv->max_active_levels_var <= 1
+#endif
+ )
return 1;
- else if (thr->ts.active_level >= gomp_max_active_levels_var)
+ else if (thr->ts.active_level >= icv->max_active_levels_var)
return 1;
/* If NUM_THREADS not specified, use nthreads_var. */
nested parallel, so there is just one thread in the
contention group as well, no need to handle it atomically. */
pool = thr->thread_pool;
- if (thr->ts.team == NULL)
+ if (thr->ts.team == NULL || pool == NULL)
{
num_threads = max_num_threads;
if (num_threads > icv->thread_limit_var)
GOMP_parallel_start (void (*fn) (void *), void *data, unsigned num_threads)
{
num_threads = gomp_resolve_num_threads (num_threads, 0);
- gomp_team_start (fn, data, num_threads, 0, gomp_new_team (num_threads));
+ gomp_team_start (fn, data, num_threads, 0, gomp_new_team (num_threads),
+ NULL);
}
void
ialias (GOMP_parallel_end)
void
-GOMP_parallel (void (*fn) (void *), void *data, unsigned num_threads, unsigned int flags)
+GOMP_parallel (void (*fn) (void *), void *data, unsigned num_threads,
+ unsigned int flags)
+{
+ num_threads = gomp_resolve_num_threads (num_threads, 0);
+ gomp_team_start (fn, data, num_threads, flags, gomp_new_team (num_threads),
+ NULL);
+ fn (data);
+ ialias_call (GOMP_parallel_end) ();
+}
+
+unsigned
+GOMP_parallel_reductions (void (*fn) (void *), void *data,
+ unsigned num_threads, unsigned int flags)
{
+ struct gomp_taskgroup *taskgroup;
num_threads = gomp_resolve_num_threads (num_threads, 0);
- gomp_team_start (fn, data, num_threads, flags, gomp_new_team (num_threads));
+ uintptr_t *rdata = *(uintptr_t **)data;
+ taskgroup = gomp_parallel_reduction_register (rdata, num_threads);
+ gomp_team_start (fn, data, num_threads, flags, gomp_new_team (num_threads),
+ taskgroup);
fn (data);
ialias_call (GOMP_parallel_end) ();
+ gomp_sem_destroy (&taskgroup->taskgroup_sem);
+ free (taskgroup);
+ return num_threads;
}
bool
}
else if (which & GOMP_CANCEL_TASKGROUP)
{
- if (thr->task->taskgroup && thr->task->taskgroup->cancelled)
- return true;
+ if (thr->task->taskgroup)
+ {
+ if (thr->task->taskgroup->cancelled)
+ return true;
+ if (thr->task->taskgroup->workshare
+ && thr->task->taskgroup->prev
+ && thr->task->taskgroup->prev->cancelled)
+ return true;
+ }
/* FALLTHRU into the GOMP_CANCEL_PARALLEL case,
as #pragma omp cancel parallel also cancels all explicit
tasks. */
}
else if (which & GOMP_CANCEL_TASKGROUP)
{
- if (thr->task->taskgroup && !thr->task->taskgroup->cancelled)
+ if (thr->task->taskgroup)
{
- gomp_mutex_lock (&team->task_lock);
- thr->task->taskgroup->cancelled = true;
- gomp_mutex_unlock (&team->task_lock);
+ struct gomp_taskgroup *taskgroup = thr->task->taskgroup;
+ if (taskgroup->workshare && taskgroup->prev)
+ taskgroup = taskgroup->prev;
+ if (!taskgroup->cancelled)
+ {
+ gomp_mutex_lock (&team->task_lock);
+ taskgroup->cancelled = true;
+ gomp_mutex_unlock (&team->task_lock);
+ }
}
return true;
}