diff --git a/openmp/libomptarget/include/omptargetplugin.h b/openmp/libomptarget/include/omptargetplugin.h index 631678c9e4518..c036eb7ced756 100644 --- a/openmp/libomptarget/include/omptargetplugin.h +++ b/openmp/libomptarget/include/omptargetplugin.h @@ -20,6 +20,12 @@ extern "C" { #endif +// First method called on the plugin +int32_t __tgt_rtl_init_plugin(); + +// Last method called on the plugin +int32_t __tgt_rtl_deinit_plugin(); + // Return the number of available devices of the type supported by the // target RTL. int32_t __tgt_rtl_number_of_devices(void); diff --git a/openmp/libomptarget/include/rtl.h b/openmp/libomptarget/include/rtl.h index f2833a13d026d..5e755393330c7 100644 --- a/openmp/libomptarget/include/rtl.h +++ b/openmp/libomptarget/include/rtl.h @@ -25,6 +25,8 @@ struct DeviceTy; struct __tgt_bin_desc; struct RTLInfoTy { + typedef int32_t(init_plugin_ty)(); + typedef int32_t(deinit_plugin_ty)(); typedef int32_t(is_valid_binary_ty)(void *); typedef int32_t(is_valid_binary_info_ty)(void *, void *); typedef int32_t(is_data_exchangable_ty)(int32_t, int32_t); @@ -82,6 +84,8 @@ struct RTLInfoTy { #endif // Functions implemented in the RTL. + init_plugin_ty *init_plugin = nullptr; + deinit_plugin_ty *deinit_plugin = nullptr; is_valid_binary_ty *is_valid_binary = nullptr; is_valid_binary_info_ty *is_valid_binary_info = nullptr; is_data_exchangable_ty *is_data_exchangable = nullptr; diff --git a/openmp/libomptarget/plugins/amdgpu/src/rtl.cpp b/openmp/libomptarget/plugins/amdgpu/src/rtl.cpp index 1bf4938094cff..9b4bf41418611 100644 --- a/openmp/libomptarget/plugins/amdgpu/src/rtl.cpp +++ b/openmp/libomptarget/plugins/amdgpu/src/rtl.cpp @@ -2048,6 +2048,9 @@ int32_t __tgt_rtl_is_valid_binary_info(__tgt_device_image *image, return true; } +int32_t __tgt_rtl_init_plugin() { return OFFLOAD_SUCCESS; } +int32_t __tgt_rtl_deinit_plugin() { return OFFLOAD_SUCCESS; } + int __tgt_rtl_number_of_devices() { // If the construction failed, no methods are safe to call if (DeviceInfo.ConstructionSucceeded) { diff --git a/openmp/libomptarget/plugins/exports b/openmp/libomptarget/plugins/exports index fa6a7d97760e5..84381af3724d9 100644 --- a/openmp/libomptarget/plugins/exports +++ b/openmp/libomptarget/plugins/exports @@ -1,5 +1,7 @@ VERS1.0 { global: + __tgt_rtl_init_plugin; + __tgt_rtl_deinit_plugin; __tgt_rtl_is_valid_binary; __tgt_rtl_is_valid_binary_info; __tgt_rtl_is_data_exchangable; diff --git a/openmp/libomptarget/src/rtl.cpp b/openmp/libomptarget/src/rtl.cpp index 9d10712c9b334..9acf5f3e19c34 100644 --- a/openmp/libomptarget/src/rtl.cpp +++ b/openmp/libomptarget/src/rtl.cpp @@ -109,6 +109,17 @@ void RTLsTy::loadRTLs() { // Retrieve the RTL information from the runtime library. RTLInfoTy &R = AllRTLs.back(); + // Remove plugin on failure to call optional init_plugin + *((void **)&R.init_plugin) = dlsym(DynlibHandle, "__tgt_rtl_init_plugin"); + if (R.init_plugin) { + int32_t Rc = R.init_plugin(); + if (Rc != OFFLOAD_SUCCESS) { + DP("Unable to initialize library '%s': %u!\n", Name, Rc); + AllRTLs.pop_back(); + continue; + } + } + bool ValidPlugin = true; if (!(*((void **)&R.is_valid_binary) = @@ -167,6 +178,8 @@ void RTLsTy::loadRTLs() { R.NumberOfDevices); // Optional functions + *((void **)&R.deinit_plugin) = + dlsym(DynlibHandle, "__tgt_rtl_deinit_plugin"); *((void **)&R.is_valid_binary_info) = dlsym(DynlibHandle, "__tgt_rtl_is_valid_binary_info"); *((void **)&R.deinit_device) = @@ -553,8 +566,14 @@ void RTLsTy::unregisterLib(__tgt_bin_desc *Desc) { PM->TblMapMtx.unlock(); - // TODO: Remove RTL and the devices it manages if it's not used anymore? // TODO: Write some RTL->unload_image(...) function? + for (auto *R : UsedRTLs) { + if (R->deinit_plugin) { + if (R->deinit_plugin() != OFFLOAD_SUCCESS) { + DP("Failure deinitializing RTL %s!\n", R->RTLName.c_str()); + } + } + } DP("Done unregistering library!\n"); }