Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 0 additions & 5 deletions score/launch_manager/daemon/src/common/concurrency/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,6 @@ cc_library(
cc_test(
name = "mpmc_concurrent_queue_test",
srcs = ["mpmc_concurrent_queue_test.cpp"],
# TODO(eclipse-score/lifecycle#241): UBSan reports a misaligned reference while this
# test fixture is constructed on ASan's fake stack; the queue itself uses
# 64-byte-aligned members, so the report is a fake-stack alignment false
# positive rather than a queue bug.
tags = ["no-asan"],
visibility = ["//tests:__subpackages__"],
deps = [
":mpmc_concurrent_queue",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -273,22 +273,36 @@ class MPMCConcurrentQueue
return score::cpp::blank{};
}

/// @brief Helper type to align members to the cache lines.
/// @details Using padding rather than alignas(CacheLineSize) so that
/// ASan's fake stack doesn't cause UBSan misalignment.
template <class Atomic>
struct CacheLinePaddedAtomic : public std::atomic<Atomic>
{
static_assert(sizeof(std::atomic<Atomic>) < CacheLineSize,
"atomic<Atomic> is too large to pad to one cache line");
using std::atomic<Atomic>::atomic;

private:
char _pad[CacheLineSize - sizeof(std::atomic<Atomic>)]{};
};

/// @brief Underlying storage.
std::array<Slot, Capacity> m_slots;

/// @brief The front of the queue; claimed by consumers via fetch_add in pop.
/// @details Aligned so that m_head and m_tail do not share a cache line.
alignas(CacheLineSize) std::atomic<std::size_t> m_head{0};
CacheLinePaddedAtomic<std::size_t> m_head{0};

/// @brief The back of the queue; claimed by producers via fetch_add in push_impl.
/// @details Aligned so that m_head and m_tail do not share a cache line.
alignas(CacheLineSize) std::atomic<std::size_t> m_tail{0};
CacheLinePaddedAtomic<std::size_t> m_tail{0};

/// @brief Set to true by stop(); causes push() to return false and pop() to
/// return std::nullopt instead of blocking.
/// @details Aligned on its own cache line so that the single stop() write
/// does not cause false sharing with m_tail updates in push_impl().
alignas(CacheLineSize) std::atomic<bool> m_stopped{false};
CacheLinePaddedAtomic<bool> m_stopped{false};

/// @brief Counts items currently in the queue; consumers block on this when
/// the queue is empty.
Expand Down
Loading