]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
libgomp.map (OMP_5.0): Export omp_pause_resource{,_all}{,_}.
authorJakub Jelinek <jakub@redhat.com>
Fri, 27 Jul 2018 12:55:28 +0000 (14:55 +0200)
committerJakub Jelinek <jakub@gcc.gnu.org>
Fri, 27 Jul 2018 12:55:28 +0000 (14:55 +0200)
* libgomp.map (OMP_5.0): Export omp_pause_resource{,_all}{,_}.
* omp.h.in (omp_pause_resource_t): New typedef.
(omp_pause_resource, omp_pause_resource_all): New prototypes.
* omp_lib.f90.in (omp_pause_resource_kind, omp_pause_soft,
omp_pause_hard): New parameters.
(omp_pause_resource, omp_pause_resource_all): New interfaces.
* omp_lib.h.in (omp_pause_resource_kind, omp_pause_soft,
omp_pause_hard): New parameters.
(omp_pause_resource, omp_pause_resource_all): New externals.
* libgomp.h (gomp_pause_host): New prototype.
* team.c (gomp_thread_attr): Remove comment.
(gomp_thread_start): Call pthread_detach.
(gomp_free_pool_helper): Likewise.
(gomp_team_start): Don't call pthread_attr_setdetachstate.
(gomp_pause_pool_helper, gomp_pause_host): New functions.
* target.c (omp_pause_resource, omp_pause_resource_all): New functions.
* env.c (initialize_env): Don't call pthread_attr_setdetachstate.
* fortran.c (omp_pause_resource, omp_pause_resource_all): Add
ialias_redirect.
(omp_pause_resource_, omp_pause_resource_all_): New functions.
* config/nvptx/team.c (gomp_pause_host): New function.
* config/nvptx/target.c (omp_pause_resource, omp_pause_resource_all):
New functions.
* testsuite/libgomp.c-c++-common/pause-1.c: New test.
* testsuite/libgomp.c-c++-common/pause-2.c: New test.

From-SVN: r263029

14 files changed:
libgomp/ChangeLog.gomp
libgomp/config/nvptx/target.c
libgomp/config/nvptx/team.c
libgomp/env.c
libgomp/fortran.c
libgomp/libgomp.h
libgomp/libgomp.map
libgomp/omp.h.in
libgomp/omp_lib.f90.in
libgomp/omp_lib.h.in
libgomp/target.c
libgomp/team.c
libgomp/testsuite/libgomp.c-c++-common/pause-1.c [new file with mode: 0644]
libgomp/testsuite/libgomp.c-c++-common/pause-2.c [new file with mode: 0644]

index 11276b1be27c50eaeab7be696b5d78190d9659b5..4c04a388e0523d0aa3b52b65dbb2389ac3d2f370 100644 (file)
@@ -1,3 +1,31 @@
+2018-07-27  Jakub Jelinek  <jakub@redhat.com>
+
+       * libgomp.map (OMP_5.0): Export omp_pause_resource{,_all}{,_}.
+       * omp.h.in (omp_pause_resource_t): New typedef.
+       (omp_pause_resource, omp_pause_resource_all): New prototypes.
+       * omp_lib.f90.in (omp_pause_resource_kind, omp_pause_soft,
+       omp_pause_hard): New parameters.
+       (omp_pause_resource, omp_pause_resource_all): New interfaces.
+       * omp_lib.h.in (omp_pause_resource_kind, omp_pause_soft,
+       omp_pause_hard): New parameters.
+       (omp_pause_resource, omp_pause_resource_all): New externals.
+       * libgomp.h (gomp_pause_host): New prototype.
+       * team.c (gomp_thread_attr): Remove comment.
+       (gomp_thread_start): Call pthread_detach.
+       (gomp_free_pool_helper): Likewise.
+       (gomp_team_start): Don't call pthread_attr_setdetachstate.
+       (gomp_pause_pool_helper, gomp_pause_host): New functions.
+       * target.c (omp_pause_resource, omp_pause_resource_all): New functions.
+       * env.c (initialize_env): Don't call pthread_attr_setdetachstate.
+       * fortran.c (omp_pause_resource, omp_pause_resource_all): Add
+       ialias_redirect.
+       (omp_pause_resource_, omp_pause_resource_all_): New functions.
+       * config/nvptx/team.c (gomp_pause_host): New function.
+       * config/nvptx/target.c (omp_pause_resource, omp_pause_resource_all):
+       New functions.
+       * testsuite/libgomp.c-c++-common/pause-1.c: New test.
+       * testsuite/libgomp.c-c++-common/pause-2.c: New test.
+
 2018-07-25  Jakub Jelinek  <jakub@redhat.com>
 
        * Makefile.am (libgomp_la_SOURCES): Add teams.c.
