Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[FR] Added response time statistics #1538

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions srtcore/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -1473,6 +1473,11 @@ struct MetricOp
{
m = 0;
}

static bool is_zero(const METRIC_TYPE& m)
{
return m == 0;
}
};

template <>
Expand All @@ -1485,4 +1490,19 @@ struct MetricOp<PacketMetric>
}
};

template <>
struct MetricOp<srt::sync::steady_clock::duration>
{
typedef srt::sync::steady_clock::duration duration;
static bool is_zero(const duration& m)
{
return m == duration::zero();
}

static void Clear(duration& m)
{
m = duration::zero();
}
};

#endif
13 changes: 11 additions & 2 deletions srtcore/core.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1486,6 +1486,8 @@ void CUDT::clearData()
m_stats.traceRcvBytesUndecrypt = 0;

m_stats.sndDuration = m_stats.m_sndDurationTotal = 0;
m_stats.tdAverageResponseTime.Init();
m_stats.tdMaxResponseTime.Init();
}

// Resetting these data because this happens when agent isn't connected.
Expand Down Expand Up @@ -7448,6 +7450,11 @@ void CUDT::bstats(CBytePerfMon *perf, bool clear, bool instantaneous)
perf->msRcvBuf = 0;
}

perf->msAvgResponseTimeTotal = count_milliseconds(m_stats.tdAverageResponseTime.total);
perf->msMaxResponseTimeTotal = count_milliseconds(m_stats.tdMaxResponseTime.total);
perf->msAvgResponseTime = count_milliseconds(m_stats.tdAverageResponseTime.local);
perf->msMaxResponseTime = count_milliseconds(m_stats.tdMaxResponseTime.local);

if (clear)
{
m_stats.traceSndDrop = 0;
Expand All @@ -7474,6 +7481,8 @@ void CUDT::bstats(CBytePerfMon *perf, bool clear, bool instantaneous)
m_stats.rcvFilterLoss = 0;

m_stats.tsLastSampleTime = currtime;
m_stats.tdAverageResponseTime.Clear();
m_stats.tdMaxResponseTime.Clear();
}
}

Expand Down Expand Up @@ -8439,7 +8448,7 @@ void CUDT::processCtrl(const CPacket &ctrlpkt)
// Just heard from the peer, reset the expiration count.
m_iEXPCount = 1;
const steady_clock::time_point currtime = steady_clock::now();
m_tsLastRspTime = currtime;
calculateResponseTime(currtime);
bool using_rexmit_flag = m_bPeerRexmitFlag;

HLOGC(inlog.Debug,
Expand Down Expand Up @@ -9347,7 +9356,7 @@ int CUDT::processData(CUnit* in_unit)
// m_pRcvBuffer->addLocalTsbPdDriftSample(packet.getMsgTimeStamp());
// Just heard from the peer, reset the expiration count.
m_iEXPCount = 1;
m_tsLastRspTime = steady_clock::now();
calculateResponseTime(steady_clock::now());

const bool need_tsbpd = m_bTsbPd || m_bGroupTsbPd;

Expand Down
67 changes: 67 additions & 0 deletions srtcore/core.h
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,51 @@ enum SeqPairItems
SEQ_BEGIN = 0, SEQ_END = 1, SEQ_SIZE = 2
};

template <class METRIC_TYPE>
struct AverageMetricUsage: public MetricUsage<METRIC_TYPE>
{
using MetricUsage<METRIC_TYPE>::Clear;
using MetricUsage<METRIC_TYPE>::Init;
using MetricUsage<METRIC_TYPE>::local;
using MetricUsage<METRIC_TYPE>::total;

void Update(METRIC_TYPE value)
{
if (MetricOp<METRIC_TYPE>::is_zero(local))
local = value;
else
{
local = (local + value)/2;
}

if (MetricOp<METRIC_TYPE>::is_zero(total))
total = value;
else
{
total = (total + value)/2;
}
}
};


template <class METRIC_TYPE>
struct MaxMetricUsage: public MetricUsage<METRIC_TYPE>
{
using MetricUsage<METRIC_TYPE>::Clear;
using MetricUsage<METRIC_TYPE>::Init;
using MetricUsage<METRIC_TYPE>::local;
using MetricUsage<METRIC_TYPE>::total;

void Update(METRIC_TYPE value)
{
if (value > local)
local = value;

if (value > total)
total = value;
}
};

#if ENABLE_EXPERIMENTAL_BONDING

struct SRT_SocketOptionObject
Expand Down Expand Up @@ -1139,8 +1184,30 @@ class CUDT

int64_t sndDuration; // real time for sending
time_point sndDurationCounter; // timers to record the sending Duration

AverageMetricUsage<duration> tdAverageResponseTime;
MaxMetricUsage<duration> tdMaxResponseTime;
} m_stats;

/// This function records the passed current time as the last response time.
/// Before doing it, however, it checks if there exist any previous such time
/// and updates statistics accordingly.
void calculateResponseTime(const time_point& now)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If it records the time, then a better name could be recordResponseTime.
Otherwise this operation is unexpected: m_tsLastRspTime = now;.

{
using namespace srt::sync;

if (!is_zero(m_tsLastRspTime))
{
duration td = now - m_tsLastRspTime;
enterCS(m_StatsLock);
m_stats.tdAverageResponseTime.Update(td);
m_stats.tdMaxResponseTime.Update(td);
leaveCS(m_StatsLock);
}

m_tsLastRspTime = now;
}

public:
static const int SELF_CLOCK_INTERVAL = 64; // ACK interval for self-clocking
static const int SEND_LITE_ACK = sizeof(int32_t); // special size for ack containing only ack seq
Expand Down
4 changes: 4 additions & 0 deletions srtcore/srt.h
Original file line number Diff line number Diff line change
Expand Up @@ -403,12 +403,16 @@ struct CBytePerfMon
int64_t pktRecvUniqueTotal; // total number of packets to be received by the application
uint64_t byteSentUniqueTotal; // total number of data bytes, sent by the application
uint64_t byteRecvUniqueTotal; // total number of data bytes to be received by the application
uint32_t msAvgResponseTimeTotal;
uint32_t msMaxResponseTimeTotal;

// Local
int64_t pktSentUnique; // number of data packets sent by the application
int64_t pktRecvUnique; // number of packets to be received by the application
uint64_t byteSentUnique; // number of data bytes, sent by the application
uint64_t byteRecvUnique; // number of data bytes to be received by the application
uint32_t msAvgResponseTime;
uint32_t msMaxResponseTime;
};

////////////////////////////////////////////////////////////////////////////////
Expand Down