This patch adds functions defined in the section 5.5.5 Thread Handles in
OpenMP API Specification 5.0. It currently omits CUDA support, and
hard-codes the offset and sizeof values. I would appreciate any
suggestions.

2020-07-30  Tony Sim  <y2s1...@gmail.com>

libgomp/ChangeLog:

        * Makefile.am (libgompd_la_SOURCES): Add ompd-thread.c.
        * Makefile.in: Regenerate.
        * libgompd.h (ompd_thread_handle_t): Add definition.
        (ompd_parallel_handle_t): Add definition.
        * ompd-thread.c: New file.

---
 libgomp/Makefile.am   |   2 +-
 libgomp/Makefile.in   |   5 +-
 libgomp/libgompd.h    |  12 +++
 libgomp/ompd-thread.c | 203 ++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 219 insertions(+), 3 deletions(-)
 create mode 100644 libgomp/ompd-thread.c

diff --git a/libgomp/Makefile.am b/libgomp/Makefile.am
index fe0a92122ea..0e6f2d1c830 100644
--- a/libgomp/Makefile.am
+++ b/libgomp/Makefile.am
@@ -90,7 +90,7 @@ libgomp_la_SOURCES = alloc.c atomic.c barrier.c critical.c 
env.c error.c \
        oacc-mem.c oacc-async.c oacc-plugin.c oacc-cuda.c priority_queue.c \
        affinity-fmt.c teams.c allocator.c oacc-profiling.c oacc-target.c
 
-libgompd_la_SOURCES = ompd-lib.c ompd-proc.c
+libgompd_la_SOURCES = ompd-lib.c ompd-proc.c ompd-thread.c
 
 include $(top_srcdir)/plugin/Makefrag.am
 
diff --git a/libgomp/Makefile.in b/libgomp/Makefile.in
index f74d5f3ac8e..137ce35dfc1 100644
--- a/libgomp/Makefile.in
+++ b/libgomp/Makefile.in
@@ -235,7 +235,7 @@ am_libgomp_la_OBJECTS = alloc.lo atomic.lo barrier.lo 
critical.lo \
        $(am__objects_1)
 libgomp_la_OBJECTS = $(am_libgomp_la_OBJECTS)
 libgompd_la_LIBADD =
-am_libgompd_la_OBJECTS = ompd-lib.lo ompd-proc.lo
+am_libgompd_la_OBJECTS = ompd-lib.lo ompd-proc.lo ompd-thread.lo
 libgompd_la_OBJECTS = $(am_libgompd_la_OBJECTS)
 AM_V_P = $(am__v_P_@AM_V@)
 am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
@@ -593,7 +593,7 @@ libgomp_la_SOURCES = alloc.c atomic.c barrier.c critical.c 
env.c \
        oacc-async.c oacc-plugin.c oacc-cuda.c priority_queue.c \
        affinity-fmt.c teams.c allocator.c oacc-profiling.c \
        oacc-target.c $(am__append_4)
-libgompd_la_SOURCES = ompd-lib.c ompd-proc.c
+libgompd_la_SOURCES = ompd-lib.c ompd-proc.c ompd-thread.c
 
 # Nvidia PTX OpenACC plugin.
 @PLUGIN_NVPTX_TRUE@libgomp_plugin_nvptx_version_info = -version-info 
$(libtool_VERSION)
@@ -819,6 +819,7 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/oacc-target.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ompd-lib.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ompd-proc.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ompd-thread.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ordered.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/parallel.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/priority_queue.Plo@am__quote@
diff --git a/libgomp/libgompd.h b/libgomp/libgompd.h
index 495995e00d3..98a2f74b983 100644
--- a/libgomp/libgompd.h
+++ b/libgomp/libgompd.h
@@ -47,4 +47,16 @@ typedef struct _ompd_aspace_handle {
   ompd_size_t ref_count;
 } ompd_address_space_handle_t;
 
