2 // Copyright (c) 2020 Fraunhofer Institute for Applied Information Technology (FIT)
3 // Network Research Group (NET)
4 // Schloss Birlinghoven, 53754 Sankt Augustin, GERMANY
5 // Contact: support@wiback.org
7 // This file is part of the SENF code tree.
8 // It is licensed under the 3-clause BSD License (aka New BSD License).
9 // See LICENSE.txt in the top level directory for details or visit
10 // https://opensource.org/licenses/BSD-3-Clause
14 #include <senf/Utils/senflikely.hh>
16 #define prefix_ inline
17 ///////////////////////////////cci.p///////////////////////////////////////
20 ///////////////////////////////////////////////////////////////////////////
21 // senf::SequenceNumberStatistics
23 prefix_ senf::SequenceNumberStatistics::SequenceNumberStatistics(std::uint8_t bits, std::int32_t maxLate)
24 : DifferenceSigned(bits),
30 prefix_ void senf::SequenceNumberStatistics::reset()
36 firstUpdateAfterReset_ = true;
39 prefix_ void senf::SequenceNumberStatistics::clear()
42 goodBytesTotal += goodBytes;
43 good = goodBytes = duplicate = late = lost = lostLate = lateMax = 0;
47 prefix_ std::int32_t senf::SequenceNumberStatistics::maxLate()
53 prefix_ void senf::SequenceNumberStatistics::countGood(std::uint32_t payloadSize)
56 goodBytes += payloadSize;
59 prefix_ bool senf::SequenceNumberStatistics::update(std::uint32_t seqNo, std::uint32_t payloadSize)
61 if (SENF_UNLIKELY(firstUpdateAfterReset_)) {
62 firstUpdateAfterReset_ = false;
63 countGood(payloadSize);
68 auto diff (difference(seqNo, last_));
70 if (SENF_LIKELY(diff == 1)) {
72 countGood(payloadSize);
81 // late frame(s) => reordering
82 if (diff <= -maxLate_) {
83 // resync to next expected SeqNo
85 countGood(payloadSize);
89 // we are tolerant to reordering here. So, let's account for it, ...
91 lateMax = std::max(lateMax, std::uint32_t(-diff));
92 if (SENF_LIKELY(lost > 0)) {
93 // we counted this 'late' frame as lost before, so let's reduce the lost count here
95 // count 'recovered' frames
97 countGood(payloadSize);
99 // ... but not suggest to drop the frame
105 countGood(payloadSize);
110 // essentially, we only indidate 'duplicates' to be dropped
114 prefix_ void senf::SequenceNumberStatistics::dump(std::ostream & os, senf::ClockService::clock_type const & period)
117 os << "good " << good << ", goodBytes " << goodBytes;
119 os << ", good/s " << ((std::uint64_t(good) * 1000) / senf::ClockService::in_milliseconds(period));
120 os << ", goodBytes/s " << ((std::uint64_t(goodBytes) * 1000) / senf::ClockService::in_milliseconds(period));
122 os << ", duplicate " << duplicate << ", late " << late << ", lost " << lost;
123 os << ", resyncs " << resyncs;
127 ///////////////////////////////////////////////////////////////////////////
128 // senf::TimestampStatistics
130 prefix_ senf::TimestampStatistics::TimestampStatistics(std::uint8_t bits)
131 : DifferenceSigned(bits)
136 prefix_ void senf::TimestampStatistics::reset()
140 firstUpdateAfterReset_ = true;
143 prefix_ void senf::TimestampStatistics::clear()
150 prefix_ void senf::TimestampStatistics::update(std::uint32_t txTStamp, std::uint32_t rxTStamp, bool updateDelay)
152 auto diff (difference(rxTStamp, txTStamp));
154 // first packet seen => establish the typical delay
155 if (SENF_UNLIKELY(firstUpdateAfterReset_)) {
156 firstUpdateAfterReset_ = false;
160 pdv.accumulate(unsigned(abs(diff - lastPD_)));
164 delay.accumulate(diff);
169 ///////////////////////////////cci.e///////////////////////////////////////