|
12 | 12 | /// \ingroup sycl_pi_level_zero |
13 | 13 |
|
14 | 14 | #include "pi_level_zero.hpp" |
| 15 | +#include <CL/sycl/detail/spinlock.hpp> |
15 | 16 | #include <algorithm> |
16 | 17 | #include <cstdarg> |
17 | 18 | #include <cstdio> |
@@ -172,6 +173,17 @@ class ReturnHelper { |
172 | 173 |
|
173 | 174 | } // anonymous namespace |
174 | 175 |
|
| 176 | +// Global variables used in PI_Level_Zero |
| 177 | +// Note we only create a simple pointer variables such that C++ RT won't |
| 178 | +// deallocate them automatically at the end of the main program. |
| 179 | +// The heap memory allocated for these global variables reclaimed only when |
| 180 | +// Sycl RT calls piTearDown(). |
| 181 | +static std::vector<pi_platform> *PiPlatformsCache = |
| 182 | + new std::vector<pi_platform>; |
| 183 | +static sycl::detail::SpinLock *PiPlatformsCacheMutex = |
| 184 | + new sycl::detail::SpinLock; |
| 185 | +static bool PiPlatformCachePopulated = false; |
| 186 | + |
175 | 187 | // TODO:: In the following 4 methods we may want to distinguish read access vs. |
176 | 188 | // write (as it is OK for multiple threads to read the map without locking it). |
177 | 189 |
|
@@ -821,16 +833,8 @@ pi_result piPlatformsGet(pi_uint32 NumEntries, pi_platform *Platforms, |
821 | 833 | // 1. sycl::platform equality issue; we always return the same pi_platform. |
822 | 834 | // 2. performance; we can save time by immediately return from cache. |
823 | 835 | // |
824 | | - // Note: The memory for "PiPlatformsCache" and "PiPlatformsCacheMutex" is |
825 | | - // intentionally leaked because the application may call into the SYCL |
826 | | - // runtime from a global destructor, and such a call could eventually |
827 | | - // access these variables. Therefore, there is no safe time when |
828 | | - // "PiPlatformsCache" and "PiPlatformsCacheMutex" could be deleted. |
829 | | - static auto PiPlatformsCache = new std::vector<pi_platform>; |
830 | | - static auto PiPlatformsCacheMutex = new std::mutex; |
831 | | - static bool PiPlatformCachePopulated = false; |
832 | | - |
833 | | - std::lock_guard<std::mutex> Lock(*PiPlatformsCacheMutex); |
| 836 | + |
| 837 | + const std::lock_guard<sycl::detail::SpinLock> Lock{*PiPlatformsCacheMutex}; |
834 | 838 | if (!PiPlatformCachePopulated) { |
835 | 839 | const char *CommandListCacheSize = |
836 | 840 | std::getenv("SYCL_PI_LEVEL_ZERO_MAX_COMMAND_LIST_CACHE"); |
@@ -5349,4 +5353,18 @@ pi_result piPluginInit(pi_plugin *PluginInit) { |
5349 | 5353 | return PI_SUCCESS; |
5350 | 5354 | } |
5351 | 5355 |
|
| 5356 | +// SYCL RT calls this api to notify the end of plugin lifetime. |
| 5357 | +// It can include all the jobs to tear down resources before |
| 5358 | +// the plugin is unloaded from memory. |
| 5359 | +pi_result piTearDown(void *PluginParameter) { |
| 5360 | + // reclaim pi_platform objects here since we don't have piPlatformRelease. |
| 5361 | + for (pi_platform &Platform : *PiPlatformsCache) { |
| 5362 | + delete Platform; |
| 5363 | + } |
| 5364 | + delete PiPlatformsCache; |
| 5365 | + delete PiPlatformsCacheMutex; |
| 5366 | + |
| 5367 | + return PI_SUCCESS; |
| 5368 | +} |
| 5369 | + |
5352 | 5370 | } // extern "C" |
0 commit comments