Initial update looking for Interlocked* calls that are unnecessary.

This commit is contained in:
Keith Horton 2024-05-26 17:32:56 -07:00
Родитель bd0626a879
Коммит 1a2b1de73c
26 изменённых файлов: 217 добавлений и 160 удалений

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

@ -25,10 +25,10 @@ See the Apache Version 2.0 License for specific language governing permissions a
// ReSharper disable once CppUnusedIncludeDirective
#include <ws2ipdef.h>
#include <iphlpapi.h>
// wil headers
#include <wil/resource.h>
// ctl headers
#include "ctSockaddr.hpp"
// wil headers always included last
#include <wil/resource.h>
namespace ctl
{

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

@ -26,13 +26,13 @@ See the Apache Version 2.0 License for specific language governing permissions a
#include <Windows.h>
#include <objbase.h>
#include <oleauto.h>
// wil headers
#include <wil/stl.h>
#include <wil/resource.h>
#include <wil/win32_helpers.h>
// ctl headers
#include <ctString.hpp>
#include <ctWmiInitialize.hpp>
// wil headers always included last
#include <wil/stl.h>
#include <wil/resource.h>
#include <wil/win32_helpers.h>
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///

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

@ -26,12 +26,12 @@ See the Apache Version 2.0 License for specific language governing permissions a
#include <ws2ipdef.h>
#include <iphlpapi.h>
#include <tcpestats.h>
// wil headers
// ctl headers
#include <ctSockaddr.hpp>
// wil headers always included last
#include <wil/stl.h>
#include <wil/resource.h>
#include <wil/win32_helpers.h>
// ctl headers
#include <ctSockaddr.hpp>
namespace ctsPerf { namespace Details
{

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

@ -20,9 +20,6 @@ See the Apache Version 2.0 License for specific language governing permissions a
// os headers
#include <Windows.h>
#include <WinSock2.h>
// wil headers
#include <wil/stl.h>
#include <wil/resource.h>
// ctl headers
#include <ctString.hpp>
#include <ctWmiInitialize.hpp>
@ -30,6 +27,9 @@ See the Apache Version 2.0 License for specific language governing permissions a
// project headers
#include "ctsWriteDetails.h"
#include "ctsEstats.h"
// wil headers always included last
#include <wil/stl.h>
#include <wil/resource.h>
using namespace std;
using namespace ctl;

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

@ -17,12 +17,11 @@ See the Apache Version 2.0 License for specific language governing permissions a
#include <string>
// os headers
#include <Windows.h>
// wil headers
#include <wil/stl.h>
#include <wil/resource.h>
// ctl headers
#include <ctString.hpp>
// wil headers always included last
#include <wil/stl.h>
#include <wil/resource.h>
namespace ctsPerf
{

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

@ -20,15 +20,15 @@ See the Apache Version 2.0 License for specific language governing permissions a
#include <Windows.h>
#include <WinSock2.h>
#include <MSWSock.h>
// wil headers
#include <wil/stl.h>
#include <wil/resource.h>
// ctl headers
#include <ctSocketExtensions.hpp>
#include <ctThreadIocp.hpp>
#include <ctSockaddr.hpp>
// project headers
#include "ctsSocket.h"
// wil headers always included last
#include <wil/stl.h>
#include <wil/resource.h>
using ctsTraffic::ctsConfig::g_configSettings;

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

@ -24,9 +24,6 @@ See the Apache Version 2.0 License for specific language governing permissions a
#include <iphlpapi.h>
// multimedia timer
#include <mmsystem.h>
// wil headers
#include <wil/stl.h>
#include <wil/resource.h>
// ctl headers
#include <ctSockaddr.hpp>
#include <ctString.hpp>
@ -40,11 +37,14 @@ See the Apache Version 2.0 License for specific language governing permissions a
#include "ctsLogger.hpp"
#include "ctsIOPattern.h"
#include "ctsPrintStatus.hpp"
// project functors
// project headers
#include "ctsTCPFunctions.h"
#include "ctsMediaStreamClient.h"
#include "ctsMediaStreamServer.h"
#include "ctsWinsockLayer.h"
// wil headers always included last
#include <wil/stl.h>
#include <wil/resource.h>
using namespace std;
using namespace ctl;
@ -3778,7 +3778,8 @@ namespace ctsTraffic::ctsConfig
errorType = ErrorType::NetworkError;
}
const int64_t totalTime = stats.m_endTime.GetValue() - stats.m_startTime.GetValue();
// the connection has ended - no locks needed
const int64_t totalTime = stats.m_endTime.GetValueNoLock() - stats.m_startTime.GetValueNoLock();
FAIL_FAST_IF_MSG(
totalTime < 0LL,
"end_time is less than start_time in this ctsTcpStatistics object (%p)", &stats);
@ -3818,10 +3819,10 @@ namespace ctsTraffic::ctsConfig
currentTime,
wsaLocalAddress,
wsaRemoteAddress,
stats.m_bytesSent.GetValue(),
totalTime > 0LL ? stats.m_bytesSent.GetValue() * 1000LL / totalTime : 0LL,
stats.m_bytesRecv.GetValue(),
totalTime > 0LL ? stats.m_bytesRecv.GetValue() * 1000LL / totalTime : 0LL,
stats.m_bytesSent.GetValueNoLock(),
totalTime > 0LL ? stats.m_bytesSent.GetValueNoLock() * 1000LL / totalTime : 0LL,
stats.m_bytesRecv.GetValueNoLock(),
totalTime > 0LL ? stats.m_bytesRecv.GetValueNoLock() * 1000LL / totalTime : 0LL,
totalTime,
ErrorType::ProtocolError == errorType
? ctsIoPattern::BuildProtocolErrorString(error)
@ -3847,10 +3848,10 @@ namespace ctsTraffic::ctsConfig
wsaLocalAddress,
wsaRemoteAddress,
stats.m_connectionIdentifier,
stats.m_bytesSent.GetValue(),
totalTime > 0LL ? stats.m_bytesSent.GetValue() * 1000LL / totalTime : 0LL,
stats.m_bytesRecv.GetValue(),
totalTime > 0LL ? stats.m_bytesRecv.GetValue() * 1000LL / totalTime : 0LL,
stats.m_bytesSent.GetValueNoLock(),
totalTime > 0LL ? stats.m_bytesSent.GetValueNoLock() * 1000LL / totalTime : 0LL,
stats.m_bytesRecv.GetValueNoLock(),
totalTime > 0LL ? stats.m_bytesRecv.GetValueNoLock() * 1000LL / totalTime : 0LL,
totalTime);
}
else
@ -3870,10 +3871,10 @@ namespace ctsTraffic::ctsConfig
wsaLocalAddress,
wsaRemoteAddress,
stats.m_connectionIdentifier,
stats.m_bytesSent.GetValue(),
totalTime > 0LL ? stats.m_bytesSent.GetValue() * 1000LL / totalTime : 0LL,
stats.m_bytesRecv.GetValue(),
totalTime > 0LL ? stats.m_bytesRecv.GetValue() * 1000LL / totalTime : 0LL,
stats.m_bytesSent.GetValueNoLock(),
totalTime > 0LL ? stats.m_bytesSent.GetValueNoLock() * 1000LL / totalTime : 0LL,
stats.m_bytesRecv.GetValueNoLock(),
totalTime > 0LL ? stats.m_bytesRecv.GetValueNoLock() * 1000LL / totalTime : 0LL,
totalTime);
}
}
@ -3955,8 +3956,9 @@ namespace ctsTraffic::ctsConfig
}
const float currentTime = GetStatusTimeStamp();
const int64_t elapsedTime(stats.m_endTime.GetValue() - stats.m_startTime.GetValue());
const int64_t bitsPerSecond = elapsedTime > 0LL ? stats.m_bitsReceived.GetValue() * 1000LL / elapsedTime : 0LL;
// the connection has ended - no locks needed
const int64_t elapsedTime(stats.m_endTime.GetValueNoLock() - stats.m_startTime.GetValueNoLock());
const int64_t bitsPerSecond = elapsedTime > 0LL ? stats.m_bitsReceived.GetValueNoLock() * 1000LL / elapsedTime : 0LL;
wstring csvString;
wstring textString;
@ -3993,10 +3995,10 @@ namespace ctsTraffic::ctsConfig
wsaLocalAddress,
wsaRemoteAddress,
bitsPerSecond,
stats.m_successfulFrames.GetValue(),
stats.m_droppedFrames.GetValue(),
stats.m_duplicateFrames.GetValue(),
stats.m_errorFrames.GetValue(),
stats.m_successfulFrames.GetValueNoLock(),
stats.m_droppedFrames.GetValueNoLock(),
stats.m_duplicateFrames.GetValueNoLock(),
stats.m_errorFrames.GetValueNoLock(),
ErrorType::ProtocolError == errorType
? ctsIoPattern::BuildProtocolErrorString(error)
: errorString.c_str(),
@ -4022,10 +4024,10 @@ namespace ctsTraffic::ctsConfig
wsaRemoteAddress,
stats.m_connectionIdentifier,
bitsPerSecond,
stats.m_successfulFrames.GetValue(),
stats.m_droppedFrames.GetValue(),
stats.m_duplicateFrames.GetValue(),
stats.m_errorFrames.GetValue());
stats.m_successfulFrames.GetValueNoLock(),
stats.m_droppedFrames.GetValueNoLock(),
stats.m_duplicateFrames.GetValueNoLock(),
stats.m_errorFrames.GetValueNoLock());
}
else
{
@ -4045,10 +4047,10 @@ namespace ctsTraffic::ctsConfig
wsaRemoteAddress,
stats.m_connectionIdentifier,
bitsPerSecond,
stats.m_successfulFrames.GetValue(),
stats.m_droppedFrames.GetValue(),
stats.m_duplicateFrames.GetValue(),
stats.m_errorFrames.GetValue());
stats.m_successfulFrames.GetValueNoLock(),
stats.m_droppedFrames.GetValueNoLock(),
stats.m_duplicateFrames.GetValueNoLock(),
stats.m_errorFrames.GetValueNoLock());
}
}
@ -4103,17 +4105,18 @@ namespace ctsTraffic::ctsConfig
remoteAddr.writeCompleteAddress(wsaRemoteAddress);
static const auto* tcpSuccessfulResultTextFormat = L"%.3f, %ws, %ws, %hs, %lld, %lld, %lld, %lld, %lld, ";
const int64_t totalTime{stats.m_endTime.GetValue() - stats.m_startTime.GetValue()};
// the connection has ended - no locks needed
const int64_t totalTime{stats.m_endTime.GetValueNoLock() - stats.m_startTime.GetValueNoLock()};
auto textString = wil::str_printf<std::wstring>(
tcpSuccessfulResultTextFormat,
GetStatusTimeStamp(),
wsaLocalAddress,
wsaRemoteAddress,
stats.m_connectionIdentifier,
stats.m_bytesSent.GetValue(),
totalTime > 0LL ? stats.m_bytesSent.GetValue() * 1000LL / totalTime : 0LL,
stats.m_bytesRecv.GetValue(),
totalTime > 0LL ? stats.m_bytesRecv.GetValue() * 1000LL / totalTime : 0LL,
stats.m_bytesSent.GetValueNoLock(),
totalTime > 0LL ? stats.m_bytesSent.GetValueNoLock() * 1000LL / totalTime : 0LL,
stats.m_bytesRecv.GetValueNoLock(),
totalTime > 0LL ? stats.m_bytesRecv.GetValueNoLock() * 1000LL / totalTime : 0LL,
totalTime);
DWORD bytesReturned;

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

