diff --git a/shared/source/memory_manager/deferred_deleter.cpp b/shared/source/memory_manager/deferred_deleter.cpp index 0383e0fd65..b16477d383 100644 --- a/shared/source/memory_manager/deferred_deleter.cpp +++ b/shared/source/memory_manager/deferred_deleter.cpp @@ -27,8 +27,11 @@ void DeferredDeleter::stop() { doWorkInBackground = false; lock.unlock(); condition.notify_one(); - // Wait for the working job to exit - worker->join(); + worker->detach(); + // Wait for the working job to exit main loop + while (!exitedMainLoop) { + std::this_thread::yield(); + } // Delete working thread worker.reset(); } @@ -76,6 +79,7 @@ void DeferredDeleter::ensureThread() { if (worker != nullptr) { return; } + exitedMainLoop = false; worker = Thread::createFunc(run, reinterpret_cast(this)); } @@ -103,6 +107,7 @@ void *DeferredDeleter::run(void *arg) { lock.lock(); // Check whether working thread should be stopped } while (!self->shouldStop()); + self->exitedMainLoop = true; lock.unlock(); return nullptr; } diff --git a/shared/source/memory_manager/deferred_deleter.h b/shared/source/memory_manager/deferred_deleter.h index 006f57df78..5b53d5a6d1 100644 --- a/shared/source/memory_manager/deferred_deleter.h +++ b/shared/source/memory_manager/deferred_deleter.h @@ -40,6 +40,7 @@ class DeferredDeleter : NEO::NonCopyableAndNonMovableClass { static void *run(void *); + std::atomic exitedMainLoop = false; std::atomic doWorkInBackground = false; std::atomic elementsToRelease = 0; std::atomic hostptrsToRelease = 0; diff --git a/shared/source/os_interface/linux/os_thread_linux.cpp b/shared/source/os_interface/linux/os_thread_linux.cpp index f5bf4c21e7..871750aa9f 100644 --- a/shared/source/os_interface/linux/os_thread_linux.cpp +++ b/shared/source/os_interface/linux/os_thread_linux.cpp @@ -24,6 +24,10 @@ void ThreadLinux::join() { pthread_join(threadId, nullptr); } +void ThreadLinux::detach() { + pthread_detach(threadId); +} + void ThreadLinux::yield() { sched_yield(); } diff --git a/shared/source/os_interface/linux/os_thread_linux.h b/shared/source/os_interface/linux/os_thread_linux.h index b934ba4b8e..8c2551a533 100644 --- a/shared/source/os_interface/linux/os_thread_linux.h +++ b/shared/source/os_interface/linux/os_thread_linux.h @@ -16,6 +16,7 @@ class ThreadLinux : public Thread { public: ThreadLinux(pthread_t threadId); void join() override; + void detach() override; void yield() override; ~ThreadLinux() override = default; diff --git a/shared/source/os_interface/os_thread.h b/shared/source/os_interface/os_thread.h index 845a1e0aa8..9d1eee7d88 100644 --- a/shared/source/os_interface/os_thread.h +++ b/shared/source/os_interface/os_thread.h @@ -15,6 +15,7 @@ class Thread { public: static decltype(&Thread::create) createFunc; virtual void join() = 0; + virtual void detach() = 0; virtual ~Thread() = default; virtual void yield() = 0; }; diff --git a/shared/source/os_interface/windows/os_thread_win.cpp b/shared/source/os_interface/windows/os_thread_win.cpp index cf39a745bb..a858fec9e5 100644 --- a/shared/source/os_interface/windows/os_thread_win.cpp +++ b/shared/source/os_interface/windows/os_thread_win.cpp @@ -21,7 +21,12 @@ void ThreadWin::join() { thread->join(); } +void ThreadWin::detach() { + thread->detach(); +} + void ThreadWin::yield() { std::this_thread::yield(); } + } // namespace NEO diff --git a/shared/source/os_interface/windows/os_thread_win.h b/shared/source/os_interface/windows/os_thread_win.h index 2a99670e02..98ce9250ae 100644 --- a/shared/source/os_interface/windows/os_thread_win.h +++ b/shared/source/os_interface/windows/os_thread_win.h @@ -16,6 +16,7 @@ class ThreadWin : public Thread { public: ThreadWin(std::thread *thread); void join() override; + void detach() override; void yield() override; ~ThreadWin() override = default; diff --git a/shared/test/unit_test/memory_manager/deferrable_allocation_deletion_tests.cpp b/shared/test/unit_test/memory_manager/deferrable_allocation_deletion_tests.cpp index 0fa702e801..5127dba06d 100644 --- a/shared/test/unit_test/memory_manager/deferrable_allocation_deletion_tests.cpp +++ b/shared/test/unit_test/memory_manager/deferrable_allocation_deletion_tests.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018-2024 Intel Corporation + * Copyright (C) 2018-2025 Intel Corporation * * SPDX-License-Identifier: MIT * @@ -10,6 +10,7 @@ #include "shared/source/memory_manager/deferrable_allocation_deletion.h" #include "shared/source/memory_manager/deferred_deleter.h" #include "shared/source/os_interface/os_context.h" +#include "shared/test/common/helpers/memory_management.h" #include "shared/test/common/libult/ult_command_stream_receiver.h" #include "shared/test/common/mocks/mock_allocation_properties.h" #include "shared/test/common/mocks/mock_device.h" @@ -36,6 +37,7 @@ struct DeferredDeleterPublic : DeferredDeleter { struct DeferrableAllocationDeletionTest : ::testing::Test { void SetUp() override { + MemoryManagement::fastLeaksDetectionMode = MemoryManagement::LeakDetectionMode::TURN_OFF_LEAK_DETECTION; executionEnvironment = new MockExecutionEnvironment(defaultHwInfo.get(), false, 1u); executionEnvironment->incRefInternal(); memoryManager = new MockMemoryManager(*executionEnvironment);