Skip to content

Commit e4dca9c

Browse files
Fixing asan error
1 parent eae594c commit e4dca9c

2 files changed

Lines changed: 17 additions & 8 deletions

File tree

score/launch_manager/daemon/src/common/concurrency/BUILD

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -49,11 +49,6 @@ cc_library(
4949
cc_test(
5050
name = "mpmc_concurrent_queue_test",
5151
srcs = ["mpmc_concurrent_queue_test.cpp"],
52-
# TODO(eclipse-score/lifecycle#241): UBSan reports a misaligned reference while this
53-
# test fixture is constructed on ASan's fake stack; the queue itself uses
54-
# 64-byte-aligned members, so the report is a fake-stack alignment false
55-
# positive rather than a queue bug.
56-
tags = ["no-asan"],
5752
visibility = ["//tests:__subpackages__"],
5853
deps = [
5954
":mpmc_concurrent_queue",

score/launch_manager/daemon/src/common/concurrency/mpmc_concurrent_queue.hpp

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -273,22 +273,36 @@ class MPMCConcurrentQueue
273273
return score::cpp::blank{};
274274
}
275275

276+
/// @brief Helper type to align members to the cache lines.
277+
/// @details Using padding rather than alignas(CacheLineSize) so that
278+
/// ASan's fake stack doesn't cause UBSan misalignment.
279+
template <class Atomic>
280+
struct CacheLinePaddedAtomic : public std::atomic<Atomic>
281+
{
282+
static_assert(sizeof(std::atomic<Atomic>) < CacheLineSize,
283+
"atomic<Atomic> is too large to pad to one cache line");
284+
using std::atomic<Atomic>::atomic;
285+
286+
private:
287+
char _pad[CacheLineSize - sizeof(std::atomic<Atomic>)]{};
288+
};
289+
276290
/// @brief Underlying storage.
277291
std::array<Slot, Capacity> m_slots;
278292

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

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

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

293307
/// @brief Counts items currently in the queue; consumers block on this when
294308
/// the queue is empty.

0 commit comments

Comments
 (0)