@@ -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 ;
0 commit comments