.. _program_listing_file_tohost_buffer.cpp: Program Listing for File tohost_buffer.cpp ========================================== |exhale_lsh| :ref:`Return to documentation for file ` (``tohost_buffer.cpp``) .. |exhale_lsh| unicode:: U+021B0 .. UPWARDS ARROW WITH TIP LEFTWARDS .. code-block:: cpp #include "tohost_buffer.hpp" #include "log.hpp" #include ToHostBuffer::ToHostBuffer(int dmaid, std::shared_ptr d) : m_dmaid(dmaid), m_device(d), m_block_size(0), m_irq_on_data(IRQ_DATA_AVAILABLE + dmaid), m_irq_counter(0), m_size(0), m_stop_flag(false), m_has_zero_copy_reader(false), m_min_bytes_sent(0) {} std::vector> ToHostBuffer::split_elinks_of_type(elink_type_t t, size_t n) { std::vector vec = get_elinks_of_type(t); std::vector> result; size_t length = vec.size() / n; size_t remain = vec.size() % n; size_t begin = 0; size_t end = 0; for (size_t i = 0; i < std::min(n, vec.size()); ++i) { end += (remain > 0) ? (length + !!(remain--)) : length; result.push_back(std::vector(vec.begin() + begin, vec.begin() + end)); begin = end; } return result; } uint32_t ToHostBuffer::reader_register(bool zero_copy) { std::scoped_lock lock(m_mutex); uint64_t offset = (uint64_t)dma_get_read_offset(); m_bytes_read.push_back(offset); m_bytes_sent.push_back(offset); uint32_t reader_id = m_bytes_read.size() - 1; return reader_id; } //The amount of data available is computed with read blocks //also when zero-copy publishers are used. //Otherwise the "data available" signal would be always fired //at the end of the ToHostReader::read function size_t ToHostBuffer::reader_get_available_bytes(uint32_t reader_id) { uint64_t write_offset = dma_get_write_offset(); uint64_t read_offset = m_bytes_read[reader_id] % m_size; LOG_TRACE("Reader id %u, write 0x%lx read 0x%lx", reader_id, write_offset, read_offset); if (write_offset > read_offset) { return write_offset - read_offset; } else if (write_offset < read_offset) { return m_size - read_offset; } else if (dma_is_full()) { if (m_bytes_read[reader_id] == m_min_bytes_sent) { return m_size - read_offset; } } return 0; } bool ToHostBuffer::reader_is_data_available(uint32_t reader_id) { return reader_get_available_bytes(reader_id); } std::span ToHostBuffer::reader_get_available_blocks(uint32_t reader_id) { return std::span(reinterpret_cast(m_buffer->vaddr + m_bytes_read[reader_id] % m_size), reader_get_available_bytes(reader_id)/sizeof(Block)); } void ToHostBuffer::reader_advance_read_ptr(uint32_t reader_id, uint32_t read_bytes, uint32_t sent_bytes) { std::scoped_lock lock(m_mutex); auto last_bytes_sent = m_bytes_sent[reader_id]; m_bytes_read[reader_id] += read_bytes; m_bytes_sent[reader_id] += sent_bytes; if (m_min_bytes_sent == last_bytes_sent) { m_min_bytes_sent = *std::ranges::min_element(m_bytes_sent); if (m_min_bytes_sent != last_bytes_sent) { dma_set_read_ptr_paddr(m_buffer->paddr + (m_min_bytes_sent % m_size)); } } } uint32_t ToHostBuffer::dma_get_free_MB() { auto to_read = dma_bytes_available(); return (m_buffer->size - to_read)/1024/1024; }