/* * Copyright (c) 2021-2022 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef SUBCOMMAND_STAT_H_ #define SUBCOMMAND_STAT_H_ #include "option.h" #include "perf_events.h" #include "subcommand.h" namespace OHOS { namespace Developtools { namespace HiPerf { class SubCommandStat : public SubCommand { public: static constexpr int DEFAULT_CHECK_APP_MS = 10; static constexpr int MIN_CHECK_APP_MS = 1; static constexpr int MAX_CHECK_APP_MS = 200; SubCommandStat() : SubCommand("stat", "Collect performance counter information", // clang-format off "Usage: hiperf stat [options] [command [command-args]]\n" " Collect performance counter information of running [command].\n" " The default options are: -c -1 -d 10000.0\n" " -a\n" " Collect system-wide information.\n" " for measures all processes/threads\n" " This requires CAP_PERFMON (since Linux 5.8) or\n" " CAP_SYS_ADMIN capability or a\n" " /proc/sys/kernel/perf_event_paranoid value of less than 1.\n" " -c [<,cpuid>]\n" " cpuid should be 0,1,2...\n" " Limit the CPU that collects data.\n" " 0 means cpu0, 1 means cpu1 ...\n" " -d \n" " stop in seconds.\n" " floating point number.\n" " default is 10000.0\n" " -i \n" " print stat info every .\n" " -e event1[:][,event1[:]]...\n" " Customize the name of the event that needs to be counted.\n" " The name can use the names listed in the list parameter.\n" " It can also be represented by the value of 0x.\n" " u - monitor user space events only\n" " k - monitor kernel space events only\n" " -g ]>[,event1[:]]...\n" " The grouping function is added on the basis of the function of the -e parameter\n" " PMU is required to report data in designated groups\n" " limited by HW capability, too many events cannot be reported in the same sampling)\n" " --no-inherit\n" " Don't track new processes/threads.\n" " -p [,pid2]...\n" " Limit the process id of the collection target. Conflicts with the -a option.\n" " -t [,tid2]...\n" " Limit the thread id of the collection target. Conflicts with the -a option.\n" " --app \n" " Collect profile info for an OHOS app, the app must be debuggable.\n" " Record will exit if the process is not started within 10 seconds.\n" " --chkms \n" " Set the interval of querying the .\n" " is in range [1-200], default is 10.\n" " --per-core\n" " Print counters for each cpu core.\n" " --per-thread\n" " Print counters for each thread.\n" " --restart\n" " Collect performance counter information of application startup.\n" " Record will exit if the process is not started within 30 seconds.\n" " --verbose\n" " Show more detailed reports.\n" " --dumpoptions\n" " Dump command options.\n" // clang-format on ), targetSystemWide_(false) { } HiperfError OnSubCommand(std::vector& args) override; bool ParseOption(std::vector &args) override; bool ParseSpecialOption(std::vector &args); void DumpOptions(void) const override; // add args for hisysevent void AddReportArgs(CommandReporter& reporter) override; static SubCommand& GetInstance(); private: PerfEvents perfEvents_; bool targetSystemWide_ {false}; std::vector selectCpus_ = {}; float timeStopSec_ = PerfEvents::DEFAULT_TIMEOUT; int timeReportMs_ {0}; std::vector> selectEvents_; std::vector> selectGroups_; bool restart_ {false}; bool noCreateNew_ {false}; std::string appPackage_ = {}; int checkAppMs_ = DEFAULT_CHECK_APP_MS; std::vector selectPids_; std::vector selectTids_; std::vector inputPidTidArgs_ = {}; bool perCpus_ {false}; bool perThreads_ {false}; bool verboseReport_ {false}; std::vector trackedCommand_ {}; bool helpOption_ {false}; bool CheckOptionPidAndApp(std::vector pids); bool CheckOptionPid(std::vector pids); static bool FindEventCount( const std::map> &countEvents, const std::string &configName, const __u64 group_id, __u64 &eventcount, double &scale); static void GetComments( const std::map> &countEvents, std::map &comments); static bool FindRunningTime( const std::map> &countEvents, double &running_time_in_sec, __u64 &group_id, double &main_scale); static bool IsMonitoredAtAllTime(const double &scale); static std::string GetCommentConfigName( const std::unique_ptr &countEvent, std::string eventName); static void Report(const std::map> &countEvents); static void PrintPerHead(); static void GetPerKey(std::string &perKey, const PerfEvents::Summary &summary); static void MakeComments(const std::unique_ptr &reportSum, std::string &commentStr); static void ReportNormal(const std::map> &countEvents); static void ReportDetailInfos(const std::map> &countEvents); static void PrintPerValue(const std::unique_ptr &reportSum, const float &ratio, std::string &configName); static void InitPerMap(const std::unique_ptr &newPerMap, const PerfEvents::Summary &summary, VirtualRuntime& virtualInstance); static bool FindPerCoreEventCount(PerfEvents::Summary &summary, __u64 &eventCount, double &scale); static bool FindPercoreRunningTime(PerfEvents::Summary &summary, double &running_time_in_sec, double &main_scale); static std::string GetDetailComments(const std::unique_ptr &countEvent, double &comment, PerfEvents::Summary &summary, std::string &configName); static std::string HandleOtherConfig(double &comment, PerfEvents::Summary &summary, double running_time_in_sec, double scale, bool findRunningTime); void PrintUsage(); inline bool HelpOption() { return helpOption_; } bool PrepairEvents(); bool CheckOptions(const std::vector &pids); bool CheckSelectCpuPidOption(); void SetReportFlags(bool cpuFlag, bool threadFlag); void SetPerfEvent(); }; bool RegisterSubCommandStat(void); } // namespace HiPerf } // namespace Developtools } // namespace OHOS #endif // SUBCOMMAND_STAT_H_