#ifndef THWEAVER_FABRIC_H #define THWEAVER_FABRIC_H #include #include #include #include #include #include namespace THWeaver { template class EndpointQueue { public: static constexpr size_t CLS = std::hardware_destructive_interference_size; static constexpr std::size_t QSIZE = 1 << qsize_expt; static constexpr std::size_t QSIZE_MASK = QSIZE - 1; EndpointQueue(const EndpointQueue &) = delete; EndpointQueue & operator=(const EndpointQueue &) = delete; EndpointQueue(EndpointQueue &&) = delete; EndpointQueue & operator=(EndpointQueue &&) = delete; void init() noexcept; void flush() noexcept; std::size_t size() const noexcept; bool is_empty() const noexcept; bool is_full() const noexcept; std::size_t get_head() const noexcept; std::size_t get_tail() const noexcept; EndpointQueueSendResult send(MessageType &&message) noexcept; EndpointQueueRecvResult recv(MessageType &buffer) noexcept; void recv_unsafe(MessageType &buffer, std::size_t old_head) noexcept; private: alignas(CLS) std::array buffer; alignas(CLS) std::atomic head; alignas(CLS) std::atomic tail; }; template class FanInFabric { public: using BitmapType = uint64_t; static constexpr size_t CLS = std::hardware_destructive_interference_size; static constexpr std::size_t QSIZE = 1 << qsize_expt; static constexpr std::size_t QSIZE_MASK = QSIZE - 1; static constexpr std::size_t BITMAP_SIZE = sizeof(BitmapType) * 8; static constexpr BitmapType THREAD_BITMAP_MASK = IN_THREAD_CNT == BITMAP_SIZE ? ~BitmapType(0) : (BitmapType(1) << IN_THREAD_CNT) - 1; static_assert(IN_THREAD_CNT <= BITMAP_SIZE, "Producer limit exceeded"); FanInFabric(const FanInFabric &) = delete; FanInFabric & operator=(const FanInFabric &) = delete; FanInFabric(FanInFabric &&) = delete; FanInFabric & operator=(FanInFabric &&) = delete; void init() noexcept; template void flush() noexcept; void flush_all() noexcept; template FanInFabricSendResult send(MessageType &&message) noexcept; FanInFabricRecvBitmapResult recv_bitmap_only(MessageType &buffer) noexcept; FanInFabricRecvTryResult recv_try(MessageType &buffer) noexcept; FanInFabricRecvAggrResult recv_aggr(MessageType &buffer) noexcept; void full_scan(BitmapType &bitmap) noexcept; template std::size_t size() const noexcept; template bool is_empty() const noexcept; template bool is_full() const noexcept; private: std::array, IN_THREAD_CNT> in_queues; alignas(CLS) std::atomic hint; struct alignas(CLS) DiscoveryList { std::array next; std::array prev; uint8_t first; uint8_t last; void init() noexcept; void move_first_to_last() noexcept; void move_to_last(uint8_t index) noexcept; } dl; std::size_t rotation; BitmapType rotate(BitmapType bitmap) const noexcept; }; } // namespace THWeaver #endif