4#include "Stroika/Frameworks/StroikaPreComp.h"
8#include "Stroika/Foundation/Characters/FloatConversion.h"
12#include "Stroika/Foundation/Execution/CommandLine.h"
13#include "Stroika/Foundation/Execution/Process.h"
15#if qStroika_Foundation_Common_Platform_POSIX
16#include "Stroika/Foundation/Execution/SignalHandlers.h"
19#include "Stroika/Foundation/Execution/WaitableEvent.h"
20#include "Stroika/Foundation/Streams/MemoryStream.h"
22#include "Stroika/Frameworks/SystemPerformance/AllInstruments.h"
23#include "Stroika/Frameworks/SystemPerformance/Capturer.h"
24#include "Stroika/Frameworks/SystemPerformance/Instruments/CPU.h"
25#include "Stroika/Frameworks/SystemPerformance/Instruments/Memory.h"
26#include "Stroika/Frameworks/SystemPerformance/Instruments/Process.h"
27#include "Stroika/Frameworks/SystemPerformance/Measurement.h"
35using namespace Stroika::Frameworks;
36using namespace Stroika::Frameworks::SystemPerformance;
53 String result = String::FromUTF8 (out.
As<
string> ());
55 result = result.
StripAll ([] (
Character c) ->
bool {
return c ==
'\n' or c ==
'\r'; });
59#if qCompilerAndStdLib_template_template_argument_as_different_template_paramters_Buggy or qCompilerAndStdLib_template_template_auto_deduced_Buggy
65#if qCompilerAndStdLib_template_template_argument_as_different_template_paramters_Buggy or qCompilerAndStdLib_template_template_auto_deduced_Buggy
66 return Time::clock_cast<DisplayedRealtimeClock, RANGE_TEMPLATE_BWA> (tpRange);
68 return Time::clock_cast<DisplayedRealtimeClock> (tpRange);
71 void Demo_PrintInstruments_ ()
73 cout <<
"Instrument:" << endl;
74 for (
const Instrument& i : SystemPerformance::GetAllInstruments ()) {
75 cout <<
" " << i.instrumentName ().GetPrintName () << endl;
85 for (
const Instrument& i : SystemPerformance::GetAllInstruments ()) {
86 if (not run.
empty ()) {
87 if (not run.Contains (i.instrumentName)) {
93 capturer.AddCaptureSet (cs);
95 capturer.AddMeasurementsCallback ([oneLineMode] (
MeasurementSet ms) {
96 cout <<
" Measured-At: " << toDisp_ (ms.fMeasuredAt).ToString () << endl;
98 cout <<
" " << mi.fType.GetPrintName () <<
": " << Serialize_ (mi.fValue, oneLineMode) << endl;
107 cout <<
"Results for each instrument:" << endl;
108 for (
Instrument i : SystemPerformance::GetAllInstruments ()) {
109 if (not run.
empty ()) {
110 if (not run.Contains (i.instrumentName)) {
114 cout <<
" " << i.instrumentName ().GetPrintName () << endl;
115 Execution::Sleep (captureInterval);
117 if (m.fMeasurements.empty ()) {
118 cout <<
" NO DATA" << endl;
121 cout <<
" Measured-At: " << toDisp_ (m.fMeasuredAt).ToString () << endl;
123 cout <<
" " << mi.fType.GetPrintName () <<
": " << Serialize_ (mi.fValue, oneLineMode) << endl;
131 namespace Demo_Using_Capturer_GetMostRecentMeasurements__Private_ {
132 using namespace Stroika::Frameworks::SystemPerformance;
140 : fProcessInstrument{Instruments::Process::Options{.fRestrictToPIDs =
Set<
pid_t>{GetCurrentProcessID ()}}}
142 AddCaptureSet (
CaptureSet{30s, {fCPUInstrument, fProcessInstrument}});
146 void Demo_Using_Capturer_GetMostRecentMeasurements_ (
const Duration& runFor)
155 using namespace Demo_Using_Capturer_GetMostRecentMeasurements__Private_;
157 MyCapturer_ capturer;
161 cout <<
"Printing most recent measurements (in loop):" << endl;
162 while (Time::GetTickCount () < doneAt) {
163 auto measurements = capturer.pMostRecentMeasurements ();
164 DateTime now = DateTime::Now ();
166 optional<double> runQLength;
167 optional<double> totalCPUUsage;
168 optional<double> totalCPURatio;
169 if (
auto om = capturer.fCPUInstrument.MeasurementAs<Instruments::CPU::Info> (measurements)) {
170 runQLength = om->fRunQLength;
171 totalCPUUsage = om->fTotalCPUUsage;
172 totalCPURatio = om->GetTotalCPURatio ();
174 optional<Duration> thisProcUptime;
175 optional<Duration> thisProcAverageCPUTimeUsed;
176 optional<uint64_t> thisProcWorkingOrResidentSetSize;
177 optional<double> thisProcCombinedIORate;
180 Assert (om->size () <= 1);
181 if (om->size () == 1) {
183 if (
auto o = thisProcess.fProcessStartedAt) {
184 thisProcUptime = now - *o;
188 thisProcCombinedIORate = thisProcess.fCombinedIOWriteRate;
191 using namespace Memory;
192 cout <<
"\tPass: " << pass << endl;
193 cout <<
"\t\tSys: " << endl;
194 cout <<
"\t\t\tRun-Q Length: " << Characters::ToString (runQLength) << endl;
195 cout <<
"\t\t\tTotal CPU Usage: " << Characters::ToString (totalCPUUsage) <<
" ("
196 << Characters::ToString (totalCPURatio * 100.0) <<
"% of computer)" << endl;
197 cout <<
"\t\tThis Process: " << endl;
198 cout <<
"\t\t\tUptime: " << Characters::ToString (thisProcUptime) << endl;
199 cout <<
"\t\t\tAverage CPU Time Used: " << Characters::ToString (thisProcAverageCPUTimeUsed) << endl;
200 cout <<
"\t\t\tWorking Or Resident-Set Size: " << Characters::ToString (thisProcWorkingOrResidentSetSize) << endl;
201 cout <<
"\t\t\tCombined IO Rate: " << Characters::ToString (thisProcCombinedIORate) << endl;
202 Execution::Sleep (30s);
208int main (
int argc,
const char* argv[])
212#if qStroika_Foundation_Common_Platform_POSIX
215 using namespace StandardCommandLineOptions;
216 const CommandLine::Option kPrintNamesO_{.fSingleCharName =
'l', .fHelpOptionText =
"prints only the instrument names"sv};
217 const CommandLine::Option kMostRecentO_{.fSingleCharName =
'm', .fHelpOptionText =
"runs in most-recent-capture-mode"sv};
218 const CommandLine::Option kOneLineModeO_{.fSingleCharName =
'o', .fHelpOptionText =
"prints instrument results (with newlines stripped)"sv};
220 .fSupportsArgument =
true,
222 .fHelpArgName =
"RUN-INSTRUMENT"sv,
223 .fHelpOptionText =
"runs the given instrument (it can be repeated)"sv};
225 .fSingleCharName =
't', .fSupportsArgument =
true, .fHelpOptionText =
"time to run for (if zero run each matching instrument once)"sv};
227 .fSingleCharName =
'c', .fSupportsArgument =
true, .fHelpArgName =
"NSEC"sv, .fHelpOptionText =
"time interval between captures"sv};
229 const initializer_list<CommandLine::Option> kAllOptions_ = {
230 kHelp, kPrintNamesO_, kMostRecentO_, kOneLineModeO_, kRunInstrumentArg_, kRunForO_, kTimeBetweenCapturesO_};
232 bool printUsage = cmdLine.Has (kHelp);
233 bool mostRecentCaptureMode = cmdLine.Has (kMostRecentO_);
234 bool printNames = cmdLine.Has (kPrintNamesO_);
235 bool oneLineMode = cmdLine.Has (kOneLineModeO_);
237 if (
auto o = cmdLine.GetArgument (kRunForO_)) {
238 runFor =
Duration{Characters::FloatConversion::ToFloat<Duration::rep> (*o)};
241 if (
auto o = cmdLine.GetArgument (kTimeBetweenCapturesO_)) {
242 captureInterval =
Duration{Characters::FloatConversion::ToFloat<Duration::rep> (*o)};
248 cerr << cmdLine.GenerateUsage (kAllOptions_);
253 cmdLine.Validate (kAllOptions_);
255 Demo_PrintInstruments_ ();
257 else if (mostRecentCaptureMode) {
258 Demo_Using_Capturer_GetMostRecentMeasurements_ (runFor);
260 else if (runFor > 0s) {
261 Demo_UsingCapturerWithCallbacks_ (run, oneLineMode, captureInterval, runFor);
264 Demo_Using_Direct_Capture_On_Instrument_ (run, oneLineMode,
Duration{captureInterval});
268 cerr <<
"Error encountered: " << Characters::ToString (current_exception ()) << endl;
269 cerr << cmdLine.GenerateUsage (kAllOptions_) << endl;
273 String exceptMsg = Characters::ToString (current_exception ());
274 cerr <<
"Exception - " << exceptMsg.
AsNarrowSDKString () <<
" - terminating..." << endl;
time_point< RealtimeClock, DurationSeconds > TimePointSeconds
TimePointSeconds is a simpler approach to chrono::time_point, which doesn't require using templates e...
chrono::duration< double > DurationSeconds
chrono::duration<double> - a time span (length of time) measured in seconds, but high precision.
String is like std::u32string, except it is much easier to use, often much more space efficient,...
nonvirtual string AsNarrowSDKString() const
nonvirtual String StripAll(bool(*removeCharIf)(Character)) const
A generalization of a vector: a container whose elements are keyed by the natural numbers.
Set<T> is a container of T, where once an item is added, additionally adds () do nothing.
nonvirtual RESULT_CONTAINER Map(ELEMENT_MAPPER &&elementMapper) const
'override' Iterable<>::Map () function so RESULT_CONTAINER defaults to Set, and improve that case to ...
An Atom is like a String, except that its much cheaper to copy/store/compare, and the semantics of co...
nonvirtual void Write(const VariantValue &v, const Streams::OutputStream::Ptr< byte > &out) const
Simple variant-value (case variant union) object, with (variant) basic types analogous to a value in ...
nonvirtual void SetSignalHandlers(SignalID signal)
static const SignalHandler kIGNORED
static SignalHandlerRegistry sThe
nonvirtual void Wait(Time::DurationSeconds timeout=Time::kInfinity)
Duration is a chrono::duration<double> (=.
nonvirtual bool empty() const
Returns true iff size() == 0.
Create a format-string (see std::wformat_string or Stroika FormatString, or python 'f' strings.
int pid_t
TODO - maybe move this to configuraiotn module???