diff --git a/static_core/libpandabase/taskmanager/utils/sp_sc_lock_free_queue.h b/static_core/libpandabase/taskmanager/utils/sp_sc_lock_free_queue.h index 2431d03ef76e2adeba817aba2e51f531d6c350f7..d0fc86fe11cf2960ac86f77c9915f3783ea5a684 100644 --- a/static_core/libpandabase/taskmanager/utils/sp_sc_lock_free_queue.h +++ b/static_core/libpandabase/taskmanager/utils/sp_sc_lock_free_queue.h @@ -199,13 +199,15 @@ public: { static_assert(ALLOCATION_TYPE == QueueElemAllocationType::INPLACE); auto inode = static_cast(node); - TSAN_ANNOTATE_IGNORE_WRITES_BEGIN(); - // Atomic with relaxed order reason: gets correct value - auto count = inode->toDeleteCount.fetch_sub(1, std::memory_order_relaxed); + + // There is atomic because the queue is used by multiple consumers using mutex, but this function is executed concurrently + // Atomic with release order reason: we need to sychronize an unprotected access to the node content with deletion of the node + auto count = inode->toDeleteCount.fetch_sub(1, std::memory_order_release); if (count == 1) { + // Atomic with acquire order reason: need to synchronize the last fetch_sub with other fetch_sub's (see above) + inode->toDeleteCount.load(std::memory_order_acquire); DeleteQueueBigNode(inode); } - TSAN_ANNOTATE_IGNORE_WRITES_END(); } private: