diff --git a/CHANGELOG.md b/CHANGELOG.md index 26f4e9b6..694ed0fc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,7 +8,8 @@ - Added function `vmaGetMemoryWin32Handle2` offering extra parameter `VkExternalMemoryHandleTypeFlagBits handleType`. - Added `VMA_VERSION` macro with library version number (#507). - Improvements in the algorithm choosing memory type when `VMA_MEMORY_USAGE_AUTO*` is used (#520). -- Fixes for compatibility with C++20 modules on Clang 21 and GCC15 (#513, #514). +- Fixed compatibility with C++20 modules on Clang 21 and GCC15 (#513, #514). +- Fixed race condition in defragmentation (#529, #313). - Other fixes and improvements, including compatibility with various platforms and compilers, improvements in documentation, sample application, and tests. # 3.3.0 (2025-05-12) diff --git a/include/vk_mem_alloc.h b/include/vk_mem_alloc.h index 24792855..3934de34 100644 --- a/include/vk_mem_alloc.h +++ b/include/vk_mem_alloc.h @@ -12221,6 +12221,8 @@ VmaDefragmentationContext_T::VmaDefragmentationContext_T( m_BlockVectorCount = 1; m_PoolBlockVector = &info.pool->m_BlockVector; m_pBlockVectors = &m_PoolBlockVector; + + VmaMutexLockWrite lock(m_PoolBlockVector->m_Mutex, hAllocator->m_UseMutex); m_PoolBlockVector->SetIncrementalSort(false); m_PoolBlockVector->SortByFreeSize(); } @@ -12234,6 +12236,7 @@ VmaDefragmentationContext_T::VmaDefragmentationContext_T( VmaBlockVector* vector = m_pBlockVectors[i]; if (vector != VMA_NULL) { + VmaMutexLockWrite lock(vector->m_Mutex, hAllocator->m_UseMutex); vector->SetIncrementalSort(false); vector->SortByFreeSize(); } @@ -12264,6 +12267,7 @@ VmaDefragmentationContext_T::~VmaDefragmentationContext_T() { if (m_PoolBlockVector != VMA_NULL) { + VmaMutexLockWrite lock(m_PoolBlockVector->m_Mutex, m_PoolBlockVector->m_hAllocator->m_UseMutex); m_PoolBlockVector->SetIncrementalSort(true); } else @@ -12272,7 +12276,10 @@ VmaDefragmentationContext_T::~VmaDefragmentationContext_T() { VmaBlockVector* vector = m_pBlockVectors[i]; if (vector != VMA_NULL) + { + VmaMutexLockWrite lock(vector->m_Mutex, vector->m_hAllocator->m_UseMutex); vector->SetIncrementalSort(true); + } } } @@ -12370,7 +12377,11 @@ VkResult VmaDefragmentationContext_T::DefragmentPassEnd(VmaDefragmentationPassMo { case VMA_DEFRAGMENTATION_MOVE_OPERATION_COPY: { - uint8_t mapCount = move.srcAllocation->SwapBlockAllocation(vector->m_hAllocator, move.dstTmpAllocation); + uint8_t mapCount = 0; + { + VmaMutexLockWrite swapLock(vector->GetMutex(), vector->GetAllocator()->m_UseMutex); + mapCount = move.srcAllocation->SwapBlockAllocation(vector->m_hAllocator, move.dstTmpAllocation); + } if (mapCount > 0) { allocator = vector->m_hAllocator;