From d8f1655a781a76f5c86b3545b181b2005e585d29 Mon Sep 17 00:00:00 2001 From: Jonathan Wakely Date: Fri, 12 Sep 2025 12:49:39 +0100 Subject: [PATCH] libstdc++: Fix memory leak in PSTL TBB backend [PR117276] Backport of upstream patch: https://github.com/uxlfoundation/oneDPL/pull/1589 libstdc++-v3/ChangeLog: PR libstdc++/117276 * include/pstl/parallel_backend_tbb.h (__func_task::finalize): Make deallocation unconditional. --- libstdc++-v3/include/pstl/parallel_backend_tbb.h | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/libstdc++-v3/include/pstl/parallel_backend_tbb.h b/libstdc++-v3/include/pstl/parallel_backend_tbb.h index bb6fa8f18e83..ff5236f39071 100644 --- a/libstdc++-v3/include/pstl/parallel_backend_tbb.h +++ b/libstdc++-v3/include/pstl/parallel_backend_tbb.h @@ -521,7 +521,7 @@ class __root_task friend class __func_task<_Func>; }; -#else // TBB_INTERFACE_VERSION <= 12000 +#else // TBB_INTERFACE_VERSION > 12000 class __task : public tbb::detail::d1::task { protected: @@ -656,10 +656,16 @@ class __func_task : public __task _PSTL_ASSERT(__parent != nullptr); _PSTL_ASSERT(__parent->_M_refcount.load(std::memory_order_relaxed) > 0); - if (--__parent->_M_refcount == 0) + + auto __refcount = --__parent->_M_refcount; + + // Placing the deallocation after the refcount decrement allows another thread to proceed with tree + // folding concurrently with this task cleanup. + __alloc.deallocate(this, *__ed); + + if (__refcount == 0) { _PSTL_ASSERT(__next == nullptr); - __alloc.deallocate(this, *__ed); return __parent; }