From b16fa2e7111dc4dc1d9d987bd5dcbf89c82b9ee8 Mon Sep 17 00:00:00 2001 From: Keno Fischer Date: Sun, 29 Dec 2019 15:08:13 -0500 Subject: [PATCH 1/2] win32: Don't run cleanup if we're about to exit anyway If the process is about to exit, there's no point trying to do a bunch of work to clean up resources. The kernel will release them much more efficiently when the process exits at the end of this function. --- exports/dllinit.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/exports/dllinit.c b/exports/dllinit.c index 4a05c0e146..88f9af6583 100644 --- a/exports/dllinit.c +++ b/exports/dllinit.c @@ -50,7 +50,10 @@ BOOL APIENTRY DllMain(HINSTANCE hInst, DWORD reason, LPVOID reserved) { gotoblas_init(); break; case DLL_PROCESS_DETACH: - gotoblas_quit(); + // If the process is about to exit, don't bother releasing any resources + // The kernel is much better at bulk releasing then. + if (!reserved) + gotoblas_quit(); break; case DLL_THREAD_ATTACH: break; From b89aef2f3215e7994c0db3f2a3543c7bfc8d70b6 Mon Sep 17 00:00:00 2001 From: Keno Fischer Date: Sun, 29 Dec 2019 15:09:21 -0500 Subject: [PATCH 2/2] win32: Properly wait unil the thread finishes in dll unload Without this we run into a problem. After 50ms we forcably kill the pool thread. However, if the pool thread currently holds the allocation lock, but doesn't get scheduled within 50ms, said lock will never be released causing an infinite deadlock and preventing the DLL from releasing. Further, in the unload scenario (as opposed to process exit), we may actually want to let the thread pool finish in case it's working on finishing an operation on another thread (since the user may be expecting the answer). --- driver/others/blas_server_win32.c | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/driver/others/blas_server_win32.c b/driver/others/blas_server_win32.c index 5ecc4428b7..3bb70b4291 100644 --- a/driver/others/blas_server_win32.c +++ b/driver/others/blas_server_win32.c @@ -462,14 +462,7 @@ int BLASFUNC(blas_thread_shutdown)(void){ for(i = 0; i < blas_num_threads - 1; i++){ // Could also just use WaitForMultipleObjects - DWORD wait_thread_value = WaitForSingleObject(blas_threads[i], 50); - -#ifndef OS_WINDOWSSTORE - // TerminateThread is only available with WINAPI_DESKTOP and WINAPI_SYSTEM not WINAPI_APP in UWP - if (WAIT_OBJECT_0 != wait_thread_value) { - TerminateThread(blas_threads[i],0); - } -#endif + DWORD wait_thread_value = WaitForSingleObject(blas_threads[i], INFINITE); CloseHandle(blas_threads[i]); }