LCOV - code coverage report
Current view: top level - engine/containers/spsc - queue.hpp (source / functions) Coverage Total Hit
Test: coverage.info Lines: 100.0 % 27 27
Test Date: 2026-03-11 04:45:14 Functions: 100.0 % 13 13

            Line data    Source code
       1              : #pragma once
       2              : 
       3              : #include <jage/engine/memory/cacheline_size.hpp>
       4              : #include <jage/engine/memory/cacheline_slot.hpp>
       5              : 
       6              : #include <algorithm>
       7              : #include <array>
       8              : #include <atomic>
       9              : #include <cstddef>
      10              : 
      11              : namespace jage::engine::containers::spsc {
      12              : template <class TEvent, std::size_t Capacity,
      13              :           template <class> class TAtomic = std::atomic>
      14              : class alignas(memory::cacheline_size) queue {
      15              :   alignas(memory::cacheline_size) TAtomic<std::uint64_t> head_{0UZ};
      16              :   alignas(memory::cacheline_size) TAtomic<std::uint64_t> tail_{0UZ};
      17              :   alignas(memory::cacheline_size)
      18              :       std::array<memory::cacheline_slot<TEvent>, Capacity> buffer_{};
      19              : 
      20              : public:
      21              :   using value_type = TEvent;
      22           19 :   [[nodiscard]] auto empty() const -> bool {
      23           19 :     return head_.load(std::memory_order::acquire) ==
      24           19 :            tail_.load(std::memory_order::acquire);
      25              :   }
      26              : 
      27           19 :   [[nodiscard]] auto size() const -> std::size_t {
      28           38 :     return std::min(tail_.load(std::memory_order::acquire) -
      29           19 :                         head_.load(std::memory_order::acquire),
      30           19 :                     Capacity);
      31              :   }
      32            1 :   [[nodiscard]] static constexpr auto capacity() -> std::size_t {
      33            1 :     return Capacity;
      34              :   }
      35              : 
      36           19 :   auto push(TEvent &&event) -> void {
      37           19 :     const auto tail_index = tail_.load(std::memory_order::acquire);
      38           19 :     if (auto head_index = head_.load(std::memory_order::acquire);
      39           19 :         tail_index - head_index >= Capacity) {
      40            4 :       const auto desired_head = head_index + 1UZ;
      41            4 :       while (not head_.compare_exchange_weak(head_index, desired_head,
      42              :                                              std::memory_order::release,
      43            7 :                                              std::memory_order::acquire) and
      44            3 :              head_index < desired_head) {
      45              :       }
      46              :     }
      47           19 :     buffer_[tail_index % Capacity] = std::forward<decltype(event)>(event);
      48           19 :     tail_.store(tail_index + 1, std::memory_order::release);
      49           19 :   }
      50              : 
      51           18 :   [[nodiscard]] auto front() const -> TEvent {
      52           18 :     return buffer_[head_.load(std::memory_order::acquire) % Capacity];
      53              :   }
      54              : 
      55           13 :   auto pop() -> void {
      56           13 :     if (const auto current_head = head_.load(std::memory_order::acquire);
      57           13 :         current_head == tail_.load(std::memory_order::acquire)) [[unlikely]] {
      58            1 :       return;
      59              :     } else {
      60           12 :       head_.store(current_head + 1, std::memory_order::release);
      61              :     }
      62              :   }
      63              : };
      64              : 
      65              : } // namespace jage::engine::containers::spsc
        

Generated by: LCOV version 2.0-1