263 changes: 140 additions & 123 deletions openmp/libomptarget/plugins/amdgpu/src/rtl.cpp

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions openmp/libomptarget/plugins/exports
Original file line number Diff line number Diff line change
@@ -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;
Expand Down
31 changes: 30 additions & 1 deletion openmp/libomptarget/src/rtl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,23 @@ __attribute__((constructor(101))) void init() {

__attribute__((destructor(101))) void deinit() {
DP("Deinit target library!\n");

for (auto *R : PM->RTLs.UsedRTLs) {
// Plugins can either destroy their local state using global variables
// or attribute(destructor) functions or by implementing deinit_plugin
// The hazard with plugin local destructors is they may be called before
// or after this destructor. If the plugin is destroyed using global
// state before this library finishes calling into it the plugin is
// likely to crash. If good fortune means the plugin outlives this
// library then there may be no crash.
// Using deinit_plugin and no global destructors from the plugin works.
if (R->deinit_plugin) {
if (R->deinit_plugin() != OFFLOAD_SUCCESS) {
DP("Failure deinitializing RTL %s!\n", R->RTLName.c_str());
}
}
}

delete PM;

#ifdef OMPTARGET_PROFILE_ENABLED
Expand Down Expand Up @@ -109,6 +126,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) =
Expand Down Expand Up @@ -167,6 +195,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) =
Expand Down Expand Up @@ -553,7 +583,6 @@ 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?

DP("Done unregistering library!\n");
Expand Down