Program Listing for File fromhost_buffer.cpp

Return to documentation for file (fromhost_buffer.cpp)

#include "fromhost_buffer.hpp"

#include <cstdint>
#include <chrono>

void FromHostBuffer::encode_and_write(uint64_t elink, const uint8_t* source, size_t size)
{
    const auto dest_offset = dma_get_write_offset();
    ERS_DEBUG(1, std::format( "encode_and_write, destination offset {:#x}", dest_offset));
    uint64_t new_dest_offset = m_encoder.encode_and_write_msg(elink, source, size, dest_offset);
    ERS_DEBUG(1, std::format( "encode_and_write, new destination offset {:#x}", new_dest_offset));
    dma_set_write_offset(new_dest_offset);
    ++m_mon.msg_counter;
    m_mon.bytes_counter += size;
}


FromHostDmaStats FromHostBuffer::get_monitoring_data()
{
    FromHostDmaStats stats = m_mon.get_increment(m_mon_prev);
    stats.dmaid = m_dmaid;
    stats.dma_free_MB = dma_get_free_MB();
    return stats;
}


void FromHostBuffer::trickle_padding(){
    constexpr static uint64_t ALIGNMENT = 4096;
    constexpr static uint64_t ELINK =  0x30; //< This is a bit of a hack. It uses a valid link-ID but an invalid e-path. FLX-2562
    constexpr static uint8_t PADDING_VALUE = 0xAA;
    const uint64_t current_offset = dma_get_write_offset();
    const uint64_t bytes_needed = (ALIGNMENT - (current_offset % ALIGNMENT)) % ALIGNMENT;

    if (bytes_needed == 0) {
        return;  // Already aligned
    }

    ERS_DEBUG(1, std::format( "The trickle configuration is not aligned to {} bytes. Padding with the required {} bytes", ALIGNMENT, bytes_needed));

    // Constants needed to calculate the final size of the padding vector
    const size_t block_size = m_encoder.get_block_size();
    const size_t header_size = m_encoder.get_header_size();
    const size_t payload_size = m_encoder.get_payload_size();

    const size_t num_full_blocks = bytes_needed / block_size;
    const size_t full_blocks_size = num_full_blocks * block_size;
    const size_t remaining_bytes = bytes_needed - full_blocks_size;

    size_t data_size = num_full_blocks * payload_size;

    // If there are remaining bytes, see if we can fit a partial block
    if (remaining_bytes > header_size) {
        // We can fit a header and some payload
        data_size += (remaining_bytes - header_size);
    }

    std::vector<uint8_t> padding(data_size, PADDING_VALUE);
    encode_and_write(ELINK, padding.data(), padding.size());
}