index 64004acb422f7874c2d25de9c26abfb25030bc1d..3878227a27fa79443a9d0cf73c6569d18c9f7801 100644 (file)
@@ -47,3 +47,21 @@ GOMP_teams (unsigned int num_teams, unsigned int thread_limit)
     }
   gomp_num_teams_var = num_teams - 1;
 }
+
+int
+omp_pause_resource (omp_pause_resource_t kind, int device_num)
+{
+  (void) kind;
+  (void) device_num;
+  return -1;
+}
+
+int
+omp_pause_resource_all (omp_pause_resource_t kind)
+{
+  (void) kind;
+  return -1;
+}
+
+ialias (omp_pause_resource)
+ialias (omp_pause_resource_all)
index 34059d389f2e2d2b7c430775552e0daf7828babc..25859fbc6767275ddcf054122cf6b1289ac3d9fd 100644 (file)
@@ -174,5 +174,11 @@ gomp_team_start (void (*fn) (void *), void *data, unsigned nthreads,
   gomp_simple_barrier_wait (&pool->threads_dock);
 }
 
+int
+gomp_pause_host (void)
+{
+  return -1;
+}
+
 #include "../../team.c"
 #endif
index 9f884a8ecd91275274f0d213fc97088650894a4c..d37225d41c0e5ecb42c9afeb1d3628e2a12c037f 100644 (file)
@@ -1348,7 +1348,6 @@ initialize_env (void)
 
   /* Not strictly environment related, but ordering constructors is tricky.  */
   pthread_attr_init (&gomp_thread_attr);
