//===-- OpenMP/OMPT/Connector.h - OpenMP Tooling lib connector -*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // // Support used by OMPT implementation to establish communication between // various OpenMP runtime libraries: host openmp library, target-independent // runtime library, and device-dependent runtime libraries. // //===----------------------------------------------------------------------===// #ifndef OMPTARGET_OPENMP_OMPT_CONNECTOR_H #define OMPTARGET_OPENMP_OMPT_CONNECTOR_H #ifdef OMPT_SUPPORT #include "llvm/Support/DynamicLibrary.h" #include #include #include "omp-tools.h" #include "omptarget.h" #include "Shared/Debug.h" #pragma push_macro("DEBUG_PREFIX") #undef DEBUG_PREFIX #define DEBUG_PREFIX "OMPT" /// Type for the function to be invoked for connecting two libraries. typedef void (*OmptConnectRtnTy)(ompt_start_tool_result_t *result); /// Establish connection between openmp runtime libraries /// /// This class is used to communicate between an OMPT implementation in /// libomptarget and libomp. It is also used to communicate between an /// OMPT implementation in a device-specific plugin and /// libomptarget. The decision whether OMPT is enabled or not needs to /// be made when the library is loaded before any functions in the /// library are invoked. For that reason, an instance of this class is /// intended to be defined in the constructor for libomptarget or a /// plugin so that the decision about whether OMPT is supposed to be /// enabled is known before any interface function in the library is /// invoked. class OmptLibraryConnectorTy { public: /// Use \p LibName as the prefix of the global function used for connecting /// two libraries, the source indicated by \p LibName and the destination /// being the one that creates this object. OmptLibraryConnectorTy(const char *Ident) { LibIdent.append(Ident); IsInitialized = false; } OmptLibraryConnectorTy() = delete; /// Use \p OmptResult init to connect the two libraries denoted by this /// object. The init function of \p OmptResult will be used during connection /// and the fini function of \p OmptResult will be used during teardown. void connect(ompt_start_tool_result_t *OmptResult) { initialize(); if (!LibConnHandle) return; // Call the function provided by the source library for connect LibConnHandle(OmptResult); } private: void initialize() { if (IsInitialized) return; std::string ErrMsg; std::string LibName = LibIdent; LibName += ".so"; DP("OMPT: Trying to load library %s\n", LibName.c_str()); auto DynLibHandle = std::make_unique( llvm::sys::DynamicLibrary::getPermanentLibrary(LibName.c_str(), &ErrMsg)); if (!DynLibHandle->isValid()) { // The upper layer will bail out if the handle is null. LibConnHandle = nullptr; } else { auto LibConnRtn = "ompt_" + LibIdent + "_connect"; DP("OMPT: Trying to get address of connection routine %s\n", LibConnRtn.c_str()); LibConnHandle = reinterpret_cast( DynLibHandle->getAddressOfSymbol(LibConnRtn.c_str())); } DP("OMPT: Library connection handle = %p\n", LibConnHandle); IsInitialized = true; } /// Ensure initialization occurs only once bool IsInitialized; /// Handle of connect routine provided by source library OmptConnectRtnTy LibConnHandle; /// Name of connect routine provided by source library std::string LibIdent; }; #endif // OMPT_SUPPORT #pragma pop_macro("DEBUG_PREFIX") #endif // OMPTARGET_OPENMP_OMPT_CONNECTOR_H