Adding more Jitter data points

This commit is contained in:
khorton 2017-02-13 00:42:10 -08:00
Родитель 811ccd6a32
Коммит e6428da53d
7 изменённых файлов: 3771 добавлений и 55 удалений

Просмотреть файл

@ -104,7 +104,7 @@ namespace ctsTraffic {
void PrintException(const std::exception& e) NOEXCEPT
{
}
void PrintJitterUpdate(long long _sequence_number, long long _sender_qpc, long long _sender_qpf, long long _recevier_qpc, long long _receiver_qpf) NOEXCEPT
void PrintJitterUpdate(const JitterFrameEntry& current_frame, const JitterFrameEntry& previous_frame, const JitterFrameEntry& first_frame) NOEXCEPT
{
}
void PrintErrorInfo(_In_z_ _Printf_format_string_ LPCWSTR _text, ...) NOEXCEPT

Просмотреть файл

@ -104,7 +104,7 @@ namespace ctsTraffic {
void PrintException(const std::exception& e) NOEXCEPT
{
}
void PrintJitterUpdate(long long _sequence_number, long long _sender_qpc, long long _sender_qpf, long long _recevier_qpc, long long _receiver_qpf) NOEXCEPT
void PrintJitterUpdate(const JitterFrameEntry& current_frame, const JitterFrameEntry& previous_frame, const JitterFrameEntry& first_frame) NOEXCEPT
{
}
void PrintErrorInfo(_In_z_ _Printf_format_string_ LPCWSTR _text, ...) NOEXCEPT

Просмотреть файл

@ -2446,7 +2446,7 @@ namespace ctsTraffic {
}
if (s_JitterLogger && s_JitterLogger->IsCsvFormat()) {
s_JitterLogger->LogMessage(L"SequenceNumber,SenderQpc,SenderQpf,ReceiverQpc,ReceiverQpf\r\n");
s_JitterLogger->LogMessage(L"SequenceNumber,SenderQpc,SenderQpf,ReceiverQpc,ReceiverQpf,PriorReceiveDelta,EstReceivedDgramInFlight\r\n");
}
}
@ -2723,10 +2723,24 @@ namespace ctsTraffic {
}
}
void PrintJitterUpdate(long long _sequence_number, long long _sender_qpc, long long _sender_qpf, long long _recevier_qpc, long long _receiver_qpf) NOEXCEPT
void PrintJitterUpdate(const JitterFrameEntry& current_frame, const JitterFrameEntry& previous_frame, const JitterFrameEntry& first_frame) NOEXCEPT
{
if (!s_ShutdownCalled) {
if (s_JitterLogger) {
long ms_since_prior_receive = 0;
// calculate time since the prior receive
if (previous_frame.receiver_qpc != 0) {
ms_since_prior_receive = static_cast<long>(((current_frame.receiver_qpc * 1000LL) / current_frame.receiver_qpf) - ((previous_frame.receiver_qpc * 1000LL) / previous_frame.receiver_qpf));
}
// estimating time in flight for this frame by determining how much time since the first send was just 'waiting' to send this frame
// and subtracing that from how much time since the first receive - since time between receives should at least be time between sends
long ms_estimated_time_in_flight = 0;
if (first_frame.receiver_qpc != 0) {
long ms_since_first_receive = static_cast<long>(((current_frame.receiver_qpc * 1000LL) / current_frame.receiver_qpf) - ((first_frame.receiver_qpc * 1000LL) / first_frame.receiver_qpf));
long ms_since_first_send = static_cast<long>(((current_frame.sender_qpc * 1000LL) / current_frame.sender_qpf) - ((first_frame.sender_qpc * 1000LL) / first_frame.sender_qpf));
ms_estimated_time_in_flight = ms_since_first_receive - ms_since_first_send;
}
// long long ~= up to 20 characters long, plus 5 for commas & CR
static const size_t formatted_text_length = (20 * 5) + 5;
wchar_t formatted_text[formatted_text_length];
@ -2735,12 +2749,12 @@ namespace ctsTraffic {
formatted_text,
formatted_text_length,
_TRUNCATE,
L"%lld,%lld,%lld,%lld,%lld\r\n",
_sequence_number, _sender_qpc, _sender_qpf, _recevier_qpc, _receiver_qpf);
L"%lld,%lld,%lld,%lld,%lld,%ld,%ld\r\n",
current_frame.sequence_number, current_frame.sender_qpc, current_frame.sender_qpf, current_frame.receiver_qpc, current_frame.receiver_qpf, ms_since_prior_receive, ms_estimated_time_in_flight);
ctl::ctFatalCondition(
-1 == converted,
L"_snwprintf_s failed to convert Jitter information: %lld, %lld, %lld, %lld, %lld",
_sequence_number, _sender_qpc, _sender_qpf, _recevier_qpc, _receiver_qpf);
L"_snwprintf_s failed to convert Jitter information: %lld, %lld, %lld, %lld, %lld, %ld, %ld",
current_frame.sequence_number, current_frame.sender_qpc, current_frame.sender_qpf, current_frame.receiver_qpc, current_frame.receiver_qpf, ms_since_prior_receive, ms_estimated_time_in_flight);
s_JitterLogger->LogMessage(formatted_text);
}
}

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -102,48 +102,48 @@ namespace ctsTraffic {
/// OR
inline
OptionType operator| (OptionType& _lhs, OptionType _rhs)
OptionType operator| (OptionType& lhs, OptionType rhs)
{
return OptionType(static_cast<unsigned long>(_lhs) | static_cast<unsigned long>(_rhs));
return OptionType(static_cast<unsigned long>(lhs) | static_cast<unsigned long>(rhs));
}
inline
OptionType& operator|= (OptionType& _lhs, OptionType _rhs)
OptionType& operator|= (OptionType& lhs, OptionType rhs)
{
_lhs = _lhs | _rhs;
return _lhs;
lhs = lhs | rhs;
return lhs;
}
/// AND
inline
OptionType operator& (OptionType _lhs, OptionType _rhs)
OptionType operator& (OptionType lhs, OptionType rhs)
{
return OptionType(static_cast<unsigned long>(_lhs) & static_cast<unsigned long>(_rhs));
return OptionType(static_cast<unsigned long>(lhs) & static_cast<unsigned long>(rhs));
}
inline
OptionType& operator&= (OptionType& _lhs, OptionType _rhs)
OptionType& operator&= (OptionType& lhs, OptionType rhs)
{
_lhs = _lhs & _rhs;
return _lhs;
lhs = lhs & rhs;
return lhs;
}
/// XOR
inline
OptionType operator^ (OptionType _lhs, OptionType _rhs)
OptionType operator^ (OptionType lhs, OptionType rhs)
{
return OptionType(static_cast<unsigned long>(_lhs) ^ static_cast<unsigned long>(_rhs));
return OptionType(static_cast<unsigned long>(lhs) ^ static_cast<unsigned long>(rhs));
}
inline
OptionType& operator^= (OptionType& _lhs, OptionType _rhs)
OptionType& operator^= (OptionType& lhs, OptionType rhs)
{
_lhs = _lhs ^ _rhs;
return _lhs;
lhs = lhs ^ rhs;
return lhs;
}
/// NOT
inline
OptionType operator~ (OptionType _lhs)
OptionType operator~ (OptionType lhs)
{
return OptionType(~static_cast<unsigned long>(_lhs));
return OptionType(~static_cast<unsigned long>(lhs));
}
////////////////////////////////////////////////////////////////////////////////////////////////////
@ -166,9 +166,19 @@ namespace ctsTraffic {
void PrintSettings();
void PrintLegend() NOEXCEPT;
struct JitterFrameEntry {
long long sequence_number = 0LL;
long long sender_qpc = 0LL;
long long sender_qpf = 0LL;
long long receiver_qpc = 0LL;
long long receiver_qpf = 0LL;
unsigned long received = 0UL;
};
void PrintJitterUpdate(const JitterFrameEntry& current_frame, const JitterFrameEntry& previous_frame, const JitterFrameEntry& first_frame) NOEXCEPT;
void PrintStatusUpdate() NOEXCEPT;
void PrintJitterUpdate(long long _sequence_number, long long _sender_qpc, long long _sender_qpf, long long _recevier_qpc, long long _receiver_qpf) NOEXCEPT;
void __cdecl PrintSummary(_In_z_ _Printf_format_string_ LPCWSTR _text, ...) NOEXCEPT;
void __cdecl PrintSummary(_In_z_ _Printf_format_string_ LPCWSTR text, ...) NOEXCEPT;
// Putting PrintDebugInfo as a macro to avoid running any code for debug printing if not necessary
#define PrintDebugInfo(fmt, ...) \
@ -182,19 +192,19 @@ namespace ctsTraffic {
} \
}
void PrintErrorIfFailed(_In_ LPCWSTR _what, unsigned long _why) NOEXCEPT;
void __cdecl PrintErrorInfo(_In_z_ _Printf_format_string_ LPCWSTR _text, ...) NOEXCEPT;
void PrintErrorIfFailed(_In_ LPCWSTR what, unsigned long why) NOEXCEPT;
void __cdecl PrintErrorInfo(_In_z_ _Printf_format_string_ LPCWSTR text, ...) NOEXCEPT;
// Override will always print to console regardless of settings (important if can't even start)
void __cdecl PrintErrorInfoOverride(_In_z_ _Printf_format_string_ LPCWSTR _text, ...) NOEXCEPT;
void __cdecl PrintErrorInfoOverride(_In_z_ _Printf_format_string_ LPCWSTR text, ...) NOEXCEPT;
void PrintException(const std::exception& e) NOEXCEPT;
// Override will always print to console regardless of settings (important if can't even start)
void PrintExceptionOverride(const std::exception& e) NOEXCEPT;
void PrintNewConnection(const ctl::ctSockaddr& _local_addr, const ctl::ctSockaddr& _remote_addr) NOEXCEPT;
void PrintConnectionResults(const ctl::ctSockaddr& _local_addr, const ctl::ctSockaddr& _remote_addr, unsigned long _error, const ctsTcpStatistics& _stats) NOEXCEPT;
void PrintConnectionResults(const ctl::ctSockaddr& _local_addr, const ctl::ctSockaddr& _remote_addr, unsigned long _error, const ctsUdpStatistics& _stats) NOEXCEPT;
void PrintConnectionResults(const ctl::ctSockaddr& _local_addr, const ctl::ctSockaddr& _remote_addr, unsigned long _error) NOEXCEPT;
void PrintNewConnection(const ctl::ctSockaddr& local_addr, const ctl::ctSockaddr& remote_addr) NOEXCEPT;
void PrintConnectionResults(const ctl::ctSockaddr& local_addr, const ctl::ctSockaddr& remote_addr, unsigned long error, const ctsTcpStatistics& stats) NOEXCEPT;
void PrintConnectionResults(const ctl::ctSockaddr& local_addr, const ctl::ctSockaddr& remote_addr, unsigned long error, const ctsUdpStatistics& stats) NOEXCEPT;
void PrintConnectionResults(const ctl::ctSockaddr& local_addr, const ctl::ctSockaddr& remote_addr, unsigned long error) NOEXCEPT;
// Get* functions
ctsSignedLongLong GetTcpBytesPerSecond() NOEXCEPT;
@ -208,8 +218,8 @@ namespace ctsTraffic {
bool IsListening() NOEXCEPT;
// Set* functions
int SetPreBindOptions(SOCKET _s, const ctl::ctSockaddr& _local_address);
int SetPreConnectOptions(SOCKET _s);
int SetPreBindOptions(SOCKET s, const ctl::ctSockaddr& local_address);
int SetPreConnectOptions(SOCKET s);
// for the MediaStream pattern
struct MediaStreamSettings {

Просмотреть файл

@ -594,15 +594,6 @@ namespace ctsTraffic {
ctsIOPatternProtocolError completed_task(const ctsIOTask& _task, unsigned long _current_transfer) NOEXCEPT override;
private:
struct FrameEntry {
long long sequence_number = 0LL;
long long sender_qpc = 0LL;
long long sender_qpf = 0LL;
long long receiver_qpc = 0LL;
long long receiver_qpf = 0LL;
unsigned long received = 0UL;
};
// private member variables
PTP_TIMER renderer_timer;
PTP_TIMER start_timer;
@ -625,14 +616,18 @@ namespace ctsTraffic {
// member variables that require the base lock
_Requires_lock_held_(cs)
std::vector<FrameEntry> frame_entries;
std::vector<ctsConfig::JitterFrameEntry> frame_entries;
_Requires_lock_held_(cs)
std::vector<FrameEntry>::iterator head_entry;
std::vector<ctsConfig::JitterFrameEntry>::iterator head_entry;
// tracking for jitter information
ctsConfig::JitterFrameEntry first_frame;
ctsConfig::JitterFrameEntry previous_frame;
// member functions - all require the base lock
_Requires_lock_held_(cs)
std::vector<FrameEntry>::iterator find_sequence_number(long long _seq_number) NOEXCEPT;
std::vector<ctsConfig::JitterFrameEntry>::iterator find_sequence_number(long long _seq_number) NOEXCEPT;
_Requires_lock_held_(cs)
bool received_buffered_frames() NOEXCEPT;

Просмотреть файл

@ -303,7 +303,7 @@ namespace ctsTraffic {
/// If the sequence number was not found, will return end(frame_entries)
///
_Requires_lock_held_(cs)
vector<ctsIOPatternMediaStreamClient::FrameEntry>::iterator ctsIOPatternMediaStreamClient::find_sequence_number(long long _seq_number) NOEXCEPT
vector<ctsConfig::JitterFrameEntry>::iterator ctsIOPatternMediaStreamClient::find_sequence_number(long long _seq_number) NOEXCEPT
{
ctsSignedLongLong head_sequence_number = this->head_entry->sequence_number;
ctsSignedLongLong tail_sequence_number = head_sequence_number + this->frame_entries.size() - 1;
@ -397,12 +397,14 @@ namespace ctsTraffic {
static_cast<long long>(this->head_entry->sequence_number));
// Directly write this status update if jitter is enabled
ctsConfig::PrintJitterUpdate(
this->head_entry->sequence_number,
this->head_entry->sender_qpc,
this->head_entry->sender_qpf,
this->head_entry->receiver_qpc,
this->head_entry->receiver_qpf);
ctsConfig::PrintJitterUpdate(*this->head_entry, this->previous_frame, this->first_frame);
// if this is the first frame, capture it
if (this->first_frame.receiver_qpc == 0) {
this->first_frame = *this->head_entry;
}
// always keep the most recently received frame for jitter
this->previous_frame = *this->head_entry;
} else {
ctsConfig::Settings->UdpStatusDetails.dropped_frames.increment();
@ -411,6 +413,10 @@ namespace ctsTraffic {
PrintDebugInfo(
L"\t\tctsIOPatternMediaStreamClient **dropped** frame %lld\n",
static_cast<long long>(this->head_entry->sequence_number));
// write and empty row
ctsConfig::PrintJitterUpdate(ctsConfig::JitterFrameEntry(), ctsConfig::JitterFrameEntry(), ctsConfig::JitterFrameEntry());
}
// update the current sequence number so it's now the "end" sequence number of the queue (the new max value)