+typedef struct _ompd_thread_handle {
+  ompd_parallel_handle_t *ph;
+  ompd_address_space_handle_t *ah;
+  ompd_thread_context_t *tcontext;
+  ompd_address_t *thread;
+} ompd_thread_handle_t;
+
+typedef struct _ompd_parallel_handle {
+  ompd_address_space_handle_t *ah;
+  ompd_address_t *tpool;
+} ompd_parallel_handle_t;
+
 #endif /* LIBGOMPD_H */
diff --git a/libgomp/ompd-thread.c b/libgomp/ompd-thread.c
new file mode 100644
index 00000000000..281cd7e2520
--- /dev/null
+++ b/libgomp/ompd-thread.c
@@ -0,0 +1,203 @@
+/* Copyright (C) 2020 Free Software Foundation, Inc.
+   Contributed by Yoosuk Sim <y2s1...@gmail.com>.
+
+   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
+   the Free Software Foundation; either version 3, or (at your option)
+   any later version.
+
+   Libgomp is distributed in the hope that it will be useful, but WITHOUT ANY
+   WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+   FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+   more details.
+
+   Under Section 7 of GPL version 3, you are granted additional
+   permissions described in the GCC Runtime Library Exception, version
+   3.1, as published by the Free Software Foundation.
+
+   You should have received a copy of the GNU General Public License and
+   a copy of the GCC Runtime Library Exception along with this program;
+   see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+/* This file contains OMPD function definitions related to threads, as defined
+   in the section 5.5.5 in the OpenMP API Specification 5.0.  */
+
+#include "omp-tools.h"
+#include "ompd-types.h"
+#include "libgompd.h"
+#include "libgomp.h"
+#include <stddef.h>
+
+ompd_rc_t
+ompd_get_thread_in_parallel (ompd_parallel_handle_t *ph, int thread_num,
+                                     ompd_thread_handle_t **th)
+{
+  ompd_rc_t ret;
+  int max_size = 0;
+  // TODO: Using ICV, obtain max_size from ompd-team-size-var
+  if ( thread_num < 0 || thread_num > max_size)
+    return ompd_rc_bad_input;
+
+  ompd_device_type_sizes_t type_size;
+  ompd_address_t thread_addr;
+  ompd_address_t thread_addr_ptr = *ph->tpool;
+
+  // TODO: fix hardcoded offset
+  thread_addr_ptr.address += offsetof (struct gomp_thread_pool, threads);
+
+  ret = gompd_callbacks.sizeof_type (ph->ah->context, &type_size);
+  if (ret != ompd_rc_ok)
+    return ret;
+
+  ret = gompd_callbacks.read_memory (ph->ah->context, NULL, &thread_addr_ptr,
+                                    type_size.sizeof_pointer,
+                                    (void *) &thread_addr.address);
+  if (ret != ompd_rc_ok)
+    return ret;
+  thread_addr.address += thread_num * type_size.sizeof_pointer;
+
+  ompd_thread_handle_t *p;
+  ret = gompd_callbacks.alloc_memory (sizeof (ompd_thread_handle_t),
+                                             (void *) p);
+  if (ret != ompd_rc_ok)
+    return ret;
+  ret = gompd_callbacks.alloc_memory (sizeof (ompd_address_t),
+                                             (void *) p->thread);
+  if (ret != ompd_rc_ok)
+    return ret;
+
+  p->ph = ph;
+  p->ah = ph->ah;
+  *p->thread = thread_addr;
+  *th = p;
+
+  return ompd_rc_ok;
+}
+
+ompd_rc_t
+ompd_get_thread_handle (ompd_address_space_handle_t *ah,
+                                ompd_thread_id_t kind,
+                                ompd_size_t sizeof_thread_id,
+                                const void *thread_id,
+                                ompd_thread_handle_t **th)
+{
+  if (!ah || !ah->context)
+    return ompd_rc_stale_handle;
+
+  ompd_rc_t ret;
+  ompd_address_space_context_t *context = ah->context;
+
+  ompd_thread_context_t *tcontext;
+  ret = gompd_callbacks.get_thread_context_for_thread_id (context, kind,
+                                                         sizeof_thread_id,
+                                                         thread_id, &tcontext);
+  if (ret != ompd_rc_ok)
+    return ret;
+
+  unsigned tid;
+  if (kind == OMPD_THREAD_ID_CUDALOGICAL)
+    {
+      //TODO: implement CUDA counterpart.
+      return ompd_rc_error;
+    }
+  else
+    {
+      ompd_address_t thread_address;
+      //TODO: check if there is a better way to find a thread from contexts.
+      ret = gompd_callbacks.symbol_addr_lookup (context, tcontext, "thr",
+                                               &thread_address, NULL);
+      if (ret != ompd_rc_ok)
+       return ret;
+
+      ompd_address_t tid_address = thread_address;
+      // TODO: fix hardcoded offset
+      tid_address.address += offsetof (struct gomp_thread, ts)
+                           + offsetof (struct gomp_team_state, team_id);
+      // TODO: fix hardcoded size
+      ret = gompd_callbacks.read_memory (context, tcontext, &tid_address,
+                                        sizeof (unsigned), &tid);
+      if (ret != ompd_rc_ok)
+       return ret;
+      if (tid < 0)
+       return ompd_rc_unavailable;
+
+      ompd_thread_handle_t *p;
+      ret = gompd_callbacks.alloc_memory (sizeof (ompd_thread_handle_t),
+                                                 (void *) p);
+      if (ret != ompd_rc_ok)
+       return ret;
+      ret = gompd_callbacks.alloc_memory (sizeof (ompd_address_t),
+                                                 (void *) p->thread);
+      if (ret != ompd_rc_ok)
+       return ret;
+
+      p->ph = NULL;
+      p->ah = ah;
+      p->tcontext = tcontext;
+      *p->thread = thread_address;
+      *th = p;
+    }
+  return ompd_rc_ok;
+}
+
+ompd_rc_t
+ompd_rel_thread_handle (ompd_thread_handle_t *th)
+{
+  if (!th || !th->thread)
+    return ompd_rc_stale_handle;
+  ompd_rc_t ret = gompd_callbacks.free_memory (th->thread);
+  if (ret != ompd_rc_ok)
+    return ret;
+  ret = gompd_callbacks.free_memory (th);
+  return ret;
+}
+
+ompd_rc_t
+ompd_thread_handle_compare (ompd_thread_handle_t *lhs,
+                               ompd_thread_handle_t *rhs, int *cmp_value)
+{
+  if (!lhs || !rhs || !lhs->thread || !rhs->thread)
+    return ompd_rc_stale_handle;
+  if (!cmp_value)
+    return ompd_rc_bad_input;
+
+  *cmp_value = lhs->ah == rhs->ah && lhs->ph == rhs->ph
+        && lhs->tcontext == rhs->tcontext
+        && lhs->thread->address == rhs->thread->address
+        && lhs->thread->segment == rhs->thread->segment;
+
+  return ompd_rc_ok;
+}
+
+ompd_rc_t
+ompd_get_thread_id (ompd_thread_handle_t *th,
+                            ompd_thread_id_t kind,
+                            ompd_size_t sizeof_thread_id, void *thread_id)
+{
+  if (!th || !th->thread)
+    return ompd_rc_stale_handle;
+
+  ompd_rc_t ret;
+
+  if (kind == OMPD_THREAD_ID_CUDALOGICAL)
+    {
+      //TODO: support CUDA
+      return ompd_rc_unsupported;
+    }
+  else
+    {
+      ompd_address_t tid_address = *th->thread;
+      // TODO: fix hardcoded offset
+      tid_address.address += offsetof (struct gomp_thread, ts)
+                            + offsetof (struct gomp_team_state, team_id);
+      ret = gompd_callbacks.read_memory (th->ah->context, th->tcontext,
+                                        &tid_address, sizeof_thread_id,
+                                        (void *) thread_id);
+      return ret;
+    }
+  return ompd_rc_ok;
+}
-- 
2.27.0

Reply via email to