From patchwork Mon Jun 6 22:21:25 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ahmed Sayed Mousse X-Patchwork-Id: 54848 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 97716384D166 for ; Mon, 6 Jun 2022 22:22:09 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 97716384D166 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1654554129; bh=ZRbwfW5WngSm8otihuDeHnukNdSIFLKr454df/YzNFc=; h=Date:Subject:To:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:From; b=Rxy7Br27DX1f+xAKIgX7FFJTuUla3WDh4hFQyWIRvvced199Ca911hy0IvACQVYsH LjrfwSTfosKO4EGF9c8N210otsVFjBI9xo+4IuAp0J8uoKDRDJSZ4q52PQ0dhPndT5 6rMW7osmZXSvJAIsNDnDLW3cJ5S39qeU3wNc/a6E= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mail-pl1-x62e.google.com (mail-pl1-x62e.google.com [IPv6:2607:f8b0:4864:20::62e]) by sourceware.org (Postfix) with ESMTPS id CE1A1384D15E for ; Mon, 6 Jun 2022 22:21:38 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org CE1A1384D15E Received: by mail-pl1-x62e.google.com with SMTP id o6so8169754plg.2 for ; Mon, 06 Jun 2022 15:21:38 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:mime-version:from:date:message-id:subject:to; bh=ImfP0qynIkqvHXgzMjE1SHvDoncwNYenp1nuzGbJFg0=; b=xAJeUzy59gMDxvJe9FZRQv+qSNqeD92oavPsyJrdR/nsx/COnd5f61scUEmFgnukFF 9biwHJ6It2cu1p61LlcJAvzW6gyLB3xNWDIVNIAPUg8OoDshCni5KcPPJhMe1sCHwwEl Ytvg/khwHvSy1fADwTdO6x5VRrKgNTNYIFvXYgOggshCLwbmXEOxSvyDZUdmFTRwaCHY FJwdmujl2+gh4Sa7DSrKNzJ513FatevZaNMLCNu36OwHDKU42OE8kPYCJPqpIakdkkrB XIFLP3w9a44BNnU5E8/2BYk1MQ5BRQ6abkUj7jP7CHYspjeL6zenGKI8RgdZy63qhG1l 7Edg== X-Gm-Message-State: AOAM53218vj/heKBbc8j+wUF1GmzejUzwtSamKP+c7cHU6D9moVQDZIH 2cCXN8HGNGT4Smh7GCmIR7m3KLDdj9LzDdsTxG2PsQ9EDoE= X-Google-Smtp-Source: ABdhPJw73qs4hfb6iNfCEPFiGp5YJ+vdtDNJDKhb4EqXXTfJRK+W4plmxEip9YCjYRy+BMuFdqbS6lXdCFLwOgJ7E1I= X-Received: by 2002:a17:902:7e89:b0:161:f196:b4b with SMTP id z9-20020a1709027e8900b00161f1960b4bmr26148822pla.40.1654554097525; Mon, 06 Jun 2022 15:21:37 -0700 (PDT) MIME-Version: 1.0 Date: Tue, 7 Jun 2022 00:21:25 +0200 Message-ID: Subject: [patch] libgompd: Add thread handles To: gcc-patches@gcc.gnu.org X-Spam-Status: No, score=-7.3 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_FROM, GIT_PATCH_0, HTML_MESSAGE, KAM_SHORT, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-Content-Filtered-By: Mailman/MimeDel 2.1.29 X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Ahmed Sayed Mousse via Gcc-patches From: Ahmed Sayed Mousse Reply-To: Ahmed Sayed Mousse Errors-To: gcc-patches-bounces+patchwork=sourceware.org@gcc.gnu.org Sender: "Gcc-patches" This patch is the initial implementation of OpenMP-API specs book section 20.5.5 with title "Thread Handles" libgomp/ChangeLog 2022-05-06 Ahmed Sayed * Makefile.am (libgompd_la_SOURCES): Add ompd-threads.c. * Makefile.in: Regenerate. * ompd-support.h ( gompd_thread_initial_tls_bias ): New Variable. * ompd-support.c ( gompd_thread_initial_tls_bias ): New Variable. ( gompd_load ): ( gompd_thread_initial_tls_bias ): Initialized with &gomp_tls_data - pthread_self (). * ompd-threads.c: New. diff --git a/libgomp/Makefile.am b/libgomp/Makefile.am index 6d913a93e7f..23f5bede1bf 100644 --- a/libgomp/Makefile.am +++ b/libgomp/Makefile.am @@ -94,7 +94,7 @@ libgomp_la_SOURCES = alloc.c atomic.c barrier.c critical.c env.c error.c \ priority_queue.c affinity-fmt.c teams.c allocator.c oacc-profiling.c \ oacc-target.c ompd-support.c -libgompd_la_SOURCES = ompd-init.c ompd-helper.c ompd-icv.c +libgompd_la_SOURCES = ompd-init.c ompd-helper.c ompd-icv.c ompd-threads.c include $(top_srcdir)/plugin/Makefrag.am diff --git a/libgomp/Makefile.in b/libgomp/Makefile.in index 40f896b5f03..7acdcbf31d5 100644 --- a/libgomp/Makefile.in +++ b/libgomp/Makefile.in @@ -233,7 +233,8 @@ am_libgomp_la_OBJECTS = alloc.lo atomic.lo barrier.lo critical.lo \ affinity-fmt.lo teams.lo allocator.lo oacc-profiling.lo \ oacc-target.lo ompd-support.lo $(am__objects_1) libgomp_la_OBJECTS = $(am_libgomp_la_OBJECTS) -am_libgompd_la_OBJECTS = ompd-init.lo ompd-helper.lo ompd-icv.lo +am_libgompd_la_OBJECTS = ompd-init.lo ompd-helper.lo ompd-icv.lo \ + ompd-threads.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@) @@ -583,7 +584,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 ompd-support.c $(am__append_7) -libgompd_la_SOURCES = ompd-init.c ompd-helper.c ompd-icv.c +libgompd_la_SOURCES = ompd-init.c ompd-helper.c ompd-icv.c ompd-threads.c # Nvidia PTX OpenACC plugin. @PLUGIN_NVPTX_TRUE@libgomp_plugin_nvptx_version_info = -version-info $(libtool_VERSION) @@ -801,6 +802,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ompd-icv.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ompd-init.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ompd-support.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ompd-threads.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/ompd-support.c b/libgomp/ompd-support.c index d8a7174b2f3..c7da3ef98a6 100644 --- a/libgomp/ompd-support.c +++ b/libgomp/ompd-support.c @@ -36,6 +36,10 @@ const char **ompd_dll_locations = NULL; __UINT64_TYPE__ gompd_state; +#if (defined HAVE_TLS || defined USE_EMUTLS) +__UINT64_TYPE__ gompd_thread_initial_tls_bias; +#endif + void gompd_load (void) { @@ -61,7 +65,11 @@ gompd_load (void) = (__UINT64_TYPE__) & (((struct gomp_thread *) NULL)->handle); __UINT64_TYPE__ gompd_sizeof_gomp_thread_handle = sizeof (((struct gomp_thread *) NULL)->handle); + #elif (defined HAVE_TLS || defined USE_EMUTLS) + gompd_thread_initial_tls_bias = (__UINT64_TYPE__) \ + (&gomp_tls_data - pthread_self ()); #endif + gomp_debug (2, "OMP OMPD active\n"); static const char *ompd_dll_locations_array[2] = {"libgompd" SONAME_SUFFIX (1) , NULL}; diff --git a/libgomp/ompd-support.h b/libgomp/ompd-support.h index 39d55161132..2dd88af2d73 100644 --- a/libgomp/ompd-support.h +++ b/libgomp/ompd-support.h @@ -69,6 +69,10 @@ void gompd_load (void); extern __UINT64_TYPE__ gompd_state; +#if (defined HAVE_TLS || defined USE_EMUTLS) +extern __UINT64_TYPE__ gompd_thread_initial_tls_bias; +#endif + #define OMPD_ENABLED 0x1 #define GOMPD_FOREACH_ACCESS(gompd_access) \ diff --git a/libgomp/ompd-support.h.gch b/libgomp/ompd-support.h.gch new file mode 100644 index 00000000000..ee98f7091c0 Binary files /dev/null and b/libgomp/ompd-support.h.gch differ diff --git a/libgomp/ompd-threads.c b/libgomp/ompd-threads.c new file mode 100644 index 00000000000..bc370e1af9c --- /dev/null +++ b/libgomp/ompd-threads.c @@ -0,0 +1,310 @@ +/* Copyright (C) The GNU Toolchain Authors. + Contributed by Ahmed Sayed . + 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 + . */ + +/* This file contains the implementation of functions defined in + Section 5.5 ThreadHandles. */ + + +#include "ompd-helper.h" + +ompd_rc_t +ompd_get_thread_in_parallel (ompd_parallel_handle_t *parallel_handle, int + thread_num, ompd_thread_handle_t **thread_handle) +{ + + if (parallel_handle == NULL) + return ompd_rc_stale_handle; + if (parallel_handle->ah == NULL) + return ompd_rc_stale_handle; + + ompd_address_space_context_t *context = parallel_handle->ah->context; + ompd_rc_t ret; + + if (!context) + return ompd_rc_stale_handle; + + if (!callbacks) + return ompd_rc_callback_error; + + ompd_word_t team_size_var; + ret = ompd_get_icv_from_scope ((void *) parallel_handle, ompd_scope_parallel, + gompd_icv_team_size_var, &team_size_var); + if (ret != ompd_rc_ok) + return ret; + if (thread_num < 0 || thread_num >= team_size_var) + return ompd_rc_bad_input; + + ompd_size_t temp_offset, field_offset; + ompd_address_t temp_symbol_addr, symbol_addr = {OMPD_SEGMENT_UNSPECIFIED, 0}; + + const char *symbol_name = "gompd_access_gomp_thread_pool_threads"; + ret = callbacks->symbol_addr_lookup (context, NULL, symbol_name, &symbol_addr, + NULL); + ret = callbacks->read_memory (context, NULL, &symbol_addr, + target_sizes.sizeof_long_long, &temp_offset); + + ret = callbacks->device_to_host (context, &temp_offset, + target_sizes.sizeof_long_long, 1, + &field_offset); + if (ret != ompd_rc_ok) + return ret; + + symbol_addr.address += field_offset; + + ret = callbacks->read_memory (context, NULL, &symbol_addr, + target_sizes.sizeof_pointer, + &temp_symbol_addr.address); + ret = callbacks->device_to_host (context, &temp_symbol_addr.address, + target_sizes.sizeof_pointer, 1, + &symbol_addr.address); + + if (ret != ompd_rc_ok) + return ret; + + symbol_addr.address += thread_num * target_sizes.sizeof_pointer; + + ret = callbacks->read_memory (context, NULL, &symbol_addr, + target_sizes.sizeof_pointer, + &temp_symbol_addr.address); + ret = callbacks->device_to_host (context, &temp_symbol_addr.address, + target_sizes.sizeof_pointer, 1, + &symbol_addr.address); + + if (ret != ompd_rc_ok) + return ret; + + ret = callbacks->alloc_memory (sizeof (ompd_thread_handle_t), + (void **) thread_handle); + + if (ret != ompd_rc_ok) + return ret; + + if (symbol_addr.address == 0) + return ompd_rc_unsupported; + + (*thread_handle)->th = symbol_addr; + (*thread_handle)->ah = parallel_handle->ah; + return ret; +} + +/* The ompd_get_thread_handle function that maps a native thread to an + OMPD thread handle. */ + +ompd_rc_t +ompd_get_thread_handle (ompd_address_space_handle_t *handle, + ompd_thread_id_t kind, ompd_size_t sizeof_thread_id, + const void *thread_id, + ompd_thread_handle_t **thread_handle) +{ + if (!handle) + return ompd_rc_stale_handle; + + if (kind != OMPD_THREAD_ID_PTHREAD) + return ompd_rc_unsupported; + + ompd_address_space_context_t *context = handle->context; + ompd_thread_context_t *tcontext; + ompd_rc_t ret; + + if (!context) + return ompd_rc_stale_handle; + + ret = callbacks->get_thread_context_for_thread_id (context, kind, + sizeof_thread_id, + thread_id, &tcontext); + if (ret != ompd_rc_ok) + return ret; + + ompd_size_t temp_symbol_size, symbol_size; + ompd_address_t temp_symbol_addr, symbol_addr = {OMPD_SEGMENT_UNSPECIFIED, 0}; + + const char *symbol_name = "gompd_sizeof_gomp_thread"; + ret = callbacks->symbol_addr_lookup(context, NULL, symbol_name, &symbol_addr, + NULL); + ret = callbacks->read_memory(context, NULL, &symbol_addr, + target_sizes.sizeof_long_long, + &temp_symbol_size); + ret = callbacks->device_to_host(context, &temp_symbol_size, + target_sizes.sizeof_long_long, 1, + &symbol_size); + if (ret != ompd_rc_ok) + return ret; + + ret = callbacks->symbol_addr_lookup (context, tcontext,"gomp_tls_data", + &symbol_addr, NULL); + + /* if libgomp is offloading or using pthread_key_t then lookup can't + find the symbol "gomp_tls_data". */ + if (ret == ompd_rc_error) + return ompd_rc_unsupported; + + ret = callbacks->read_memory (context, tcontext, &symbol_addr, symbol_size, + &temp_symbol_addr.address); + ret = callbacks->device_to_host (context, &temp_symbol_addr.address, + symbol_size, 1, &symbol_addr.address); + if (ret != ompd_rc_ok) + return ret; + + ret = callbacks->alloc_memory (sizeof(ompd_thread_handle_t), (void **) + (thread_handle)); + + if (ret != ompd_rc_ok) + return ret; + + (*thread_handle)->ah = handle; + (*thread_handle)->th = symbol_addr; + (*thread_handle)->thread_context = tcontext; + return ret; +} + + +ompd_rc_t +ompd_rel_thread_handle (ompd_thread_handle_t *thread_handle) +{ + if (thread_handle == NULL) + return ompd_rc_stale_handle; + + ompd_rc_t ret; + ret = callbacks->free_memory ((void *) thread_handle); + if (ret != ompd_rc_ok) + return ret; + + return ompd_rc_ok; +} + + +/* return -1, 0 or 1 for thread_handle_1 <, == or > thread_handle_2. */ +ompd_rc_t +ompd_thread_handle_compare (ompd_thread_handle_t *thread_handle_1, + ompd_thread_handle_t *thread_handle_2, + int *cmp_value ) +{ + + if (thread_handle_1 == NULL) + return ompd_rc_stale_handle; + if (thread_handle_2 == NULL) + return ompd_rc_stale_handle; + if (cmp_value == NULL) + return ompd_rc_bad_input; + if (thread_handle_1->ah->kind != thread_handle_2->ah->kind) + return ompd_rc_bad_input; + *cmp_value = thread_handle_1->th.address - thread_handle_2->th.address; + + return ompd_rc_ok; +} + + +ompd_rc_t +ompd_get_thread_id (ompd_thread_handle_t *thread_handle, ompd_thread_id_t kind, + ompd_size_t sizeof_thread_id, void *thread_id) +{ + if (kind != OMPD_THREAD_ID_PTHREAD) + return ompd_rc_unsupported; + if (thread_id == NULL) + return ompd_rc_bad_input; + if (!thread_handle || !thread_handle->ah) + return ompd_rc_stale_handle; + + ompd_address_space_context_t *context = thread_handle->ah->context; + if (context == NULL) + return ompd_rc_stale_handle; + + ompd_rc_t ret; + ompd_address_t taddr = thread_handle->th; + ompd_address_t temp_symbol_addr, symbol_addr = {OMPD_SEGMENT_UNSPECIFIED, 0}; + ompd_size_t temp_symbol_size, symbol_size; + ompd_size_t temp_offset, offset; + + + char *symbol_name = "gompd_sizeof_gomp_thread_handle"; + ret = callbacks->symbol_addr_lookup (context, NULL, symbol_name, &symbol_addr, + NULL); + /* If symbol isn't found we check for the optimized version. */ + if (ret == ompd_rc_error) + goto try_bias; + ret = callbacks->read_memory (context, NULL, &symbol_addr, + target_sizes.sizeof_long_long, + &temp_symbol_size); + ret = callbacks->device_to_host (context, &temp_symbol_size, + target_sizes.sizeof_long_long, 1, + &symbol_size); + if (ret != ompd_rc_ok) + return ret; + if (sizeof_thread_id != symbol_size) + return ompd_rc_bad_input; + + symbol_name = "gompd_access_gomp_thread_handle"; + ret = callbacks->symbol_addr_lookup (context, NULL, symbol_name, &symbol_addr, + NULL); + ret = callbacks->read_memory (context, NULL, &symbol_addr, symbol_size, + &temp_offset); + ret = callbacks->device_to_host (context, &temp_offset, symbol_size, 1, + &offset); + + if (ret != ompd_rc_ok) + return ret; + + taddr.address += offset; + ret = callbacks->read_memory (context, NULL, &taddr, + target_sizes.sizeof_long_long, thread_id); + return ret; + +try_bias: + symbol_name = "gompd_thread_initial_tls_bias"; + ret = callbacks->symbol_addr_lookup (context, NULL, symbol_name, &symbol_addr, + NULL); + if (ret == ompd_rc_error) + return ompd_rc_unsupported; + + ret = callbacks->read_memory (context, NULL, &symbol_addr, + target_sizes.sizeof_long_long, &temp_offset); + ret = callbacks->device_to_host (context, &temp_offset, + target_sizes.sizeof_long_long, 1, &offset); + + if (ret != ompd_rc_ok) + return ret; + + ret = callbacks->symbol_addr_lookup (context, NULL,"gomp_tls_data", + &symbol_addr, NULL); + ret = callbacks->device_to_host (context, &temp_symbol_addr.address, + target_sizes.sizeof_long_long, 1, + &symbol_addr.address); + if (ret != ompd_rc_ok) + return ret; + + taddr.address = symbol_addr.address + offset; + ret = callbacks->read_memory (context, NULL, &taddr, + target_sizes.sizeof_long_long, thread_id); + return ret; +} + + +/* OMPD doesn't support GPUs for now. */ +ompd_rc_t ompd_get_device_from_thread (ompd_thread_handle_t *thread_handle, + ompd_address_space_handle_t **device) +{ + if (thread_handle == NULL) + return ompd_rc_stale_handle; + return ompd_rc_unsupported; +}