-  pthread_attr_setdetachstate (&gomp_thread_attr, PTHREAD_CREATE_DETACHED);
 
   if (parse_stacksize ("OMP_STACKSIZE", &stacksize)
       || parse_stacksize ("GOMP_STACKSIZE", &stacksize)
index df2b108968ab13cd50a7209a4ef6def19e856c93..5c2cb03662d8c40f78ce19f3bcff60908a2b609b 100644 (file)
@@ -84,6 +84,8 @@ ialias_redirect (omp_get_team_num)
 ialias_redirect (omp_is_initial_device)
 ialias_redirect (omp_get_initial_device)
 ialias_redirect (omp_get_max_task_priority)
+ialias_redirect (omp_pause_resource)
+ialias_redirect (omp_pause_resource_all)
 #endif
 
 #ifndef LIBGOMP_GNU_SYMBOL_VERSIONING
@@ -659,3 +661,15 @@ omp_capture_affinity_ (char *buffer, const char *format,
     memset (buffer + ret, ' ', buffer_len - ret);
   return ret;
 }
+
+int32_t
+omp_pause_resource_ (const int32_t *kind, const int32_t *device_num)
+{
+  return omp_pause_resource (*kind, *device_num);
+}
+
+int32_t
+omp_pause_resource_all_ (const int32_t *kind)
+{
+  return omp_pause_resource_all (*kind);
+}
index b0fb6aa4b01092cb5efac4822218c1160307387b..7453d6292c81239179c2d54d2ef0bd2c210ba39e 100644 (file)
@@ -821,6 +821,7 @@ extern void gomp_team_start (void (*) (void *), void *, unsigned,
                             unsigned, struct gomp_team *);
 extern void gomp_team_end (void);
 extern void gomp_free_thread (void *);
+extern int gomp_pause_host (void);
 
 /* target.c */
 
index 69faa7fa0310b62604df36b25712cba051ce35ee..c8f08e7bf4bb700372047f736aa4f4762ac1c9b2 100644 (file)
@@ -174,6 +174,10 @@ OMP_5.0 {
        omp_get_affinity_format_;
        omp_set_affinity_format;
        omp_set_affinity_format_;
+       omp_pause_resource;
+       omp_pause_resource_;
+       omp_pause_resource_all;
+       omp_pause_resource_all_;
 } OMP_4.5;
 
 GOMP_1.0 {
index 3d350dd089b09b003aeaa80f7e603fbd1d2103e8..a9fbd9ec1ce52c3addb6db43c9c2be98e21a81e2 100644 (file)
@@ -83,6 +83,12 @@ typedef struct __attribute__((__aligned__ (sizeof (void *)))) omp_depend_t
   char __omp_depend_t__[2 * sizeof (void *)];
 } omp_depend_t;
 
+typedef enum omp_pause_resource_t
+{
+  omp_pause_soft = 1,
+  omp_pause_hard = 2
+} omp_pause_resource_t;
+
 #ifdef __cplusplus
 extern "C" {
 # define __GOMP_NOTHROW throw ()
@@ -178,6 +184,9 @@ extern void omp_display_affinity (const char *) __GOMP_NOTHROW;
 extern __SIZE_TYPE__ omp_capture_affinity (char *, __SIZE_TYPE__, const char *)
   __GOMP_NOTHROW;
 
+extern int omp_pause_resource (omp_pause_resource_t, int) __GOMP_NOTHROW;
+extern int omp_pause_resource_all (omp_pause_resource_t) __GOMP_NOTHROW;
+
 #ifdef __cplusplus
 }
 #endif
index 8613d17bad6959d376c0d12891bf00c37d285f93..caecfba749dd76a69aaf6824c4bd8daf41b18e8e 100644 (file)
@@ -30,6 +30,7 @@
         integer, parameter :: omp_sched_kind = 4
         integer, parameter :: omp_proc_bind_kind = 4
         integer, parameter :: omp_lock_hint_kind = 4
+        integer, parameter :: omp_pause_resource_kind = 4
         integer (omp_sched_kind), parameter :: omp_sched_static = 1
         integer (omp_sched_kind), parameter :: omp_sched_dynamic = 2
         integer (omp_sched_kind), parameter :: omp_sched_guided = 3
                  parameter :: omp_lock_hint_nonspeculative = 4
         integer (omp_lock_hint_kind), &
                  parameter :: omp_lock_hint_speculative = 8
+        integer (kind=omp_pause_resource_kind), &
+                 parameter :: omp_pause_soft = 1
+        integer (kind=omp_pause_resource_kind), &
+                 parameter :: omp_pause_hard = 2
       end module
 
       module omp_lib
           end function omp_capture_affinity
         end interface
 
+        interface
+          function omp_pause_resource (kind, device_num)
+            use omp_lib_kinds
+            integer (4) :: omp_pause_resource
+            integer (kind=omp_pause_resource_kind), &
+              intent(in) :: kind
+            integer (4) :: device_num
+          end function
+        end interface
+
+        interface
+          function omp_pause_resource_all (kind)
+            use omp_lib_kinds
+            integer (4) :: omp_pause_resource_all
+            integer (kind=omp_pause_resource_kind), &
+              intent(in) :: kind
+          end function
+        end interface
+
       end module omp_lib
index 130fb034eb0cdb5a1d269a4be9bd9dbe27e514d2..2a553435a451580866a4f8f3e0875663c948c0a2 100644 (file)
       parameter (omp_lock_hint_nonspeculative = 4)
       parameter (omp_lock_hint_speculative = 8)
       parameter (openmp_version = 201511)
+      integer omp_pause_resource_kind
+      parameter (omp_pause_resource_kind = 4)
+      integer (omp_pause_resource_kind) omp_pause_soft
+      integer (omp_pause_resource_kind) omp_pause_hard
+      parameter (omp_pause_soft = 1)
+      parameter (omp_pause_hard = 2)
 
       external omp_init_lock, omp_init_nest_lock
       external omp_init_lock_with_hint
       external omp_display_affinity, omp_capture_affinity
       integer(4) omp_get_affinity_format
       integer(4) omp_capture_affinity
+
+      external omp_pause_resource, omp_pause_resource_all
+      integer(4) omp_pause_resource
+      integer(4) omp_pause_resource_all
index 3713132cf2fd82f96bd0da212835b5e048295d23..d9288274243da97dcb8007604fbe7185f38a8b5c 100644 (file)
@@ -2503,6 +2503,31 @@ omp_target_disassociate_ptr (const void *ptr, int device_num)
   return ret;
 }
 
