| 154 | |
| 155 | template <typename U> |
| 156 | [[nodiscard]] auto enqueue_impl(U&& item) noexcept -> bool { |
| 157 | size_t pos; |
| 158 | Cell* cell; |
| 159 | size_t seq; |
| 160 | |
| 161 | pos = head_.load(std::memory_order_relaxed); |
| 162 | |
| 163 | for (;;) { |
| 164 | cell = &buffer_[pos & (Capacity - 1)]; |
| 165 | seq = cell->sequence.load(std::memory_order_acquire); |
| 166 | intptr_t diff = static_cast<intptr_t>(seq) - static_cast<intptr_t>(pos); |
| 167 | |
| 168 | if (diff == 0) { |
| 169 | if (head_.compare_exchange_weak(pos, pos + 1, |
| 170 | std::memory_order_relaxed)) { |
| 171 | cell->data = std::forward<U>(item); |
| 172 | cell->sequence.store(pos + 1, std::memory_order_release); |
| 173 | return true; |
| 174 | } |
| 175 | } else if (diff < 0) { |
| 176 | return false; |
| 177 | } else { |
| 178 | pos = head_.load(std::memory_order_relaxed); |
| 179 | } |
| 180 | } |
| 181 | } |
| 182 | |
| 183 | // Cache line padding to avoid false sharing |
| 184 | static constexpr size_t kCacheLineSize = 64; |
nothing calls this directly
no outgoing calls
no test coverage detected