]> git.ipfire.org Git - thirdparty/gcc.git/blobdiff - libgomp/sections.c
[Ada] Improved support for aspect alignment in CCG
[thirdparty/gcc.git] / libgomp / sections.c
index 369f7a4426fd768bb570c487a8581077411ae51c..99001db7d50cd6e9c6a7071984219d1f8fdd80b8 100644 (file)
@@ -1,7 +1,8 @@
-/* Copyright (C) 2005-2013 Free Software Foundation, Inc.
+/* Copyright (C) 2005-2020 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
 /* This file handles the SECTIONS construct.  */
 
 #include "libgomp.h"
+#include <string.h>
 
 
+ialias_redirect (GOMP_taskgroup_reduction_register)
+
 /* Initialize the given work share construct from the given arguments.  */
 
 static inline void
@@ -71,11 +75,85 @@ GOMP_sections_start (unsigned count)
   struct gomp_thread *thr = gomp_thread ();
   long s, e, ret;
 
-  if (gomp_work_share_start (false))
+  if (gomp_work_share_start (0))
+    {
+      gomp_sections_init (thr->ts.work_share, count);
+      gomp_work_share_init_done ();
+    }
+
+#ifdef HAVE_SYNC_BUILTINS
+  if (gomp_iter_dynamic_next (&s, &e))
+    ret = s;
+  else
+    ret = 0;
+#else
+  gomp_mutex_lock (&thr->ts.work_share->lock);
+  if (gomp_iter_dynamic_next_locked (&s, &e))
+    ret = s;
+  else
+    ret = 0;
+  gomp_mutex_unlock (&thr->ts.work_share->lock);
+#endif
+
+  return ret;
+}
+
+unsigned
+GOMP_sections2_start (unsigned count, uintptr_t *reductions, void **mem)
+{
+  struct gomp_thread *thr = gomp_thread ();
+  long s, e, ret;
+
+  if (reductions)
+    gomp_workshare_taskgroup_start ();
+  if (gomp_work_share_start (0))
     {
       gomp_sections_init (thr->ts.work_share, count);
+      if (reductions)
+       {
+         GOMP_taskgroup_reduction_register (reductions);
+         thr->task->taskgroup->workshare = true;
+         thr->ts.work_share->task_reductions = reductions;
+       }
+      if (mem)
+       {
+         uintptr_t size = (uintptr_t) *mem;
+#define INLINE_ORDERED_TEAM_IDS_OFF \
+  ((offsetof (struct gomp_work_share, inline_ordered_team_ids)         \
+    + __alignof__ (long long) - 1) & ~(__alignof__ (long long) - 1))
+         if (size > (sizeof (struct gomp_work_share)
+                     - INLINE_ORDERED_TEAM_IDS_OFF))
+           *mem
+             = (void *) (thr->ts.work_share->ordered_team_ids
+                         = gomp_malloc_cleared (size));
+         else
+           *mem = memset (((char *) thr->ts.work_share)
+                          + INLINE_ORDERED_TEAM_IDS_OFF, '\0', size);
+       }
       gomp_work_share_init_done ();
     }
+  else
+    {
+      if (reductions)
+       {
+         uintptr_t *first_reductions = thr->ts.work_share->task_reductions;
+         gomp_workshare_task_reduction_register (reductions,
+                                                 first_reductions);
+       }
+      if (mem)
+       {
+         if ((offsetof (struct gomp_work_share, inline_ordered_team_ids)
+              & (__alignof__ (long long) - 1)) == 0)
+           *mem = (void *) thr->ts.work_share->ordered_team_ids;
+         else
+           {
+             uintptr_t p = (uintptr_t) thr->ts.work_share->ordered_team_ids;
+             p += __alignof__ (long long) - 1;
+             p &= ~(__alignof__ (long long) - 1);
+             *mem = (void *) p;
+           }
+       }
+    }
 
 #ifdef HAVE_SYNC_BUILTINS
   if (gomp_iter_dynamic_next (&s, &e))
@@ -139,11 +217,27 @@ GOMP_parallel_sections_start (void (*fn) (void *), void *data,
   num_threads = gomp_resolve_num_threads (num_threads, count);
   team = gomp_new_team (num_threads);
   gomp_sections_init (&team->work_shares[0], count);
-  gomp_team_start (fn, data, num_threads, team);
+  gomp_team_start (fn, data, num_threads, 0, team, NULL);
+}
+
+ialias_redirect (GOMP_parallel_end)
+
+void
+GOMP_parallel_sections (void (*fn) (void *), void *data,
+                       unsigned num_threads, unsigned count, unsigned flags)
+{
+  struct gomp_team *team;
+
+  num_threads = gomp_resolve_num_threads (num_threads, count);
+  team = gomp_new_team (num_threads);
+  gomp_sections_init (&team->work_shares[0], count);
+  gomp_team_start (fn, data, num_threads, flags, team, NULL);
+  fn (data);
+  GOMP_parallel_end ();
 }
 
 /* The GOMP_section_end* routines are called after the thread is told
-   that all sections are complete.  This first version synchronizes
+   that all sections are complete.  The first two versions synchronize
    all threads; the nowait version does not.  */
 
 void
@@ -152,6 +246,12 @@ GOMP_sections_end (void)
   gomp_work_share_end ();
 }
 
+bool
+GOMP_sections_end_cancel (void)
+{
+  return gomp_work_share_end_cancel ();
+}
+
 void
 GOMP_sections_end_nowait (void)
 {