+int
+omp_pause_resource (omp_pause_resource_t kind, int device_num)
+{
+  (void) kind;
+  if (device_num == GOMP_DEVICE_HOST_FALLBACK)
+    return gomp_pause_host ();
+  if (device_num < 0 || device_num >= gomp_get_num_devices ())
+    return -1;
+  /* Do nothing for target devices for now.  */
+  return 0;
+}
+
+int
+omp_pause_resource_all (omp_pause_resource_t kind)
+{
+  (void) kind;
+  if (gomp_pause_host ())
+    return -1;
+  /* Do nothing for target devices for now.  */
+  return 0;
+}
+
+ialias (omp_pause_resource)
+ialias (omp_pause_resource_all)
+
 #ifdef PLUGIN_SUPPORT
 
 /* This function tries to load a plugin for DEVICE.  Name of plugin is passed
index d81674870a384ee5b9a1f5258f1621f39159e7b4..c73a349b56f9965f739c50e0fc46b8e679c150d5 100644 (file)
@@ -32,7 +32,6 @@
 #include <string.h>
 
 #ifdef LIBGOMP_USE_PTHREADS
-/* This attribute contains PTHREAD_CREATE_DETACHED.  */
 pthread_attr_t gomp_thread_attr;
 
 /* This key is for the thread destructor.  */
@@ -135,6 +134,7 @@ gomp_thread_start (void *xdata)
     }
 
   gomp_sem_destroy (&thr->release);
+  pthread_detach (pthread_self ());
   thr->thread_pool = NULL;
   thr->task = NULL;
   return NULL;
@@ -235,6 +235,7 @@ gomp_free_pool_helper (void *thread_pool)
   thr->thread_pool = NULL;
   thr->task = NULL;
 #ifdef LIBGOMP_USE_PTHREADS
+  pthread_detach (pthread_self ());
   pthread_exit (NULL);
 #elif defined(__nvptx__)
   asm ("exit;");
