From e386efe2e8a662f7efd64034cb0acaa2a4a16118 Mon Sep 17 00:00:00 2001 From: Sergey Kanaev Date: Thu, 18 Nov 2021 11:51:45 +0300 Subject: [PATCH 1/6] [SYCL] Only call shutdown when DLL is being unloaded, not when process is terminating Signed-off-by: Sergey Kanaev --- sycl/source/detail/global_handler.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sycl/source/detail/global_handler.cpp b/sycl/source/detail/global_handler.cpp index c4cb4394c39ab..3cee0563c6e63 100644 --- a/sycl/source/detail/global_handler.cpp +++ b/sycl/source/detail/global_handler.cpp @@ -150,7 +150,8 @@ extern "C" __SYCL_EXPORT BOOL WINAPI DllMain(HINSTANCE hinstDLL, // Perform actions based on the reason for calling. switch (fdwReason) { case DLL_PROCESS_DETACH: - shutdown(); + if (!lpReserved) + shutdown(); break; case DLL_PROCESS_ATTACH: case DLL_THREAD_ATTACH: From d3ce27904c6376e11f971bca1499afb0b2af5669 Mon Sep 17 00:00:00 2001 From: Sergey Kanaev Date: Tue, 23 Nov 2021 17:35:40 +0300 Subject: [PATCH 2/6] Add unit-test Signed-off-by: Sergey Kanaev --- sycl/unittests/CMakeLists.txt | 1 + sycl/unittests/windows/CMakeLists.txt | 4 ++ sycl/unittests/windows/dllmain.cpp | 62 +++++++++++++++++++++++++++ 3 files changed, 67 insertions(+) create mode 100644 sycl/unittests/windows/CMakeLists.txt create mode 100644 sycl/unittests/windows/dllmain.cpp diff --git a/sycl/unittests/CMakeLists.txt b/sycl/unittests/CMakeLists.txt index 3efd330c112c5..163f139c42737 100644 --- a/sycl/unittests/CMakeLists.txt +++ b/sycl/unittests/CMakeLists.txt @@ -24,3 +24,4 @@ add_subdirectory(thread_safety) add_subdirectory(program_manager) add_subdirectory(assert) add_subdirectory(Extensions) +add_subdirectory(windows) diff --git a/sycl/unittests/windows/CMakeLists.txt b/sycl/unittests/windows/CMakeLists.txt new file mode 100644 index 0000000000000..6143d5de55045 --- /dev/null +++ b/sycl/unittests/windows/CMakeLists.txt @@ -0,0 +1,4 @@ +add_sycl_unittest(WindowsDllMainTest OBJECT + dllmain.cpp +) + diff --git a/sycl/unittests/windows/dllmain.cpp b/sycl/unittests/windows/dllmain.cpp new file mode 100644 index 0000000000000..83b4b415731a0 --- /dev/null +++ b/sycl/unittests/windows/dllmain.cpp @@ -0,0 +1,62 @@ +//==----- dllmain.cpp --- verify behaviour of lib on process termination ---==// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +/* + * This test calls DllMain on Windows. This means, the process performs actions + * which are required for library unload. That said, the test requires to be a + * distinct binary executable. + */ + +#include +#include +#include +#include + +#include + +#ifdef _WIN32 +#include +#endif + +static std::atomic TearDownCalls{0}; + +pi_result redefinedTearDown(void *PluginParameter) { + ++TearDownCalls; +} + +TEST(Windows, DllMainCall) { + { + sycl::platform Plt{sycl::default_selector()}; + if (Plt.is_host()) { + printf("Test is not supported on host, skipping\n"); + return; + } + + sycl::unittest::PiMock Mock{Plt}; + setupDefaultMockAPIs(Mock); + + Mock.redefine(redefinedTearDown); + +#ifdef _WIN32 + // Teardown calls are only expected on sycl.dll library unload, not when + // process gets terminated. + // The first call to DllMain is to simulate library unload. The second one + // is to simulate process termination + DllMain((HINSTANCE)0, DLL_PROCESS_DETACH, (LPVOID)NULL); + + int TearDownCallsDone = TearDownCalls.load(); + + EXPECT_NE(TearDownCallsDone, 0); + + DllMain((HINSTANCE)0, DLL_PROCESS_DETACH, (LPVOID)0x01); + + EXPECT_EQ(TearDownCalls.load(), TearDownCallsDone); +#endif + } +} + From 9832e6ecfa459e9ce90d7df175177b4b81af3792 Mon Sep 17 00:00:00 2001 From: Sergey Kanaev Date: Thu, 2 Dec 2021 15:40:16 +0300 Subject: [PATCH 3/6] Fixes in the test along with some outputs for verbosity Signed-off-by: Sergey Kanaev --- sycl/unittests/windows/dllmain.cpp | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/sycl/unittests/windows/dllmain.cpp b/sycl/unittests/windows/dllmain.cpp index 83b4b415731a0..498ab1be5f228 100644 --- a/sycl/unittests/windows/dllmain.cpp +++ b/sycl/unittests/windows/dllmain.cpp @@ -23,10 +23,18 @@ #include #endif + +extern "C" BOOL WINAPI DllMain(HINSTANCE hinstDLL, + DWORD fdwReason, + LPVOID lpReserved); + static std::atomic TearDownCalls{0}; pi_result redefinedTearDown(void *PluginParameter) { + fprintf(stderr, "intercepted tear down\n"); ++TearDownCalls; + + return PI_SUCCESS; } TEST(Windows, DllMainCall) { @@ -36,23 +44,23 @@ TEST(Windows, DllMainCall) { printf("Test is not supported on host, skipping\n"); return; } - sycl::unittest::PiMock Mock{Plt}; setupDefaultMockAPIs(Mock); - - Mock.redefine(redefinedTearDown); + Mock.redefine(redefinedTearDown); #ifdef _WIN32 // Teardown calls are only expected on sycl.dll library unload, not when // process gets terminated. // The first call to DllMain is to simulate library unload. The second one // is to simulate process termination + fprintf(stderr, "Call DllMain for the first time\n"); DllMain((HINSTANCE)0, DLL_PROCESS_DETACH, (LPVOID)NULL); int TearDownCallsDone = TearDownCalls.load(); EXPECT_NE(TearDownCallsDone, 0); + fprintf(stderr, "Call DllMain for the second time\n"); DllMain((HINSTANCE)0, DLL_PROCESS_DETACH, (LPVOID)0x01); EXPECT_EQ(TearDownCalls.load(), TearDownCallsDone); From 93744b3bf0382207a68f3e433a678aadd9c64749 Mon Sep 17 00:00:00 2001 From: Sergey Kanaev Date: Thu, 2 Dec 2021 15:44:15 +0300 Subject: [PATCH 4/6] Make unit-test a no-op on non-windows platform Signed-off-by: Sergey Kanaev --- sycl/unittests/windows/dllmain.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/sycl/unittests/windows/dllmain.cpp b/sycl/unittests/windows/dllmain.cpp index 498ab1be5f228..37205da75a10b 100644 --- a/sycl/unittests/windows/dllmain.cpp +++ b/sycl/unittests/windows/dllmain.cpp @@ -21,8 +21,6 @@ #ifdef _WIN32 #include -#endif - extern "C" BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, @@ -36,9 +34,11 @@ pi_result redefinedTearDown(void *PluginParameter) { return PI_SUCCESS; } +#endif TEST(Windows, DllMainCall) { { +#ifdef _WIN32 sycl::platform Plt{sycl::default_selector()}; if (Plt.is_host()) { printf("Test is not supported on host, skipping\n"); @@ -48,7 +48,6 @@ TEST(Windows, DllMainCall) { setupDefaultMockAPIs(Mock); Mock.redefine(redefinedTearDown); -#ifdef _WIN32 // Teardown calls are only expected on sycl.dll library unload, not when // process gets terminated. // The first call to DllMain is to simulate library unload. The second one From 3643090bde51018043cc50383658fe7880680c0b Mon Sep 17 00:00:00 2001 From: Sergey Kanaev Date: Thu, 2 Dec 2021 15:44:49 +0300 Subject: [PATCH 5/6] Stylistic change Signed-off-by: Sergey Kanaev --- sycl/unittests/windows/dllmain.cpp | 40 ++++++++++++++---------------- 1 file changed, 19 insertions(+), 21 deletions(-) diff --git a/sycl/unittests/windows/dllmain.cpp b/sycl/unittests/windows/dllmain.cpp index 37205da75a10b..a5a6f172b99c0 100644 --- a/sycl/unittests/windows/dllmain.cpp +++ b/sycl/unittests/windows/dllmain.cpp @@ -37,33 +37,31 @@ pi_result redefinedTearDown(void *PluginParameter) { #endif TEST(Windows, DllMainCall) { - { #ifdef _WIN32 - sycl::platform Plt{sycl::default_selector()}; - if (Plt.is_host()) { - printf("Test is not supported on host, skipping\n"); - return; - } - sycl::unittest::PiMock Mock{Plt}; - setupDefaultMockAPIs(Mock); - Mock.redefine(redefinedTearDown); + sycl::platform Plt{sycl::default_selector()}; + if (Plt.is_host()) { + printf("Test is not supported on host, skipping\n"); + return; + } + sycl::unittest::PiMock Mock{Plt}; + setupDefaultMockAPIs(Mock); + Mock.redefine(redefinedTearDown); - // Teardown calls are only expected on sycl.dll library unload, not when - // process gets terminated. - // The first call to DllMain is to simulate library unload. The second one - // is to simulate process termination - fprintf(stderr, "Call DllMain for the first time\n"); - DllMain((HINSTANCE)0, DLL_PROCESS_DETACH, (LPVOID)NULL); + // Teardown calls are only expected on sycl.dll library unload, not when + // process gets terminated. + // The first call to DllMain is to simulate library unload. The second one + // is to simulate process termination + fprintf(stderr, "Call DllMain for the first time\n"); + DllMain((HINSTANCE)0, DLL_PROCESS_DETACH, (LPVOID)NULL); - int TearDownCallsDone = TearDownCalls.load(); + int TearDownCallsDone = TearDownCalls.load(); - EXPECT_NE(TearDownCallsDone, 0); + EXPECT_NE(TearDownCallsDone, 0); - fprintf(stderr, "Call DllMain for the second time\n"); - DllMain((HINSTANCE)0, DLL_PROCESS_DETACH, (LPVOID)0x01); + fprintf(stderr, "Call DllMain for the second time\n"); + DllMain((HINSTANCE)0, DLL_PROCESS_DETACH, (LPVOID)0x01); - EXPECT_EQ(TearDownCalls.load(), TearDownCallsDone); + EXPECT_EQ(TearDownCalls.load(), TearDownCallsDone); #endif - } } From c183ba7484b74a52b787fd6c34ab3c99ec413e8f Mon Sep 17 00:00:00 2001 From: Sergey Kanaev Date: Thu, 2 Dec 2021 15:51:47 +0300 Subject: [PATCH 6/6] Stylistic change Signed-off-by: Sergey Kanaev --- sycl/unittests/windows/dllmain.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/sycl/unittests/windows/dllmain.cpp b/sycl/unittests/windows/dllmain.cpp index a5a6f172b99c0..0e46f0eea9483 100644 --- a/sycl/unittests/windows/dllmain.cpp +++ b/sycl/unittests/windows/dllmain.cpp @@ -22,8 +22,7 @@ #ifdef _WIN32 #include -extern "C" BOOL WINAPI DllMain(HINSTANCE hinstDLL, - DWORD fdwReason, +extern "C" BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved); static std::atomic TearDownCalls{0}; @@ -64,4 +63,3 @@ TEST(Windows, DllMainCall) { EXPECT_EQ(TearDownCalls.load(), TearDownCallsDone); #endif } -