1+
12/*
23 *
34 * Copyright (C) 2019-2021 Intel Corporation
@@ -27,6 +28,11 @@ namespace ze_lib
2728 }
2829 }
2930 bool delayContextDestruction = false ;
31+ std::mutex stabilityMutex;
32+ std::promise<int > stabilityPromiseResult;
33+ std::future<int > resultFutureResult;
34+ std::atomic<int > stabilityCheckThreadStarted{0 };
35+ std::thread stabilityThread;
3036 #endif
3137 bool destruction = false ;
3238
@@ -43,6 +49,14 @@ namespace ze_lib
4349 if (loader) {
4450 FREE_DRIVER_LIBRARY ( loader );
4551 }
52+ ze_lib::stabilityCheckThreadStarted = -1 ;
53+ try {
54+ if (stabilityThread.joinable ()) {
55+ stabilityThread.join ();
56+ }
57+ } catch (...) {
58+ // Ignore any exceptions from thread join
59+ }
4660#endif
4761 ze_lib::destruction = true ;
4862 };
@@ -490,18 +504,45 @@ zelCheckIsLoaderInTearDown() {
490504 return true ;
491505 }
492506 #ifdef DYNAMIC_LOAD_LOADER
493- std::promise<int > stabilityPromise;
494- std::future<int > resultFuture = stabilityPromise.get_future ();
495- int result = -1 ;
507+ static bool unstable = false ;
508+ int threadResult = -1 ;
509+ if (unstable) {
510+ return true ;
511+ }
496512 try {
497- // Launch the stability checker thread
498- std::thread stabilityThread (stabilityCheck, std::move (stabilityPromise));
499- result = resultFuture.get (); // Blocks until the result is available
500- if (ze_lib::context->debugTraceEnabled ) {
501- std::string message = " Stability checker thread completed with result: " + std::to_string (result);
502- ze_lib::context->debug_trace_message (message, " " );
503- }
504- stabilityThread.join ();
513+ // Launch the stability checker thread on the first call
514+ static std::once_flag stabilityThreadFlag;
515+ std::lock_guard<std::mutex> lock (ze_lib::stabilityMutex);
516+ ze_lib::stabilityPromiseResult = std::promise<int >();
517+ ze_lib::resultFutureResult = ze_lib::stabilityPromiseResult.get_future ();
518+ ze_lib::stabilityCheckThreadStarted = 1 ;
519+ std::call_once (stabilityThreadFlag, []() {
520+ ze_lib::stabilityThread = std::thread ([]() {
521+ while (true ) {
522+ std::promise<int > stabilityPromise;
523+ std::future<int > resultFuture = stabilityPromise.get_future ();
524+ while (ze_lib::stabilityCheckThreadStarted == 0 ) {
525+ std::this_thread::sleep_for (std::chrono::milliseconds (1 ));
526+ }
527+ if (ze_lib::stabilityCheckThreadStarted == -1 ) {
528+ break ;
529+ }
530+ ze_lib::stabilityCheckThreadStarted = 0 ;
531+ stabilityCheck (std::move (stabilityPromise));
532+ int result = resultFuture.get ();
533+ if (result != ZEL_STABILITY_CHECK_RESULT_SUCCESS) {
534+ if (ze_lib::context->debugTraceEnabled ) {
535+ std::string message = " Loader stability check thread failed with result: " + std::to_string (result);
536+ ze_lib::context->debug_trace_message (message, " " );
537+ }
538+ ze_lib::stabilityPromiseResult.set_value (result);
539+ break ; // Exit the thread if stability check fails
540+ }
541+ ze_lib::stabilityPromiseResult.set_value (result);
542+ }
543+ });
544+ });
545+ threadResult = ze_lib::resultFutureResult.get ();
505546 } catch (const std::exception& e) {
506547 if (ze_lib::context->debugTraceEnabled ) {
507548 std::string message = " Exception caught in parent thread: " + std::string (e.what ());
@@ -513,11 +554,12 @@ zelCheckIsLoaderInTearDown() {
513554 ze_lib::context->debug_trace_message (message, " " );
514555 }
515556 }
516- if (result != ZEL_STABILITY_CHECK_RESULT_SUCCESS) {
557+ if (threadResult != ZEL_STABILITY_CHECK_RESULT_SUCCESS) {
517558 if (ze_lib::context->debugTraceEnabled ) {
518- std::string message = " Loader stability check failed with result: " + std::to_string (result );
559+ std::string message = " Loader stability check failed with result: " + std::to_string (threadResult );
519560 ze_lib::context->debug_trace_message (message, " " );
520561 }
562+ unstable = true ;
521563 return true ;
522564 }
523565 #endif
0 commit comments