diff options
Diffstat (limited to 'profiling/client/src/PeriodicCounterCapture.cpp')
-rw-r--r-- | profiling/client/src/PeriodicCounterCapture.cpp | 139 |
1 files changed, 139 insertions, 0 deletions
diff --git a/profiling/client/src/PeriodicCounterCapture.cpp b/profiling/client/src/PeriodicCounterCapture.cpp new file mode 100644 index 0000000000..490173c7e0 --- /dev/null +++ b/profiling/client/src/PeriodicCounterCapture.cpp @@ -0,0 +1,139 @@ +// +// Copyright © 2019 Arm Ltd. All rights reserved. +// SPDX-License-Identifier: MIT +// + +#include "PeriodicCounterCapture.hpp" + +#include <common/include/Logging.hpp> + +#include <iostream> + +namespace arm +{ + +namespace pipe +{ + +void PeriodicCounterCapture::Start() +{ + // Check if the capture thread is already running + if (m_IsRunning) + { + // The capture thread is already running + return; + } + + // Mark the capture thread as running + m_IsRunning = true; + + // Keep the capture procedure going until the capture thread is signalled to stop + m_KeepRunning.store(true); + + // Start the new capture thread. + m_PeriodCaptureThread = std::thread(&PeriodicCounterCapture::Capture, this, std::ref(m_ReadCounterValues)); +} + +void PeriodicCounterCapture::Stop() +{ + // Signal the capture thread to stop + m_KeepRunning.store(false); + + // Check that the capture thread is running + if (m_PeriodCaptureThread.joinable()) + { + // Wait for the capture thread to complete operations + m_PeriodCaptureThread.join(); + } + + // Mark the capture thread as not running + m_IsRunning = false; +} + +CaptureData PeriodicCounterCapture::ReadCaptureData() +{ + return m_CaptureDataHolder.GetCaptureData(); +} + +void PeriodicCounterCapture::DispatchPeriodicCounterCapturePacket( + const std::string& backendId, const std::vector<Timestamp>& timestampValues) +{ + // Report counter values + for (const auto& timestampInfo : timestampValues) + { + std::vector<CounterValue> backendCounterValues = timestampInfo.counterValues; + for_each(backendCounterValues.begin(), backendCounterValues.end(), [&](CounterValue& backendCounterValue) + { + // translate the counterId to globalCounterId + backendCounterValue.counterId = m_CounterIdMap.GetGlobalId(backendCounterValue.counterId, backendId); + }); + + // Send Periodic Counter Capture Packet for the Timestamp + m_SendCounterPacket.SendPeriodicCounterCapturePacket(timestampInfo.timestamp, backendCounterValues); + } +} + +void PeriodicCounterCapture::Capture(IReadCounterValues& readCounterValues) +{ + do + { + // Check if the current capture data indicates that there's data capture + auto currentCaptureData = ReadCaptureData(); + const std::vector<uint16_t>& counterIds = currentCaptureData.GetCounterIds(); + const uint32_t capturePeriod = currentCaptureData.GetCapturePeriod(); + + if (capturePeriod == 0) + { + // No data capture, wait the indicated capture period (milliseconds), if it is not zero + std::this_thread::sleep_for(std::chrono::milliseconds(50u)); + continue; + } + + if(counterIds.size() != 0) + { + std::vector<CounterValue> counterValues; + + auto numCounters = counterIds.size(); + counterValues.reserve(numCounters); + + // Create a vector of pairs of CounterIndexes and Values + for (uint16_t index = 0; index < numCounters; ++index) + { + auto requestedId = counterIds[index]; + uint32_t counterValue = 0; + try + { + counterValue = readCounterValues.GetDeltaCounterValue(requestedId); + } + catch (const arm::pipe::ProfilingException& e) + { + // Report the error and continue + ARM_PIPE_LOG(warning) << "An error has occurred when getting a counter value: " + << e.what(); + continue; + } + + counterValues.emplace_back(CounterValue {requestedId, counterValue }); + } + + // Send Periodic Counter Capture Packet for the Timestamp + m_SendCounterPacket.SendPeriodicCounterCapturePacket(GetTimestamp(), counterValues); + } + + // Report counter values for each active backend + auto activeBackends = currentCaptureData.GetActiveBackends(); + for_each(activeBackends.begin(), activeBackends.end(), [&](const std::string& backendId) + { + DispatchPeriodicCounterCapturePacket( + backendId, m_BackendProfilingContexts.at(backendId)->ReportCounterValues()); + }); + + // Wait the indicated capture period (microseconds) + std::this_thread::sleep_for(std::chrono::microseconds(capturePeriod)); + } + while (m_KeepRunning.load()); +} + +} // namespace pipe + +} // namespace arm |