@ -16,10 +16,11 @@ See the Apache Version 2.0 License for specific language governing permissions a
// ReSharper disable CppClangTidyClangDiagnosticGnuZeroVariadicMacroArguments
// cpp headers
#include <stdexcept>
#include <vector>
#include <functional>
#include <memory>
#include <optional>
#include <stdexcept>
#include <vector>
// os headers
#include <Windows.h>
// ctl headers
@ -27,11 +28,9 @@ See the Apache Version 2.0 License for specific language governing permissions a
#include <ctSockaddr.hpp>
//
// ** NOTE ** cannot include local project cts headers to avoid circular references
// - with the below exceptions : these do not include any cts* headers
// -- ctsStatistics.hpp
// - with the exception of ctsStatistics.hpp
// - this header *can* be included here because it does not include any cts* headers
//
#include <optional>
#include "ctsStatistics.hpp"
namespace ctsTraffic

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

@ -16,15 +16,15 @@ See the Apache Version 2.0 License for specific language governing permissions a
#include "ctsIOPattern.h"
// cpp headers
#include <vector>
// wil headers
#include <wil/stl.h>
#include <wil/resource.h>
// ctl headers
#include <ctSocketExtensions.hpp>
#include <ctTimer.hpp>
// project headers
#include "ctsMediaStreamProtocol.hpp"
#include "ctsTCPFunctions.h"
// wil headers always included last
#include <wil/stl.h>
#include <wil/resource.h>
namespace ctsTraffic
{
@ -1197,7 +1197,8 @@ namespace ctsTraffic
const int64_t currentTransferBits = static_cast<int64_t>(currentTransfer) * 8LL;
ctsConfig::g_configSettings->UdpStatusDetails.m_bitsReceived.Add(currentTransferBits);
m_statistics.m_bitsReceived.Add(currentTransferBits);
// local updates are always under lock - not requiring Interlocked* calls
m_statistics.m_bitsReceived.AddNoLock(currentTransferBits);
m_currentFrameCompleted += currentTransfer;
if (m_currentFrameCompleted == m_frameSizeBytes)

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

@ -186,10 +186,10 @@ private:
///
/// Private method which must be implemented by the derived interface (the IO pattern)
///
/// ctsIOTask GetNextTask()
/// ctsIOTask GetNextTaskFromPattern()
/// - must return a ctsIOTask returned from CreateTrackedTask or CreateUntrackedTask
///
/// ctsIoPatternError CompleteTask(const ctsIOTask&, uint32_t currentTransfer) noexcept
/// ctsIoPatternError CompleteTaskBackToPattern(const ctsIOTask&, uint32_t currentTransfer) noexcept
/// - a notification to the derived class over what task completed
/// - ctsIOTask argument: the ctsIOTask which it previously returned from GetNextTask()
/// - uint32_t argument: the # of bytes actually transferred
@ -477,7 +477,7 @@ public:
void PrintStatistics(const ctl::ctSockaddr& localAddr, const ctl::ctSockaddr& remoteAddr) noexcept override
{
// before printing the final results, make sure the timers are stopped
if (0 == GetLastPatternError() && 0 == m_statistics.GetBytesReceived())
if (0 == GetLastPatternError() && 0 == m_statistics.GetBytesTransferred())
{
PRINT_DEBUG_INFO(L"\t\tctsIOPattern::PrintStatistics : reporting a successful IO completion but transfered zero bytes\n");
UpdateLastPatternError(ctsIoPatternError::TooFewBytes);

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

@ -24,7 +24,7 @@ See the Apache Version 2.0 License for specific language governing permissions a
#include "ctsConfig.h"
#include "ctsIOTask.hpp"
#include "ctsMediaStreamProtocol.hpp"
// wil headers
// wil headers always included last
#include <wil/stl.h>
#include <wil/resource.h>
@ -203,13 +203,15 @@ ctsIoPatternError ctsIoPatternMediaStreamClient::CompleteTaskBackToPattern(const
// track the # of *bits* received
ctsConfig::g_configSettings->UdpStatusDetails.m_bitsReceived.Add(static_cast<int64_t>(completedBytes) * 8LL);
m_statistics.m_bitsReceived.Add(static_cast<int64_t>(completedBytes) * 8LL);
// local stats are called under lock - no need for Interlocked* calls
m_statistics.m_bitsReceived.AddNoLock(static_cast<int64_t>(completedBytes) * 8LL);
const auto receivedsequenceNumber = ctsMediaStreamMessage::GetSequenceNumberFromTask(task);
if (receivedsequenceNumber > m_finalFrame)
{
ctsConfig::g_configSettings->UdpStatusDetails.m_errorFrames.Increment();
m_statistics.m_errorFrames.Increment();
// local stats are called under lock - no need for Interlocked* calls
m_statistics.m_errorFrames.IncrementNoLock();
PRINT_DEBUG_INFO(
L"\t\tctsIOPatternMediaStreamClient recevieved **an unknown** seq number (%lld) (outside the final frame %lu)\n",
@ -253,7 +255,8 @@ ctsIoPatternError ctsIoPatternMediaStreamClient::CompleteTaskBackToPattern(const
{
// didn't find a slot for the received seq. number
ctsConfig::g_configSettings->UdpStatusDetails.m_errorFrames.Increment();
m_statistics.m_errorFrames.Increment();
// local stats are called under lock - no need for Interlocked* calls
m_statistics.m_errorFrames.IncrementNoLock();
if (receivedsequenceNumber < m_headEntry->m_sequenceNumber)
{
@ -393,7 +396,8 @@ void ctsIoPatternMediaStreamClient::RenderFrame() noexcept
if (m_headEntry->m_bytesReceived == m_frameSizeBytes)
{
ctsConfig::g_configSettings->UdpStatusDetails.m_successfulFrames.Increment();
m_statistics.m_successfulFrames.Increment();
// local stats are called under lock - no need for Interlocked* calls
m_statistics.m_successfulFrames.IncrementNoLock();
PRINT_DEBUG_INFO(
L"\t\tctsIOPatternMediaStreamClient rendered frame %lld\n",
@ -413,7 +417,8 @@ void ctsIoPatternMediaStreamClient::RenderFrame() noexcept
else if (m_headEntry->m_bytesReceived < m_frameSizeBytes)
{
ctsConfig::g_configSettings->UdpStatusDetails.m_droppedFrames.Increment();
m_statistics.m_droppedFrames.Increment();
// local stats are called under lock - no need for Interlocked* calls
m_statistics.m_droppedFrames.IncrementNoLock();
PRINT_DEBUG_INFO(
L"\t\tctsIOPatternMediaStreamClient **dropped** frame for seq number (%lld)\n",
@ -428,7 +433,8 @@ void ctsIoPatternMediaStreamClient::RenderFrame() noexcept
else // m_headEntry->bytes_received > m_frameSizeBytes
{
ctsConfig::g_configSettings->UdpStatusDetails.m_duplicateFrames.Increment();
m_statistics.m_duplicateFrames.Increment();
// local stats are called under lock - no need for Interlocked* calls
m_statistics.m_duplicateFrames.IncrementNoLock();
PRINT_DEBUG_INFO(
L"\t\tctsIOPatternMediaStreamClient **a duplicate** frame for seq number (%lld)\n",
@ -509,7 +515,8 @@ VOID CALLBACK ctsIoPatternMediaStreamClient::TimerCallback(PTP_CALLBACK_INSTANCE
// indicate all frames were dropped
ctsConfig::g_configSettings->UdpStatusDetails.m_droppedFrames.Add(thisPtr->m_finalFrame);
thisPtr->m_statistics.m_droppedFrames.Add(thisPtr->m_finalFrame);
// local stats are called under lock - no need for Interlocked* calls
thisPtr->m_statistics.m_droppedFrames.AddNoLock(thisPtr->m_finalFrame);
thisPtr->m_finishedStream = true;
ctsTask abortTask;

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

@ -16,9 +16,6 @@ See the Apache Version 2.0 License for specific language governing permissions a
// os headers
#include <Windows.h>
#include <WinSock2.h>
// wil headers
#include <wil/stl.h>
#include <wil/resource.h>
// ctl headers
#include <ctSockaddr.hpp>
// project headers
@ -29,6 +26,9 @@ See the Apache Version 2.0 License for specific language governing permissions a
#include "ctsIOPattern.h"
#include "ctsSocket.h"
#include "ctsConfig.h"
// wil headers always included last
#include <wil/stl.h>
#include <wil/resource.h>
namespace ctsTraffic
{
@ -117,6 +117,7 @@ namespace ctsTraffic
//
// increment IO count while issuing this Impl, so we hold a ref-count during this out of band callback
// TODO: socket is locked - no need for interlocked
if (lambdaSharedSocket->IncrementIo() > 1)
{
// only running this one task in the OOB callback
@ -139,6 +140,7 @@ namespace ctsTraffic
});
// increment IO count while issuing this Impl, so we hold a ref-count during this out of band callback
// TODO: socket is locked - no need for interlocked
sharedSocket->IncrementIo();
IoImplStatus status = ctsMediaStreamClientIoImpl(
sharedSocket,
@ -245,6 +247,7 @@ namespace ctsTraffic
case ctsTaskAction::Recv:
{
// add-ref the IO about to start
// TODO: the socket locked when ctsMediaStreamClientIoImpl is called
sharedSocket->IncrementIo();
auto callback = [weak_reference = std::weak_ptr(sharedSocket), task](OVERLAPPED* ov) noexcept
{

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

@ -20,14 +20,14 @@ See the Apache Version 2.0 License for specific language governing permissions a
// os headers
#include <Windows.h>
#include <WinSock2.h>
// wil headers
#include <wil/resource.h>
// ctl headers
#include <ctTimer.hpp>
// local headers
// project headers
#include "ctsConfig.h"
#include "ctsIOTask.hpp"
#include "ctsStatistics.hpp"
// wil headers always included last
#include <wil/resource.h>
namespace ctsTraffic
{

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

@ -18,9 +18,6 @@ See the Apache Version 2.0 License for specific language governing permissions a
// os headers
#include <Windows.h>
#include <WinSock2.h>
// wil headers
#include <wil/stl.h>
#include <wil/resource.h>
// ctl headers
#include <ctSockaddr.hpp>
// project headers
@ -32,7 +29,9 @@ See the Apache Version 2.0 License for specific language governing permissions a
#include "ctsMediaStreamServerConnectedSocket.h"
#include "ctsMediaStreamServerListeningSocket.h"
#include "ctsMediaStreamProtocol.hpp"
// wil headers always included last
#include <wil/stl.h>
#include <wil/resource.h>
namespace ctsTraffic
{

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

@ -18,14 +18,14 @@ See the Apache Version 2.0 License for specific language governing permissions a
// os headers
#include <Windows.h>
#include <WinSock2.h>
// wil headers
#include <wil/resource.h>
// ctl headers
#include <ctSockaddr.hpp>
// project headers
#include "ctsIOTask.hpp"
#include "ctsSocket.h"
#include "ctsWinsockLayer.h"
// wil headers always included last
#include <wil/resource.h>
namespace ctsTraffic
{

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

@ -18,9 +18,6 @@ See the Apache Version 2.0 License for specific language governing permissions a
// os headers
#include <Windows.h>
#include <WinSock2.h>
// wil headers
#include <wil/stl.h>
#include <wil/resource.h>
// ctl headers
#include <ctThreadIocp.hpp>
#include <ctSockaddr.hpp>
@ -29,6 +26,9 @@ See the Apache Version 2.0 License for specific language governing permissions a
#include "ctsMediaStreamServer.h"
#include "ctsMediaStreamProtocol.hpp"
#include "ctsConfig.h"
// wil headers always included last
#include <wil/stl.h>
#include <wil/resource.h>
namespace ctsTraffic
{

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

@ -21,7 +21,7 @@ See the Apache Version 2.0 License for specific language governing permissions a
// ctl headers
#include <ctSockaddr.hpp>
#include <ctThreadIocp.hpp>
// project headers
#include "ctsConfig.h"
namespace ctsTraffic

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

@ -410,6 +410,7 @@ public:
{
const ctsUdpStatistics udpData(ctsConfig::g_configSettings->UdpStatusDetails.SnapView(clearStatus));
const ctsConnectionStatistics connectionData(ctsConfig::g_configSettings->ConnectionStatusDetails.SnapView(clearStatus));
// can call GetValueNoLock on both Statistics objects since they are copies
if (ctsConfig::StatusFormatting::Csv == format)
{
@ -417,17 +418,17 @@ public:
// converting milliseconds to seconds before printing
charactersWritten += AppendCsvOutput(charactersWritten, c_timeSliceLength, static_cast<float>(currentTime) / 1000.0f);
// calculating # of bytes that were received between the previous format() and current call to format()
const int64_t timeElapsed = udpData.m_endTime.GetValue() - udpData.m_startTime.GetValue();
const int64_t timeElapsed = udpData.m_endTime.GetValueNoLock() - udpData.m_startTime.GetValueNoLock();
charactersWritten += AppendCsvOutput(
charactersWritten,
c_bitsPerSecondLength,
timeElapsed > 0LL ? udpData.m_bitsReceived.GetValue() * 1000LL / timeElapsed : 0LL);
timeElapsed > 0LL ? udpData.m_bitsReceived.GetValueNoLock() * 1000LL / timeElapsed : 0LL);
charactersWritten += AppendCsvOutput(charactersWritten, c_currentStreamsLength, connectionData.m_activeConnectionCount.GetValue());
charactersWritten += AppendCsvOutput(charactersWritten, c_competedFramesLength, udpData.m_successfulFrames.GetValue());
charactersWritten += AppendCsvOutput(charactersWritten, c_droppedFramesLength, udpData.m_droppedFrames.GetValue());
charactersWritten += AppendCsvOutput(charactersWritten, c_duplicatedFramesLength, udpData.m_duplicateFrames.GetValue());
charactersWritten += AppendCsvOutput(charactersWritten, c_errorFramesLength, udpData.m_errorFrames.GetValue(), false); // no comma at the end
charactersWritten += AppendCsvOutput(charactersWritten, c_currentStreamsLength, connectionData.m_activeConnectionCount.GetValueNoLock());
charactersWritten += AppendCsvOutput(charactersWritten, c_competedFramesLength, udpData.m_successfulFrames.GetValueNoLock());
charactersWritten += AppendCsvOutput(charactersWritten, c_droppedFramesLength, udpData.m_droppedFrames.GetValueNoLock());
charactersWritten += AppendCsvOutput(charactersWritten, c_duplicatedFramesLength, udpData.m_duplicateFrames.GetValueNoLock());
charactersWritten += AppendCsvOutput(charactersWritten, c_errorFramesLength, udpData.m_errorFrames.GetValueNoLock(), false); // no comma at the end
TerminateFileString(charactersWritten);
}
else
@ -435,17 +436,17 @@ public:
// converting milliseconds to seconds before printing
RightJustifyOutput(c_timeSliceOffset, c_timeSliceLength, static_cast<float>(currentTime) / 1000.0f);
// calculating # of bytes that were received between the previous format() and current call to format()
const int64_t timeElapsed = udpData.m_endTime.GetValue() - udpData.m_startTime.GetValue();
const int64_t timeElapsed = udpData.m_endTime.GetValueNoLock() - udpData.m_startTime.GetValueNoLock();
RightJustifyOutput(
c_bitsPerSecondOffset,
c_bitsPerSecondLength,
timeElapsed > 0LL ? udpData.m_bitsReceived.GetValue() * 1000LL / timeElapsed : 0LL);
timeElapsed > 0LL ? udpData.m_bitsReceived.GetValueNoLock() * 1000LL / timeElapsed : 0LL);
RightJustifyOutput(c_currentStreamsOffset, c_currentStreamsLength, connectionData.m_activeConnectionCount.GetValue());
RightJustifyOutput(c_competedFramesOffset, c_competedFramesLength, udpData.m_successfulFrames.GetValue());
RightJustifyOutput(c_droppedFramesOffset, c_droppedFramesLength, udpData.m_droppedFrames.GetValue());
RightJustifyOutput(c_duplicatedFramesOffset, c_duplicatedFramesLength, udpData.m_duplicateFrames.GetValue());
RightJustifyOutput(c_errorFramesOffset, c_errorFramesLength, udpData.m_errorFrames.GetValue());
RightJustifyOutput(c_currentStreamsOffset, c_currentStreamsLength, connectionData.m_activeConnectionCount.GetValueNoLock());
RightJustifyOutput(c_competedFramesOffset, c_competedFramesLength, udpData.m_successfulFrames.GetValueNoLock());
RightJustifyOutput(c_droppedFramesOffset, c_droppedFramesLength, udpData.m_droppedFrames.GetValueNoLock());
RightJustifyOutput(c_duplicatedFramesOffset, c_duplicatedFramesLength, udpData.m_duplicateFrames.GetValueNoLock());
RightJustifyOutput(c_errorFramesOffset, c_errorFramesLength, udpData.m_errorFrames.GetValueNoLock());
if (format == ctsConfig::StatusFormatting::ConsoleOutput)
{
TerminateString(c_errorFramesOffset);
@ -505,8 +506,9 @@ public:
{
const ctsTcpStatistics tcpData(ctsConfig::g_configSettings->TcpStatusDetails.SnapView(clearStatus));
const ctsConnectionStatistics connectionData(ctsConfig::g_configSettings->ConnectionStatusDetails.SnapView(clearStatus));
// can call GetValueNoLock on both Statistics objects since they are copies
const int64_t timeElapsed = tcpData.m_endTime.GetValue() - tcpData.m_startTime.GetValue();
const int64_t timeElapsed = tcpData.m_endTime.GetValueNoLock() - tcpData.m_startTime.GetValueNoLock();
if (format == ctsConfig::StatusFormatting::Csv)
{
@ -518,17 +520,17 @@ public:
charactersWritten += AppendCsvOutput(
charactersWritten,
c_sendBytesPerSecondLength,
timeElapsed > 0LL ? tcpData.m_bytesSent.GetValue() * 1000LL / timeElapsed : 0LL);
timeElapsed > 0LL ? tcpData.m_bytesSent.GetValueNoLock() * 1000LL / timeElapsed : 0LL);
// calculating # of bytes that were received between the previous format() and current call to format()
charactersWritten += AppendCsvOutput(
charactersWritten,
c_recvBytesPerSecondLength,
timeElapsed > 0LL ? tcpData.m_bytesRecv.GetValue() * 1000LL / timeElapsed : 0LL);
timeElapsed > 0LL ? tcpData.m_bytesRecv.GetValueNoLock() * 1000LL / timeElapsed : 0LL);
charactersWritten += AppendCsvOutput(charactersWritten, c_currentTransactionsLength, connectionData.m_activeConnectionCount.GetValue());
charactersWritten += AppendCsvOutput(charactersWritten, c_completedTransactionsLength, connectionData.m_successfulCompletionCount.GetValue());
charactersWritten += AppendCsvOutput(charactersWritten, c_connectionErrorsLength, connectionData.m_connectionErrorCount.GetValue());
charactersWritten += AppendCsvOutput(charactersWritten, c_protocolErrorsLength, connectionData.m_protocolErrorCount.GetValue(), false); // no comma at the end
charactersWritten += AppendCsvOutput(charactersWritten, c_currentTransactionsLength, connectionData.m_activeConnectionCount.GetValueNoLock());
charactersWritten += AppendCsvOutput(charactersWritten, c_completedTransactionsLength, connectionData.m_successfulCompletionCount.GetValueNoLock());
charactersWritten += AppendCsvOutput(charactersWritten, c_connectionErrorsLength, connectionData.m_connectionErrorCount.GetValueNoLock());
charactersWritten += AppendCsvOutput(charactersWritten, c_protocolErrorsLength, connectionData.m_protocolErrorCount.GetValueNoLock(), false); // no comma at the end
TerminateFileString(charactersWritten);
}
else
@ -540,17 +542,17 @@ public:
RightJustifyOutput(
c_sendBytesPerSecondOffset,
c_sendBytesPerSecondLength,
timeElapsed > 0LL ? tcpData.m_bytesSent.GetValue() * 1000LL / timeElapsed : 0LL);
timeElapsed > 0LL ? tcpData.m_bytesSent.GetValueNoLock() * 1000LL / timeElapsed : 0LL);
// calculating # of bytes that were received between the previous format() and current call to format()
RightJustifyOutput(
c_recvBytesPerSecondOffset,
c_recvBytesPerSecondLength,
timeElapsed > 0LL ? tcpData.m_bytesRecv.GetValue() * 1000LL / timeElapsed : 0LL);
timeElapsed > 0LL ? tcpData.m_bytesRecv.GetValueNoLock() * 1000LL / timeElapsed : 0LL);
RightJustifyOutput(c_currentTransactionsOffset, c_currentTransactionsLength, connectionData.m_activeConnectionCount.GetValue());
RightJustifyOutput(c_completedTransactionsOffset, c_completedTransactionsLength, connectionData.m_successfulCompletionCount.GetValue());
RightJustifyOutput(c_connectionErrorsOffset, c_connectionErrorsLength, connectionData.m_connectionErrorCount.GetValue());
RightJustifyOutput(c_protocolErrorsOffset, c_protocolErrorsLength, connectionData.m_protocolErrorCount.GetValue());
RightJustifyOutput(c_currentTransactionsOffset, c_currentTransactionsLength, connectionData.m_activeConnectionCount.GetValueNoLock());
RightJustifyOutput(c_completedTransactionsOffset, c_completedTransactionsLength, connectionData.m_successfulCompletionCount.GetValueNoLock());
RightJustifyOutput(c_connectionErrorsOffset, c_connectionErrorsLength, connectionData.m_connectionErrorCount.GetValueNoLock());
RightJustifyOutput(c_protocolErrorsOffset, c_protocolErrorsLength, connectionData.m_protocolErrorCount.GetValueNoLock());
if (format == ctsConfig::StatusFormatting::ConsoleOutput)
{
TerminateString(c_protocolErrorsOffset);

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

@ -19,7 +19,7 @@ See the Apache Version 2.0 License for specific language governing permissions a
// ctl headers
#include <ctThreadIocp.hpp>
#include <ctSockaddr.hpp>
// local headers
// project headers
#include "ctsConfig.h"
#include "ctsSocket.h"
#include "ctsIOTask.hpp"
@ -176,6 +176,7 @@ void ctsReadWriteIocp(const std::weak_ptr<ctsSocket>& weakSocket) noexcept
// else we need to initiate another IO
// add-ref the IO about to start
// TODO: socket is locked - no need for interlocked
ioCount = sharedSocket->IncrementIo();
std::shared_ptr<ctl::ctThreadIocp> ioThreadPool;

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

@ -20,16 +20,16 @@ See the Apache Version 2.0 License for specific language governing permissions a
#include <Windows.h>
#include <WinSock2.h>
#include <MSWSock.h>
// wil headers
#include <wil/stl.h>
#include <wil/resource.h>
// ctl headers
#include <ctSocketExtensions.hpp>
#include <ctSockaddr.hpp>
// local headers
// project headers
#include "ctsConfig.h"
#include "ctsSocket.h"
#include "ctsIOTask.hpp"
// wil headers always included last
#include <wil/stl.h>
#include <wil/resource.h>
namespace ctsTraffic { namespace Rioiocp
{
@ -730,6 +730,7 @@ namespace ctsTraffic { namespace Rioiocp
// if we're here, we're attempting IO
// pre-incremenet IO tracking on the socket before issuing the IO
// TODO: socket is locked - no need for interlocked
ioRefcount = sharedSocket->IncrementIo();
// must ensure we have room in the RQ & CQ before initiating the IO

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

@ -19,7 +19,7 @@ See the Apache Version 2.0 License for specific language governing permissions a
// ctl headers
#include <ctThreadIocp.hpp>
#include <ctSockaddr.hpp>
// local headers
// project headers
#include "ctsConfig.h"
#include "ctsSocket.h"
#include "ctsIOTask.hpp"
@ -305,6 +305,7 @@ namespace ctsTraffic
// where it's handled appropriately
// increment IO for this IO request
// TODO: socket is locked - no need for interlocked
sharedSocket->IncrementIo();
// run the ctsIOTask (next_io) that was scheduled through the TP timer
@ -362,6 +363,7 @@ namespace ctsTraffic
// The IO ref-count must be incremented here to hold an IO count on the socket
// - so that we won't inadvertently call complete_state() while IO is still being scheduled
//
// TODO: socket is locked - no need for interlocked
sharedSocket->IncrementIo();
ctsSendRecvStatus status{};
@ -375,6 +377,7 @@ namespace ctsTraffic
}
// increment IO for each individual request
// TODO: socket is locked - no need for interlocked
sharedSocket->IncrementIo();
if (nextIo.m_timeOffsetMilliseconds > 0)

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

@ -18,14 +18,14 @@ See the Apache Version 2.0 License for specific language governing permissions a
// os headers
#include <Windows.h>
#include <WinSock2.h>
// wil headers
#include <wil/stl.h>
#include <wil/resource.h>
// ctl headers
#include <ctSockaddr.hpp>
// project headers
#include "ctsSocket.h"
#include "ctsConfig.h"
// wil headers always included last
#include <wil/stl.h>
#include <wil/resource.h>
namespace ctsTraffic
{

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

@ -16,13 +16,13 @@ See the Apache Version 2.0 License for specific language governing permissions a
// OS headers
#include <Windows.h>
// ctl headers
#include <wil/win32_helpers.h>
// ctl headers
#include <ctMemoryGuard.hpp>
// project headers
#include "ctsConfig.h"
#include "ctsSocketState.h"
#include "ctsWinsockLayer.h"
// wil headers always included last
#include <wil/win32_helpers.h>
namespace ctsTraffic
{
@ -129,8 +129,7 @@ void ctsSocket::PrintPatternResults(uint32_t lastError) const noexcept
else
{
// failed during socket creation, bind, or connect
ctsConfig::PrintConnectionResults(
lastError);
ctsConfig::PrintConnectionResults(lastError);
}
}
@ -286,20 +285,25 @@ catch (...)
int32_t ctsSocket::IncrementIo() noexcept
{
return ctMemoryGuardIncrement(&m_ioCount);
// not apply memory guards - we are holding the socket lock
++m_ioCount;
return m_ioCount;
}
int32_t ctsSocket::DecrementIo() noexcept
{
const auto ioValue = ctMemoryGuardDecrement(&m_ioCount);
// not apply memory guards - we are holding the socket lock
--m_ioCount;
FAIL_FAST_IF_MSG(
ioValue < 0,
"ctsSocket: io count fell below zero (%d)\n", ioValue);
return ioValue;
m_ioCount < 0,
"ctsSocket: io count fell below zero (%d)\n", m_ioCount);
return m_ioCount;
}
int32_t ctsSocket::GetPendedIoCount() noexcept
{
// using Interlocked* to read to force CPU synchronization
// even though writes do not need to be synchronized (we are OK having a small drift with the actual count)
return ctMemoryGuardRead(&m_ioCount);
}

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

@ -21,14 +21,14 @@ See the Apache Version 2.0 License for specific language governing permissions a
// os headers
#include <Windows.h>
#include <WinSock2.h>
// wil headers
#include <wil/resource.h>
// ctl headers
#include <ctThreadIocp.hpp>
#include <ctSockaddr.hpp>
// project headers
#include "ctsIOPattern.h"
#include "ctsIOTask.hpp"
// wil headers always included last
#include <wil/resource.h>
namespace ctsTraffic
{

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

@ -21,6 +21,7 @@ See the Apache Version 2.0 License for specific language governing permissions a
// ctl headers
#include <ctTimer.hpp>
#include <ctMemoryGuard.hpp>
// wil headers always included last
#include <wil/resource.h>
namespace ctsTraffic { namespace ctsStatistics
@ -115,6 +116,13 @@ namespace ctsTraffic { namespace ctsStatistics
return ctl::ctMemoryGuardRead(&m_currentValue);
}
// called when there is no possibility of a race with m_currentValue
// e.g., when printing the final results after it's fully stopped
[[nodiscard]] int64_t GetValueNoLock() const noexcept
{
return m_currentValue;
}
//
// Safely writes to the current value, returning the *prior* value
//
@ -128,6 +136,14 @@ namespace ctsTraffic { namespace ctsStatistics
return ctl::ctMemoryGuardWriteConditionally(&m_currentValue, new_value, if_equals);
}
//
// Writes to the current value without requiring Interlocked* semantics
//
void SetValueNoLock(int64_t new_value) noexcept
{
m_currentValue = new_value;
}
//
// Adds 1 to the current value, returning the new value
//
@ -136,6 +152,14 @@ namespace ctsTraffic { namespace ctsStatistics
return ctl::ctMemoryGuardIncrement(&m_currentValue);
}
//
// Adds 1 to the current value without any Interlocked* semantics
//
void IncrementNoLock() noexcept
{
++m_currentValue;
}
//
// Subtracts 1 from the current value, returning the new value
//
@ -152,6 +176,14 @@ namespace ctsTraffic { namespace ctsStatistics
return ctl::ctMemoryGuardAdd(&m_currentValue, value);
}
//
// Adds the [in] value to the current value without Interlocked* semantics
//
void AddNoLock(int64_t value) noexcept
{
m_currentValue += value;
}
//
// Subtracts the [in] value from the current value, returning the original value
//
@ -233,13 +265,14 @@ namespace ctsTraffic { namespace ctsStatistics
m_startTime.SetPriorValue(currentTime) :
m_startTime.GetPriorValue();
// all writes to the local variable do not require Interlocked* semantics
ctsConnectionStatistics returnStats(priorTimeRead);
returnStats.m_endTime.SetValue(currentTime);
returnStats.m_endTime.SetValueNoLock(currentTime);
returnStats.m_activeConnectionCount.SetValue(m_activeConnectionCount.GetValue());
returnStats.m_successfulCompletionCount.SetValue(m_successfulCompletionCount.GetValue());
returnStats.m_connectionErrorCount.SetValue(m_connectionErrorCount.GetValue());
returnStats.m_protocolErrorCount.SetValue(m_protocolErrorCount.GetValue());
returnStats.m_activeConnectionCount.SetValueNoLock(m_activeConnectionCount.GetValue());
returnStats.m_successfulCompletionCount.SetValueNoLock(m_successfulCompletionCount.GetValue());
returnStats.m_connectionErrorCount.SetValueNoLock(m_connectionErrorCount.GetValue());
returnStats.m_protocolErrorCount.SetValueNoLock(m_protocolErrorCount.GetValue());
return returnStats;
}
@ -271,7 +304,8 @@ namespace ctsTraffic { namespace ctsStatistics
ctsUdpStatistics& operator=(const ctsUdpStatistics&) = delete;
ctsUdpStatistics& operator=(ctsUdpStatistics&&) = delete;
[[nodiscard]] int64_t GetBytesReceived() const noexcept
// currently only called by the UDP client - only tracking the receives
[[nodiscard]] int64_t GetBytesTransferred() const noexcept
{
return m_bitsReceived.GetValue() / 8;
}
@ -286,24 +320,25 @@ namespace ctsTraffic { namespace ctsStatistics
m_startTime.SetPriorValue(currentTime) :
m_startTime.GetPriorValue();
// all writes to the local variable do not require Interlocked* semantics
ctsUdpStatistics returnStats(priorTimeRead);
returnStats.m_endTime.SetValue(currentTime);
returnStats.m_endTime.SetValueNoLock(currentTime);
if (clear_settings)
{
returnStats.m_bitsReceived.SetValue(m_bitsReceived.SnapValueDifference());
returnStats.m_successfulFrames.SetValue(m_successfulFrames.SnapValueDifference());
returnStats.m_droppedFrames.SetValue(m_droppedFrames.SnapValueDifference());
returnStats.m_duplicateFrames.SetValue(m_duplicateFrames.SnapValueDifference());
returnStats.m_errorFrames.SetValue(m_errorFrames.SnapValueDifference());
returnStats.m_bitsReceived.SetValueNoLock(m_bitsReceived.SnapValueDifference());
returnStats.m_successfulFrames.SetValueNoLock(m_successfulFrames.SnapValueDifference());
returnStats.m_droppedFrames.SetValueNoLock(m_droppedFrames.SnapValueDifference());
returnStats.m_duplicateFrames.SetValueNoLock(m_duplicateFrames.SnapValueDifference());
returnStats.m_errorFrames.SetValueNoLock(m_errorFrames.SnapValueDifference());
}
else
{
returnStats.m_bitsReceived.SetValue(m_bitsReceived.ReadValueDifference());
returnStats.m_successfulFrames.SetValue(m_successfulFrames.ReadValueDifference());
returnStats.m_droppedFrames.SetValue(m_droppedFrames.ReadValueDifference());
returnStats.m_duplicateFrames.SetValue(m_duplicateFrames.ReadValueDifference());
returnStats.m_errorFrames.SetValue(m_errorFrames.ReadValueDifference());
returnStats.m_bitsReceived.SetValueNoLock(m_bitsReceived.ReadValueDifference());
returnStats.m_successfulFrames.SetValueNoLock(m_successfulFrames.ReadValueDifference());
returnStats.m_droppedFrames.SetValueNoLock(m_droppedFrames.ReadValueDifference());
returnStats.m_duplicateFrames.SetValueNoLock(m_duplicateFrames.ReadValueDifference());
returnStats.m_errorFrames.SetValueNoLock(m_errorFrames.ReadValueDifference());
}
return returnStats;
@ -336,7 +371,7 @@ namespace ctsTraffic { namespace ctsStatistics
ctsTcpStatistics operator=(const ctsTcpStatistics&) = delete;
ctsTcpStatistics operator=(ctsTcpStatistics&&) = delete;
[[nodiscard]] int64_t GetBytesReceived() const noexcept
[[nodiscard]] int64_t GetBytesTransferred() const noexcept
{
return m_bytesRecv.GetValue() + m_bytesSent.GetValue();
}

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

@ -16,14 +16,14 @@ See the Apache Version 2.0 License for specific language governing permissions a
// os headers
#include <Windows.h>
#include <WinSock2.h>
// wil headers
#include <wil/stl.h>
#include <wil/resource.h>
// ctl headers
#include <ctString.hpp>
// project headers
#include "ctsSocket.h"
#include "ctsConfig.h"
// wil headers always included last
#include <wil/stl.h>
#include <wil/resource.h>
namespace ctsTraffic
{