Skip to content

Commit 04ab3fb

Browse files
committed
[SYCL] Fix unloading of shared images on Windows
After intel#17869, Windows will not unload images during the runtime of the program. However, this means that shared libraries that are dynamically loaded and unloaded will leave dangling pointers to their images. If somehow these images get picked up, e.g. if another library is loaded with overlapping symbols, the runtime may try to dereference the dangling device image pointers. This commit reenables Windows unloading with the caveat that once the global handler is dead the runtime assumes that shutdown has begun. Signed-off-by: Larsen, Steffen <[email protected]>
1 parent d2a2b92 commit 04ab3fb

File tree

4 files changed

+16
-5
lines changed

4 files changed

+16
-5
lines changed

sycl/source/detail/global_handler.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,10 @@ GlobalHandler &GlobalHandler::instance() {
134134
return *RTGlobalObjHandler;
135135
}
136136

137+
bool GlobalHandler::isInstanceAlive() {
138+
return GlobalHandler::getInstancePtr();
139+
}
140+
137141
template <typename T, typename... Types>
138142
T &GlobalHandler::getOrCreate(InstWithLock<T> &IWL, Types &&...Args) {
139143
const LockGuard Lock{IWL.Lock};

sycl/source/detail/global_handler.hpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,9 @@ class GlobalHandler {
5252
/// `__attribute__((destructor))` is called).
5353
static GlobalHandler &instance();
5454

55+
/// \return true if the instance has not been deallocated yet.
56+
static bool isInstanceAlive();
57+
5558
GlobalHandler(const GlobalHandler &) = delete;
5659
GlobalHandler(GlobalHandler &&) = delete;
5760
GlobalHandler &operator=(const GlobalHandler &) = delete;

sycl/source/detail/program_manager/program_manager.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3927,9 +3927,8 @@ extern "C" void __sycl_register_lib(sycl_device_binaries desc) {
39273927
// Executed as a part of current module's (.exe, .dll) static initialization
39283928
extern "C" void __sycl_unregister_lib(sycl_device_binaries desc) {
39293929
// Partial cleanup is not necessary at shutdown
3930-
#ifndef _WIN32
3931-
if (!sycl::detail::GlobalHandler::instance().isOkToDefer())
3930+
if (!sycl::detail::GlobalHandler::isInstanceAlive() ||
3931+
!sycl::detail::GlobalHandler::instance().isOkToDefer())
39323932
return;
39333933
sycl::detail::ProgramManager::getInstance().removeImages(desc);
3934-
#endif
39353934
}

sycl/unittests/helpers/MockDeviceImage.hpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -363,10 +363,15 @@ template <size_t __NumberOfImages> class MockDeviceImageArray {
363363
nullptr, // not used, put here for compatibility with OpenMP
364364
};
365365

366-
__sycl_register_lib(&MAllBinaries);
366+
sycl::detail::ProgramManager::getInstance().addImages(&MAllBinaries);
367367
}
368368

369-
~MockDeviceImageArray() { __sycl_unregister_lib(&MAllBinaries); }
369+
~MockDeviceImageArray() {
370+
// If there is still a global handler, we are not doing full unloading yet.
371+
// As such, we need to clean up the images we registered.
372+
if (GlobalHandler::isInstanceAlive())
373+
sycl::detail::ProgramManager::getInstance().removeImages(&MAllBinaries);
374+
}
370375

371376
private:
372377
sycl_device_binary_struct MNativeImages[NumberOfImages];

0 commit comments

Comments
 (0)