blob: 937baf982601163a68e0bd66955a16104fc219af (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
|
//
// Copyright 2019 Ettus Research, a National Instruments Brand
//
// SPDX-License-Identifier: GPL-3.0-or-later
//
#ifndef INCLUDED_LIBUHD_RFNOC_RX_FLOW_CTRL_STATE_HPP
#define INCLUDED_LIBUHD_RFNOC_RX_FLOW_CTRL_STATE_HPP
#include <uhd/utils/log.hpp>
#include <uhdlib/rfnoc/rfnoc_common.hpp>
namespace uhd { namespace rfnoc {
//! Class to manage rx flow control state
class rx_flow_ctrl_state
{
public:
//! Constructor
rx_flow_ctrl_state(const rfnoc::sep_id_pair_t epids) : _epids(epids) {}
//! Initialize frequency parameters
void initialize(const stream_buff_params_t fc_freq)
{
_fc_freq = fc_freq;
}
//! Resynchronize with transfer counts from the sender
void resynchronize(const stream_buff_params_t counts)
{
if (_recv_counts.bytes != counts.bytes
|| _recv_counts.packets != counts.packets) {
// If there is a discrepancy between the amount of data sent by
// the device and received by the transport, adjust the counts
// of data received and transferred to include the dropped data.
auto bytes_dropped = counts.bytes - _recv_counts.bytes;
auto pkts_dropped = counts.packets - _recv_counts.packets;
_xfer_counts.bytes += bytes_dropped;
_xfer_counts.packets += pkts_dropped;
UHD_LOGGER_DEBUG("rx_flow_ctrl_state")
<< "oh noes: bytes_sent=" << counts.bytes
<< " bytes_received=" << _recv_counts.bytes
<< " pkts_sent=" << counts.packets
<< " pkts_received=" << _recv_counts.packets
<< " src_epid=" << _epids.first << " dst_epid=" << _epids.second
<< std::endl;
_recv_counts = counts;
}
}
//! Reset the transfer counts (happens during init)
void reset_counts()
{
UHD_LOGGER_TRACE("rx_flow_ctrl_state")
<< "Resetting transfer counts" << std::endl;
_recv_counts = {0, 0};
_xfer_counts = {0, 0};
}
//! Update state when data is received
void data_received(const size_t bytes)
{
_recv_counts.bytes += bytes;
_recv_counts.packets++;
}
//! Update state when transfer is complete (buffer space freed)
void xfer_done(const size_t bytes)
{
_xfer_counts.bytes += bytes;
_xfer_counts.packets++;
}
//! Returns whether a flow control response is needed
bool fc_resp_due() const
{
stream_buff_params_t accum_counts = {
_xfer_counts.bytes - _last_fc_resp_counts.bytes,
_xfer_counts.packets - _last_fc_resp_counts.packets};
return accum_counts.bytes >= _fc_freq.bytes
|| accum_counts.packets >= _fc_freq.packets;
}
//! Update state after flow control response was sent
void fc_resp_sent()
{
_last_fc_resp_counts = _xfer_counts;
}
//! Returns counts for completed transfers
stream_buff_params_t get_xfer_counts() const
{
return _xfer_counts;
}
//! Returns counts for completed transfers
stream_buff_params_t get_recv_counts() const
{
return _recv_counts;
}
//! Returns configured flow control frequency
stream_buff_params_t get_fc_freq() const
{
return _fc_freq;
}
private:
// Counts for data received, including any data still in use
stream_buff_params_t _recv_counts{0, 0};
// Counts for data read and whose buffer space is ok to reuse
stream_buff_params_t _xfer_counts{0, 0};
// Counts sent in last flow control response
stream_buff_params_t _last_fc_resp_counts{0, 0};
// Frequency of flow control responses
stream_buff_params_t _fc_freq{0, 0};
// Endpoint ID for log messages
const sep_id_pair_t _epids;
};
}} // namespace uhd::rfnoc
#endif /* INCLUDED_LIBUHD_RFNOC_RX_FLOW_CTRL_STATE_HPP */
|