Skip to content

Commit 62a742b

Browse files
committed
Add ability to Register a TeardownCallback to notify release of L0 resources
Signed-off-by: Neil R. Spruit <neil.r.spruit@intel.com>
1 parent 37f2501 commit 62a742b

4 files changed

Lines changed: 97 additions & 3 deletions

File tree

include/loader/ze_loader.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,20 @@ zelEnableTracingLayer();
9494
ZE_DLLEXPORT bool ZE_APICALL
9595
zelCheckIsLoaderInTearDown();
9696

97+
///////////////////////////////////////////////////////////////////////////////
98+
/// @brief Exported function for registering a callback to indicate teardown.
99+
/// @details The callback function will be invoked when the loader is in teardown.
100+
///
101+
typedef void (*zel_loader_teardown_callback_t)();
102+
typedef void (*zel_application_teardown_callback_t)(uint32_t index);
103+
104+
ZE_DLLEXPORT ze_result_t ZE_APICALL
105+
zelRegisterTeardownCallback(
106+
zel_loader_teardown_callback_t application_callback, // [in] Pointer to the user's application callback function
107+
zel_application_teardown_callback_t *loader_callback, // [out] Pointer to the L0 Loader's callback function
108+
uint32_t *index // [out] Index of the callback function
109+
);
110+
97111
///////////////////////////////////////////////////////////////////////////////
98112
/// @brief Exported function for Disabling the Tracing Layer During Runtime.
99113
///

source/lib/windows/lib_init.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ namespace ze_lib
1616
#ifndef DYNAMIC_LOAD_LOADER
1717
extern "C" BOOL APIENTRY DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) {
1818
if (fdwReason == DLL_PROCESS_DETACH) {
19+
printf("DLL_PROCESS_DETACH\n");
20+
ze_lib::context->teardownCallbacks.clear();
1921
delete context;
2022
delete loader::context;
2123
} else if (fdwReason == DLL_PROCESS_ATTACH) {

source/lib/ze_lib.cpp

Lines changed: 70 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,18 @@ namespace ze_lib
2727
}
2828
}
2929
bool delayContextDestruction = false;
30+
bool loaderTeardownCallbackReceived = false;
31+
void staticLoaderTeardownCallback() {
32+
printf("ze_lib Static Teardown Callback\n");
33+
loaderTeardownCallbackReceived = true;
34+
}
3035
#endif
36+
void applicationTeardownCallback(uint32_t index) {
37+
printf("ze_lib Application Teardown Callback %d\n", index);
38+
if (ze_lib::context->teardownCallbacks.find(index) != ze_lib::context->teardownCallbacks.end()) {
39+
ze_lib::context->teardownCallbacks.erase(index);
40+
}
41+
}
3142
bool destruction = false;
3243

