diff --git a/opencl/test/unit_test/mt_tests/memory_manager/CMakeLists.txt b/opencl/test/unit_test/mt_tests/memory_manager/CMakeLists.txt index b39d83748c..d6f2e6b236 100644 --- a/opencl/test/unit_test/mt_tests/memory_manager/CMakeLists.txt +++ b/opencl/test/unit_test/mt_tests/memory_manager/CMakeLists.txt @@ -1,5 +1,5 @@ # -# Copyright (C) 2018-2022 Intel Corporation +# Copyright (C) 2018-2025 Intel Corporation # # SPDX-License-Identifier: MIT # @@ -8,5 +8,6 @@ set(IGDRCL_SRCS_mt_tests_memory_manager ${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt ${CMAKE_CURRENT_SOURCE_DIR}/deferred_deleter_clear_queue_mt_tests.cpp ${CMAKE_CURRENT_SOURCE_DIR}/deferred_deleter_mt_tests.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/unified_memory_reuse_cleaner_tests_mt.cpp ) target_sources(igdrcl_mt_tests PRIVATE ${IGDRCL_SRCS_mt_tests_memory_manager}) diff --git a/opencl/test/unit_test/mt_tests/memory_manager/unified_memory_reuse_cleaner_tests_mt.cpp b/opencl/test/unit_test/mt_tests/memory_manager/unified_memory_reuse_cleaner_tests_mt.cpp new file mode 100644 index 0000000000..a545fa063f --- /dev/null +++ b/opencl/test/unit_test/mt_tests/memory_manager/unified_memory_reuse_cleaner_tests_mt.cpp @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2025 Intel Corporation + * + * SPDX-License-Identifier: MIT + * + */ + +#include "shared/test/common/mocks/mock_usm_memory_reuse_cleaner.h" +#include "shared/test/common/test_macros/test.h" +namespace NEO { + +TEST(UnifiedMemoryReuseCleanerTestsMt, givenUnifiedMemoryReuseCleanerWhenSleepExpiredThenTrimOldInCachesIsCalled) { + MockUnifiedMemoryReuseCleaner cleaner; + cleaner.callBaseStartThread = true; + cleaner.callBaseTrimOldInCaches = false; + EXPECT_EQ(nullptr, cleaner.unifiedMemoryReuseCleanerThread); + cleaner.startThread(); + EXPECT_NE(nullptr, cleaner.unifiedMemoryReuseCleanerThread); + EXPECT_FALSE(cleaner.runCleaning.load()); + EXPECT_TRUE(cleaner.keepCleaning.load()); + + EXPECT_FALSE(cleaner.trimOldInCachesCalled); + cleaner.registerSvmAllocationCache(nullptr); + EXPECT_TRUE(cleaner.runCleaning.load()); + + while (false == cleaner.trimOldInCachesCalled) { + std::this_thread::yield(); + } + cleaner.stopThread(); + EXPECT_EQ(nullptr, cleaner.unifiedMemoryReuseCleanerThread); + EXPECT_FALSE(cleaner.runCleaning.load()); + EXPECT_FALSE(cleaner.keepCleaning.load()); +} + +TEST(UnifiedMemoryReuseCleanerTestsMt, givenUnifiedMemoryReuseCleanerWithNotStartedCleaningWhenShuttingDownThenNoHang) { + MockUnifiedMemoryReuseCleaner cleaner; + cleaner.callBaseStartThread = true; + cleaner.callBaseTrimOldInCaches = false; + cleaner.startThread(); + EXPECT_NE(nullptr, cleaner.unifiedMemoryReuseCleanerThread); + + std::this_thread::yield(); + cleaner.stopThread(); +} + +} // namespace NEO \ No newline at end of file diff --git a/shared/source/memory_manager/unified_memory_reuse_cleaner.h b/shared/source/memory_manager/unified_memory_reuse_cleaner.h index 619160d8ef..37c15c3aed 100644 --- a/shared/source/memory_manager/unified_memory_reuse_cleaner.h +++ b/shared/source/memory_manager/unified_memory_reuse_cleaner.h @@ -35,7 +35,7 @@ class UnifiedMemoryReuseCleaner { protected: void startCleaning() { runCleaning.store(true); }; static void *cleanUnifiedMemoryReuse(void *self); - void trimOldInCaches(); + MOCKABLE_VIRTUAL void trimOldInCaches(); std::unique_ptr unifiedMemoryReuseCleanerThread; std::vector svmAllocationCaches; diff --git a/shared/test/common/mocks/mock_usm_memory_reuse_cleaner.h b/shared/test/common/mocks/mock_usm_memory_reuse_cleaner.h index 0b71766b8b..2e646d05f6 100644 --- a/shared/test/common/mocks/mock_usm_memory_reuse_cleaner.h +++ b/shared/test/common/mocks/mock_usm_memory_reuse_cleaner.h @@ -10,8 +10,24 @@ namespace NEO { struct MockUnifiedMemoryReuseCleaner : public UnifiedMemoryReuseCleaner { public: + using UnifiedMemoryReuseCleaner::keepCleaning; + using UnifiedMemoryReuseCleaner::runCleaning; using UnifiedMemoryReuseCleaner::svmAllocationCaches; - using UnifiedMemoryReuseCleaner::trimOldInCaches; - void startThread() override{}; + using UnifiedMemoryReuseCleaner::unifiedMemoryReuseCleanerThread; + + void trimOldInCaches() override { + trimOldInCachesCalled = true; + if (callBaseTrimOldInCaches) { + UnifiedMemoryReuseCleaner::trimOldInCaches(); + } + } + void startThread() override { + if (callBaseStartThread) { + UnifiedMemoryReuseCleaner::startThread(); + } + }; + bool trimOldInCachesCalled = false; + bool callBaseStartThread = false; + bool callBaseTrimOldInCaches = true; }; } // namespace NEO \ No newline at end of file