2 // Copyright © 2019 Arm Ltd. All rights reserved.
3 // SPDX-License-Identifier: MIT
6 #include "PeriodicCounterCapture.hpp"
8 #include <boost/log/trivial.hpp>
17 void PeriodicCounterCapture::Start()
19 // Check if the capture thread is already running
22 // The capture thread is already running
26 // Mark the capture thread as running
29 // Keep the capture procedure going until the capture thread is signalled to stop
30 m_KeepRunning.store(true);
32 // Start the new capture thread.
33 m_PeriodCaptureThread = std::thread(&PeriodicCounterCapture::Capture, this, std::ref(m_ReadCounterValues));
36 void PeriodicCounterCapture::Stop()
38 // Signal the capture thread to stop
39 m_KeepRunning.store(false);
41 // Check that the capture thread is running
42 if (m_PeriodCaptureThread.joinable())
44 // Wait for the capture thread to complete operations
45 m_PeriodCaptureThread.join();
48 // Mark the capture thread as not running
52 CaptureData PeriodicCounterCapture::ReadCaptureData()
54 return m_CaptureDataHolder.GetCaptureData();
57 void PeriodicCounterCapture::Capture(const IReadCounterValues& readCounterValues)
61 // Check if the current capture data indicates that there's data capture
62 auto currentCaptureData = ReadCaptureData();
63 const std::vector<uint16_t>& counterIds = currentCaptureData.GetCounterIds();
65 if (currentCaptureData.GetCapturePeriod() == 0 || counterIds.empty())
67 // No data capture, wait the indicated capture period (milliseconds)
68 std::this_thread::sleep_for(std::chrono::milliseconds(5));
72 std::vector<std::pair<uint16_t, uint32_t>> values;
73 auto numCounters = counterIds.size();
74 values.reserve(numCounters);
76 // Create a vector of pairs of CounterIndexes and Values
77 for (uint16_t index = 0; index < numCounters; ++index)
79 auto requestedId = counterIds[index];
80 uint32_t counterValue = 0;
83 counterValue = readCounterValues.GetCounterValue(requestedId);
85 catch (const Exception& e)
87 // Report the error and continue
88 BOOST_LOG_TRIVIAL(warning) << "An error has occurred when getting a counter value: "
89 << e.what() << std::endl;
92 values.emplace_back(std::make_pair(requestedId, counterValue));
96 uint64_t timestamp = GetTimestamp();
98 // Write a Periodic Counter Capture packet to the Counter Stream Buffer
99 m_SendCounterPacket.SendPeriodicCounterCapturePacket(timestamp, values);
101 // Notify the Send Thread that new data is available in the Counter Stream Buffer
102 m_SendCounterPacket.SetReadyToRead();
104 // Wait the indicated capture period (microseconds)
105 std::this_thread::sleep_for(std::chrono::microseconds(currentCaptureData.GetCapturePeriod()));
108 while (m_KeepRunning.load());
111 } // namespace profiling