3344
///////////////////////////////////////////////////////////////////////////////
@@ -39,10 +50,22 @@ namespace ze_lib
3950
///////////////////////////////////////////////////////////////////////////////
4051
__zedlllocal context_t::~context_t()
4152
{
53+
if (debugTraceEnabled) {
54+
debug_trace_message("ze_lib Context Destructor", "");
55+
}
4256
#ifdef DYNAMIC_LOAD_LOADER
57+
if (!loaderTeardownCallbackReceived) {
58+
loaderTeardownCallback(loaderTeardownCallbackIndex);
59+
}
4360
if (loader) {
4461
FREE_DRIVER_LIBRARY( loader );
4562
}
63+
#else
64+
// Call the teardown callbacks
65+
for (auto &callback : teardownCallbacks) {
66+
callback.second();
67+
}
68+
teardownCallbacks.clear();
4669
#endif
4770
ze_lib::destruction = true;
4871
};
@@ -343,9 +366,19 @@ namespace ze_lib
343366
isInitialized = true;
344367
}
345368
#ifdef DYNAMIC_LOAD_LOADER
346-
if (!delayContextDestruction) {
347-
std::atexit(context_at_exit_destructor);
348-
}
369+
std::call_once(ze_lib::context->initTeardownCallbacksOnce, [this]() {
370+
if (!delayContextDestruction) {
371+
std::atexit(context_at_exit_destructor);
372+
}
373+
// Get the function pointer for zelRegisterTeardownCallback from the loader
374+
typedef ze_result_t (ZE_APICALL *zelRegisterTeardownCallback_t)(
375+
zel_loader_teardown_callback_t,
376+
zel_application_teardown_callback_t*,
377+
uint32_t*);
378+
auto pfnZelRegisterTeardownCallback = reinterpret_cast<zelRegisterTeardownCallback_t>(
379+
GET_FUNCTION_PTR(loader, "zelRegisterTeardownCallback"));
380+
pfnZelRegisterTeardownCallback(staticLoaderTeardownCallback, &loaderTeardownCallback, &loaderTeardownCallbackIndex);
381+
});
349382
#endif
350383
return result;
351384
}
@@ -397,6 +430,13 @@ zelSetDriverTeardown()
397430
{
398431
ze_result_t result = ZE_RESULT_SUCCESS;
399432
if (!ze_lib::destruction) {
433+
if (ze_lib::context) {
434+
// Call the teardown callbacks
435+
for (auto &callback : ze_lib::context->teardownCallbacks) {
436+
callback.second();
437+
}
438+
}
439+
400440
ze_lib::destruction = true;
401441
}
402442
return result;
@@ -476,6 +516,30 @@ void stabilityCheck(std::promise<int> stabilityPromise) {
476516
}
477517
#endif
478518

519+
ZE_DLLEXPORT ze_result_t ZE_APICALL
520+
zelRegisterTeardownCallback(
521+
zel_loader_teardown_callback_t application_callback, // [in] Pointer to the user's application callback function
522+
zel_application_teardown_callback_t *loader_callback, // [out] Pointer to the L0 Loader's callback function
523+
uint32_t *index // [out] Index of the callback function
524+
) {
525+
ze_result_t result = ZE_RESULT_SUCCESS;
526+
if (nullptr == application_callback) {
527+
return ZE_RESULT_ERROR_INVALID_ARGUMENT;
528+
}
529+
if (!ze_lib::context) {
530+
return ZE_RESULT_ERROR_UNINITIALIZED;
531+
}
532+
*loader_callback = ze_lib::applicationTeardownCallback;
533+
ze_lib::context->teardownCallbacksCount.fetch_add(1);
534+
*index = ze_lib::context->teardownCallbacksCount.load();
535+
ze_lib::context->teardownCallbacks.insert(std::pair<uint32_t, zel_loader_teardown_callback_t>(*index, application_callback));
536+
if (ze_lib::context->debugTraceEnabled) {
537+
std::string message = "Registered teardown callback with index: " + std::to_string(*index);
538+
ze_lib::context->debug_trace_message(message, "");
539+
}
540+
return result;
541+
}
542+
479543
/**
480544
* @brief Checks if the loader is in the process of tearing down.
481545
*
@@ -497,6 +561,9 @@ zelCheckIsLoaderInTearDown() {
497561
return true;
498562
}
499563
#if defined(DYNAMIC_LOAD_LOADER) && defined(_WIN32)
564+
if (ze_lib::loaderTeardownCallbackReceived) {
565+
return true;
566+
}
500567
std::promise<int> stabilityPromise;
501568
std::future<int> resultFuture = stabilityPromise.get_future();
502569
int result = -1;

source/lib/ze_lib.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,9 @@
2424
#include <typeinfo>
2525
#include <iostream>
2626

27+
typedef void (*zel_loader_teardown_callback_t)();
28+
typedef void (*zel_application_teardown_callback_t)(uint32_t index);
29+
2730
namespace ze_lib
2831
{
2932
///////////////////////////////////////////////////////////////////////////////
@@ -175,12 +178,20 @@ namespace ze_lib
175178
bool debugTraceEnabled = false;
176179
bool dynamicTracingSupported = true;
177180
ze_pfnDriverGet_t loaderDriverGet = nullptr;
181+
std::atomic<uint32_t> teardownCallbacksCount{0};
182+
std::map<uint32_t, zel_loader_teardown_callback_t> teardownCallbacks;
183+
#ifdef DYNAMIC_LOAD_LOADER
184+
std::once_flag initTeardownCallbacksOnce;
185+
zel_application_teardown_callback_t loaderTeardownCallback = nullptr;
186+
uint32_t loaderTeardownCallbackIndex = 0;
187+
#endif
178188
};
179189

180190
extern bool destruction;
181191
extern context_t *context;
182192
#ifdef DYNAMIC_LOAD_LOADER
183193
extern bool delayContextDestruction;
194+
extern bool loaderTeardownCallbackReceived;
184195
#endif
185196

186197
} // namespace ze_lib

0 commit comments

Comments
 (0)