@@ -726,7 +727,6 @@ gomp_team_start (void (*fn) (void *), void *data, unsigned nthreads,
     {
       size_t stacksize;
       pthread_attr_init (&thread_attr);
-      pthread_attr_setdetachstate (&thread_attr, PTHREAD_CREATE_DETACHED);
       if (! pthread_attr_getstacksize (&gomp_thread_attr, &stacksize))
        pthread_attr_setstacksize (&thread_attr, stacksize);
       attr = &thread_attr;
@@ -1010,6 +1010,76 @@ team_destructor (void)
      crashes.  */
   pthread_key_delete (gomp_thread_destructor);
 }
+
+/* Similar to gomp_free_pool_helper, but don't detach itself,
+   gomp_pause_host will pthread_join those threads.  */
+
+static void
+gomp_pause_pool_helper (void *thread_pool)
+{
+  struct gomp_thread *thr = gomp_thread ();
+  struct gomp_thread_pool *pool
+    = (struct gomp_thread_pool *) thread_pool;
+  gomp_simple_barrier_wait_last (&pool->threads_dock);
+  gomp_sem_destroy (&thr->release);
+  thr->thread_pool = NULL;
+  thr->task = NULL;
+  pthread_exit (NULL);
+}
+
+/* Free a thread pool and release its threads.  Return non-zero on
+   failure.  */
+
+int
+gomp_pause_host (void)
+{
+  struct gomp_thread *thr = gomp_thread ();
+  struct gomp_thread_pool *pool = thr->thread_pool;
+  if (thr->ts.level)
+    return -1;
+  if (pool)
+    {
+      if (pool->threads_used > 0)
+       {
+         int i;
+         pthread_t *thrs
+           = gomp_alloca (sizeof (pthread_t) * pool->threads_used);
+         for (i = 1; i < pool->threads_used; i++)
+           {
+             struct gomp_thread *nthr = pool->threads[i];
+             nthr->fn = gomp_pause_pool_helper;
+             nthr->data = pool;
+             thrs[i] = gomp_thread_to_pthread_t (nthr);
+           }
+         /* This barrier undocks threads docked on pool->threads_dock.  */
+         gomp_simple_barrier_wait (&pool->threads_dock);
+         /* And this waits till all threads have called gomp_barrier_wait_last
+            in gomp_pause_pool_helper.  */
+         gomp_simple_barrier_wait (&pool->threads_dock);
+         /* Now it is safe to destroy the barrier and free the pool.  */
+         gomp_simple_barrier_destroy (&pool->threads_dock);
+
+#ifdef HAVE_SYNC_BUILTINS
+         __sync_fetch_and_add (&gomp_managed_threads,
+                               1L - pool->threads_used);
+#else
+         gomp_mutex_lock (&gomp_managed_threads_lock);
+         gomp_managed_threads -= pool->threads_used - 1L;
+         gomp_mutex_unlock (&gomp_managed_threads_lock);
+#endif
+         for (i = 1; i < pool->threads_used; i++)
+           pthread_join (thrs[i], NULL);
+       }
+      if (pool->last_team)
+       free_team (pool->last_team);
+#ifndef __nvptx__
+      free (pool->threads);
+      free (pool);
+#endif
+      thr->thread_pool = NULL;
+    }
+  return 0;
+}
 #endif
 
 struct gomp_task_icv *
diff --git a/libgomp/testsuite/libgomp.c-c++-common/pause-1.c b/libgomp/testsuite/libgomp.c-c++-common/pause-1.c
new file mode 100644 (file)
index 0000000..5367a72
--- /dev/null
@@ -0,0 +1,23 @@
+#include <omp.h>
+#include <stdlib.h>
+
+int a[64];
+
+int
+main ()
+{
+  int i;
+  #pragma omp parallel for
+  for (i = 0; i < 64; i++)
+    a[i] = i;
+  omp_pause_resource (omp_pause_soft, omp_get_initial_device ());
+  #pragma omp parallel for
+  for (i = 0; i < 64; i++)
+    a[i] += i;
+  omp_pause_resource_all (omp_pause_hard);
+  #pragma omp parallel for
+  for (i = 0; i < 64; i++)
+    if (a[i] != 2 * i)
+      abort ();
+  return 0;
+}
diff --git a/libgomp/testsuite/libgomp.c-c++-common/pause-2.c b/libgomp/testsuite/libgomp.c-c++-common/pause-2.c
new file mode 100644 (file)
index 0000000..e4781cd
--- /dev/null
@@ -0,0 +1,41 @@
+/* { dg-do run } */
+/* { dg-require-effective-target tls_runtime } */
+
+#include <omp.h>
+#include <stdlib.h>
+
+int t = 128;
+#pragma omp threadprivate (t)
+
+int
+main ()
+{
+  #pragma omp parallel
+  t = omp_get_thread_num () + 256;
+  #pragma omp parallel
+  if (t != omp_get_thread_num () + 256)
+    abort ();
+  omp_pause_resource (omp_pause_soft, omp_get_initial_device ());
+  /* This goes beyond what is required by the standard, we actually
+     check if the threads other than the initial one have been destroyed.  */
+  #pragma omp parallel
+  {
+    if (omp_get_thread_num () != 0 && t != 128)
+      abort ();
+    t = omp_get_thread_num () + 384;
+  }
+  #pragma omp parallel
+  if (t != omp_get_thread_num () + 384)
+    abort ();
+  omp_pause_resource_all (omp_pause_hard);
+  #pragma omp parallel
+  {
+    if (omp_get_thread_num () != 0 && t != 128)
+      abort ();
+    t = omp_get_thread_num () + 512;
+  }
+  #pragma omp parallel
+  if (t != omp_get_thread_num () + 512)
+    abort ();
+  return 0;
+}