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