1 /* 2 * Copyright (c) 2021-2022 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 #ifndef SUBCOMMAND_STAT_H_ 16 #define SUBCOMMAND_STAT_H_ 17 18 #include "option.h" 19 #include "perf_events.h" 20 #include "subcommand.h" 21 22 namespace OHOS { 23 namespace Developtools { 24 namespace HiPerf { 25 class SubCommandStat : public SubCommand { 26 public: 27 static constexpr int DEFAULT_CHECK_APP_MS = 10; 28 static constexpr int MIN_CHECK_APP_MS = 1; 29 static constexpr int MAX_CHECK_APP_MS = 200; SubCommandStat()30 SubCommandStat() 31 : SubCommand("stat", "Collect performance counter information", 32 // clang-format off 33 "Usage: hiperf stat [options] [command [command-args]]\n" 34 " Collect performance counter information of running [command].\n" 35 " The default options are: -c -1 -d 10000.0\n" 36 " -a\n" 37 " Collect system-wide information.\n" 38 " for measures all processes/threads\n" 39 " This requires CAP_PERFMON (since Linux 5.8) or\n" 40 " CAP_SYS_ADMIN capability or a\n" 41 " /proc/sys/kernel/perf_event_paranoid value of less than 1.\n" 42 " -c <cpuid>[<,cpuid>]\n" 43 " cpuid should be 0,1,2...\n" 44 " Limit the CPU that collects data.\n" 45 " 0 means cpu0, 1 means cpu1 ...\n" 46 " -d <sec>\n" 47 " stop in <sec> seconds.\n" 48 " floating point number.\n" 49 " default is 10000.0\n" 50 " -i <ms>\n" 51 " print stat info every <ms>.\n" 52 " -e event1[:<u|k>][,event1[:<u|k>]]...\n" 53 " Customize the name of the event that needs to be counted.\n" 54 " The name can use the names listed in the list parameter.\n" 55 " It can also be represented by the value of 0x<hex>.\n" 56 " u - monitor user space events only\n" 57 " k - monitor kernel space events only\n" 58 " -g <event1[:<u|k>]>[,event1[:<u|k>]]...\n" 59 " The grouping function is added on the basis of the function of the -e parameter\n" 60 " PMU is required to report data in designated groups\n" 61 " limited by HW capability, too many events cannot be reported in the same sampling)\n" 62 " --no-inherit\n" 63 " Don't track new processes/threads.\n" 64 " -p <pid1>[,pid2]...\n" 65 " Limit the process id of the collection target. Conflicts with the -a option.\n" 66 " -t <tid1>[,tid2]...\n" 67 " Limit the thread id of the collection target. Conflicts with the -a option.\n" 68 " --app <package_name>\n" 69 " Collect profile info for an OHOS app, the app must be debuggable.\n" 70 " Record will exit if the process is not started within 10 seconds.\n" 71 " --chkms <millisec>\n" 72 " Set the interval of querying the <package_name>.\n" 73 " <millisec> is in range [1-200], default is 10.\n" 74 " --per-core\n" 75 " Print counters for each cpu core.\n" 76 " --per-thread\n" 77 " Print counters for each thread.\n" 78 " --restart\n" 79 " Collect performance counter information of application startup.\n" 80 " Record will exit if the process is not started within 30 seconds.\n" 81 " --verbose\n" 82 " Show more detailed reports.\n" 83 // clang-format on 84 ), 85 targetSystemWide_(false) 86 { 87 } 88 89 bool OnSubCommand(std::vector<std::string> &args) override; 90 bool ParseOption(std::vector<std::string> &args) override; 91 bool ParseSpecialOption(std::vector<std::string> &args); 92 void DumpOptions(void) const override; 93 94 private: 95 PerfEvents perfEvents_; 96 bool targetSystemWide_ {false}; 97 std::vector<int> selectCpus_ = {}; 98 float timeStopSec_ = PerfEvents::DEFAULT_TIMEOUT; 99 int timeReportMs_ {0}; 100 std::vector<std::vector<std::string>> selectEvents_; 101 std::vector<std::vector<std::string>> selectGroups_; 102 bool restart_ {false}; 103 bool noCreateNew_ {false}; 104 std::string appPackage_ = {}; 105 int checkAppMs_ = DEFAULT_CHECK_APP_MS; 106 std::vector<pid_t> selectPids_; 107 std::vector<pid_t> selectTids_; 108 bool perCpus_ {false}; 109 bool perThreads_ {false}; 110 bool verboseReport_ {false}; 111 std::vector<std::string> trackedCommand_ {}; 112 bool helpOption_ {false}; 113 bool CheckOptionPidAndApp(std::vector<pid_t> pids); 114 bool CheckOptionPid(std::vector<pid_t> pids); 115 static bool FindEventCount( 116 const std::map<std::string, std::unique_ptr<PerfEvents::CountEvent>> &countEvents, 117 const std::string &configName, const __u64 group_id, __u64 &eventcount, double &scale); 118 static void GetComments( 119 const std::map<std::string, std::unique_ptr<PerfEvents::CountEvent>> &countEvents, 120 std::map<std::string, std::string> &comments); 121 static bool FindRunningTime( 122 const std::map<std::string, std::unique_ptr<PerfEvents::CountEvent>> &countEvents, 123 double &running_time_in_sec, __u64 &group_id, double &main_scale); 124 static bool IsMonitoredAtAllTime(const double &scale); 125 static std::string GetCommentConfigName( 126 const std::unique_ptr<PerfEvents::CountEvent> &countEvent, std::string eventName); 127 128 static void Report(const std::map<std::string, std::unique_ptr<PerfEvents::CountEvent>> &countEvents); 129 static void PrintPerHead(); 130 static void GetPerKey(std::string &perKey, const PerfEvents::Summary &summary); 131 static void MakeComments(const std::unique_ptr<PerfEvents::ReportSum> &reportSum, std::string &commentStr); 132 static void ReportNormal(const std::map<std::string, std::unique_ptr<PerfEvents::CountEvent>> &countEvents); 133 static void ReportDetailInfos(const std::map<std::string, std::unique_ptr<PerfEvents::CountEvent>> &countEvents); 134 static void PrintPerValue(const std::unique_ptr<PerfEvents::ReportSum> &reportSum, const float &ratio, 135 std::string &configName); 136 static void InitPerMap(const std::unique_ptr<PerfEvents::ReportSum> &newPerMap, 137 const PerfEvents::Summary &summary, VirtualRuntime& virtualInstance); 138 static bool FindPerCoreEventCount(PerfEvents::Summary &summary, __u64 &eventCount, double &scale); 139 static bool FindPercoreRunningTime(PerfEvents::Summary &summary, double &running_time_in_sec, double &main_scale); 140 static std::string GetDetailComments(const std::unique_ptr<PerfEvents::CountEvent> &countEvent, double &comment, 141 PerfEvents::Summary &summary, std::string &configName); 142 static std::string HandleOtherConfig(double &comment, PerfEvents::Summary &summary, 143 double running_time_in_sec, double scale, bool findRunningTime); 144 145 void PrintUsage(); HelpOption()146 inline bool HelpOption() 147 { 148 return helpOption_; 149 } 150 bool PrepairEvents(); 151 bool CheckOptions(const std::vector<pid_t> &pids); 152 bool CheckSelectCpuPidOption(); 153 void SetReportFlags(bool cpuFlag, bool threadFlag); 154 void SetPerfEvent(); 155 }; 156 157 bool RegisterSubCommandStat(void); 158 } // namespace HiPerf 159 } // namespace Developtools 160 } // namespace OHOS 161 #endif // SUBCOMMAND_STAT_H_ 162