mirror of
https://gitee.com/openharmony/developtools_hiperf
synced 2024-11-27 01:30:28 +00:00
Signed-off-by: sunshuaiyuan <sunshuaiyuan@huawei.com>
This commit is contained in:
parent
ca089319e4
commit
b47f5baede
@ -388,11 +388,38 @@ public:
|
||||
{
|
||||
clockId_ = clockId;
|
||||
};
|
||||
void SetPerCpu(bool perCpu);
|
||||
void SetPerThread(bool perThread);
|
||||
bool SetBranchSampleType(uint64_t value);
|
||||
bool AddDefaultEvent(perf_type_id type);
|
||||
|
||||
std::map<__u64, std::string> GetSupportEvents(perf_type_id type);
|
||||
|
||||
struct Summary {
|
||||
int cpu;
|
||||
pid_t tid;
|
||||
__u64 eventCount = 0;
|
||||
__u64 time_enabled = 0;
|
||||
__u64 time_running = 0;
|
||||
Summary(const int cpu, const pid_t tid, const __u64 eventCount,
|
||||
const __u64 time_enabled, const __u64 time_running)
|
||||
: cpu(cpu), tid(tid), eventCount(eventCount), time_enabled(time_enabled), time_running(time_running)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
struct ReportSum {
|
||||
int cpu;
|
||||
pid_t pid;
|
||||
pid_t tid;
|
||||
double scaleSum = 1.0;
|
||||
double commentSum = 0;
|
||||
__u64 eventCountSum = 0;
|
||||
__u64 enabledSum = 0;
|
||||
__u64 runningSum = 0;
|
||||
std::string configName = "";
|
||||
std::string threadName = "";
|
||||
};
|
||||
struct CountEvent {
|
||||
bool userOnly = false;
|
||||
bool kernelOnly = false;
|
||||
@ -401,6 +428,7 @@ public:
|
||||
__u64 time_running = 0;
|
||||
__u64 id = 0;
|
||||
double used_cpus = 0;
|
||||
std::vector<Summary> summaries;
|
||||
};
|
||||
using StatCallBack =
|
||||
std::function<void(const std::map<std::string, std::unique_ptr<PerfEvents::CountEvent>> &)>;
|
||||
@ -516,6 +544,8 @@ private:
|
||||
std::vector<OHOS::UniqueFd> groups_;
|
||||
std::chrono::milliseconds timeOut_; // milliseconds
|
||||
std::chrono::milliseconds timeReport_; // means same as timeOut
|
||||
bool perCpu_ = false;
|
||||
bool perThread_ = false;
|
||||
bool verboseReport_ = false;
|
||||
bool prepared_ = false;
|
||||
ConfigTable traceConfigTable;
|
||||
|
@ -71,6 +71,10 @@ public:
|
||||
" --chkms <millisec>\n"
|
||||
" Set the interval of querying the <package_name>.\n"
|
||||
" <millisec> 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"
|
||||
@ -84,6 +88,7 @@ public:
|
||||
|
||||
bool OnSubCommand(std::vector<std::string> &args) override;
|
||||
bool ParseOption(std::vector<std::string> &args) override;
|
||||
bool ParseSpecialOption(std::vector<std::string> &args);
|
||||
void DumpOptions(void) const override;
|
||||
|
||||
private:
|
||||
@ -100,6 +105,8 @@ private:
|
||||
int checkAppMs_ = DEFAULT_CHECK_APP_MS;
|
||||
std::vector<pid_t> selectPids_;
|
||||
std::vector<pid_t> selectTids_;
|
||||
bool perCpus_ {false};
|
||||
bool perThreads_ {false};
|
||||
bool verboseReport_ {false};
|
||||
std::vector<std::string> trackedCommand_ {};
|
||||
bool helpOption_ {false};
|
||||
@ -118,7 +125,22 @@ private:
|
||||
static std::string GetCommentConfigName(
|
||||
const std::unique_ptr<PerfEvents::CountEvent> &countEvent, std::string eventName);
|
||||
|
||||
static void Report(const std::map<std::string, std::unique_ptr<PerfEvents::CountEvent>> &);
|
||||
static void Report(const std::map<std::string, std::unique_ptr<PerfEvents::CountEvent>> &countEvents);
|
||||
static void PrintPerHead();
|
||||
static void GetPerKey(std::string &perKey, const PerfEvents::Summary &summary);
|
||||
static void FormatComments(const std::unique_ptr<PerfEvents::ReportSum> &reportSum, std::string &commentStr);
|
||||
static void ReportNormal(const std::map<std::string, std::unique_ptr<PerfEvents::CountEvent>> &countEvents);
|
||||
static void ReportDetailInfos(const std::map<std::string, std::unique_ptr<PerfEvents::CountEvent>> &countEvents);
|
||||
static void PrintPerValue(const std::unique_ptr<PerfEvents::ReportSum> &reportSum, const float &ratio,
|
||||
std::string &configName);
|
||||
static void InitPerMap(const std::unique_ptr<PerfEvents::ReportSum> &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<PerfEvents::CountEvent> &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()
|
||||
@ -128,6 +150,7 @@ private:
|
||||
bool PrepairEvents();
|
||||
bool CheckOptions(const std::vector<pid_t> &pids);
|
||||
bool CheckSelectCpuPidOption();
|
||||
void SetReportFlags(bool cpuFlag, bool threadFlag);
|
||||
};
|
||||
|
||||
bool RegisterSubCommandStat(void);
|
||||
|
@ -98,6 +98,10 @@ static const std::string USER_TYPE_PARAM_GET = "";
|
||||
static FILE *outputDump_ = nullptr;
|
||||
const uint64_t waitAppRunCheckTimeOut = 10;
|
||||
|
||||
struct ThreadInfos {
|
||||
pid_t tid;
|
||||
pid_t pid;
|
||||
};
|
||||
// string function
|
||||
class MemoryHold {
|
||||
public:
|
||||
@ -206,6 +210,7 @@ std::string StringPrintf(const char *stringFormat, VA... args)
|
||||
std::vector<std::string> GetEntriesInDir(const std::string &basePath);
|
||||
|
||||
std::vector<std::string> GetSubDirs(const std::string &basePath);
|
||||
std::vector<pid_t> GetSubthreadIDs(const pid_t pid, std::map<pid_t, ThreadInfos> &thread_map);
|
||||
|
||||
bool IsDir(const std::string &path);
|
||||
|
||||
@ -319,6 +324,8 @@ bool PowerOfTwo(uint64_t n);
|
||||
#endif
|
||||
pid_t GetAppPackagePid(const std::string &appPackage, const pid_t oldPid, const int checkAppMs,
|
||||
const uint64_t waitAppTimeOut);
|
||||
bool IsNeedCheckSamePid(const std::string &fileName, const std::string &appPackage, const std::string &subDir,
|
||||
pid_t &res, const pid_t oldPid);
|
||||
bool CheckAppIsRunning (std::vector<pid_t> &selectPids, const std::string &appPackage, int checkAppMs);
|
||||
bool IsExistDebugByApp(const std::string& bundleName);
|
||||
bool IsExistDebugByPid(const std::vector<pid_t> pids);
|
||||
|
@ -719,6 +719,16 @@ void PerfEvents::LoadTracepointEventTypesFromSystem()
|
||||
}
|
||||
}
|
||||
|
||||
void PerfEvents::SetPerCpu(bool perCpu)
|
||||
{
|
||||
perCpu_ = perCpu;
|
||||
}
|
||||
|
||||
void PerfEvents::SetPerThread(bool perThread)
|
||||
{
|
||||
perThread_ = perThread;
|
||||
}
|
||||
|
||||
void PerfEvents::SetVerboseReport(bool verboseReport)
|
||||
{
|
||||
verboseReport_ = verboseReport;
|
||||
@ -829,7 +839,10 @@ bool PerfEvents::PrepareFdEvents(void)
|
||||
pids_.push_back(0); // no pid means use 0 as self pid
|
||||
}
|
||||
}
|
||||
|
||||
if (perCpu_ || perThread_) {
|
||||
cpus_.clear();
|
||||
PutAllCpus();
|
||||
}
|
||||
if (cpus_.empty()) {
|
||||
PutAllCpus();
|
||||
}
|
||||
@ -1024,6 +1037,10 @@ bool PerfEvents::StatReport(const __u64 &durationInSec)
|
||||
fditem.pid, readNoGroupValue.time_enabled,
|
||||
readNoGroupValue.time_running, readNoGroupValue.value);
|
||||
}
|
||||
if ((perCpu_ || perThread_) && readNoGroupValue.value) {
|
||||
countEvent->summaries.emplace_back(fditem.cpu, fditem.pid, readNoGroupValue.value,
|
||||
readNoGroupValue.time_enabled, readNoGroupValue.time_running);
|
||||
}
|
||||
} else {
|
||||
printf("read failed from event '%s'\n", eventItem.configName.c_str());
|
||||
}
|
||||
|
@ -29,6 +29,10 @@ const uint16_t THOUSNADS_SEPARATOR = 3;
|
||||
namespace OHOS {
|
||||
namespace Developtools {
|
||||
namespace HiPerf {
|
||||
static std::map<pid_t, ThreadInfos> thread_map_;
|
||||
static bool g_reportCpuFlag = false;
|
||||
static bool g_reportThreadFlag = false;
|
||||
static VirtualRuntime runtimeInstance_;
|
||||
void SubCommandStat::DumpOptions() const
|
||||
{
|
||||
printf("DumpOptions:\n");
|
||||
@ -44,6 +48,8 @@ void SubCommandStat::DumpOptions() const
|
||||
printf(" selectPids:\t%s\n", VectorToString(selectPids_).c_str());
|
||||
printf(" selectTids:\t%s\n", VectorToString(selectTids_).c_str());
|
||||
printf(" restart:\t%s\n", restart_ ? "true" : "false");
|
||||
printf(" perCore:\t%s\n", perCpus_ ? "true" : "false");
|
||||
printf(" perTread:\t%s\n", perThreads_ ? "true" : "false");
|
||||
printf(" verbose:\t%s\n", verboseReport_ ? "true" : "false");
|
||||
}
|
||||
|
||||
@ -113,10 +119,23 @@ bool SubCommandStat::ParseOption(std::vector<std::string> &args)
|
||||
HLOGD("get option --restart failed");
|
||||
return false;
|
||||
}
|
||||
if (!Option::GetOptionValue(args, "--per-core", perCpus_)) {
|
||||
HLOGD("get option --per-core failed");
|
||||
return false;
|
||||
}
|
||||
if (!Option::GetOptionValue(args, "--per-thread", perThreads_)) {
|
||||
HLOGD("get option --per-thread failed");
|
||||
return false;
|
||||
}
|
||||
if (!Option::GetOptionValue(args, "--verbose", verboseReport_)) {
|
||||
HLOGD("get option --verbose failed");
|
||||
return false;
|
||||
}
|
||||
return ParseSpecialOption(args);
|
||||
}
|
||||
|
||||
bool SubCommandStat::ParseSpecialOption(std::vector<std::string> &args)
|
||||
{
|
||||
if (!Option::GetOptionTrackedCommand(args, trackedCommand_)) {
|
||||
HLOGD("get cmd failed");
|
||||
return false;
|
||||
@ -133,19 +152,146 @@ void SubCommandStat::PrintUsage()
|
||||
printf("%s\n", Help().c_str());
|
||||
}
|
||||
|
||||
void SubCommandStat::Report(
|
||||
void SubCommandStat::SetReportFlags(bool cpuFlag, bool threadFlag)
|
||||
{
|
||||
g_reportCpuFlag = cpuFlag;
|
||||
g_reportThreadFlag = threadFlag;
|
||||
}
|
||||
|
||||
void SubCommandStat::Report(const std::map<std::string, std::unique_ptr<PerfEvents::CountEvent>> &countEvents)
|
||||
{
|
||||
bool isNeedPerCpuTid = false;
|
||||
for (auto it = countEvents.begin(); it != countEvents.end(); ++it) {
|
||||
if (!(it->second->summaries.empty())) {
|
||||
isNeedPerCpuTid = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (isNeedPerCpuTid) {
|
||||
PrintPerHead();
|
||||
ReportDetailInfos(countEvents);
|
||||
} else {
|
||||
ReportNormal(countEvents);
|
||||
}
|
||||
}
|
||||
|
||||
void SubCommandStat::PrintPerHead()
|
||||
{
|
||||
// print head
|
||||
if (g_reportCpuFlag && g_reportThreadFlag) {
|
||||
printf(" %24s %-30s | %-30s %10s %10s %10s | %-32s | %s\n", "count", "event_name", "thread_name",
|
||||
"pid", "tid", "coreid", "comment", "coverage");
|
||||
return;
|
||||
}
|
||||
if (g_reportCpuFlag) {
|
||||
printf(" %24s %-30s | %10s | %-32s | %s\n", "count", "event_name", "coreid", "comment", "coverage");
|
||||
return;
|
||||
}
|
||||
printf(" %24s %-30s | %-30s %10s %10s | %-32s | %s\n", "count", "event_name", "thread_name", "pid", "tid",
|
||||
"comment", "coverage");
|
||||
return;
|
||||
}
|
||||
|
||||
void SubCommandStat::PrintPerValue(const std::unique_ptr<PerfEvents::ReportSum> &reportSum, const float &ratio,
|
||||
std::string &configName)
|
||||
{
|
||||
// print value
|
||||
std::string strEventCount = std::to_string(reportSum->eventCountSum);
|
||||
for (size_t i = strEventCount.size() - 1, j = 1; i > 0; --i, ++j) {
|
||||
if (j == THOUSNADS_SEPARATOR) {
|
||||
strEventCount.insert(strEventCount.begin() + i, ',');
|
||||
j = 0;
|
||||
}
|
||||
}
|
||||
std::string commentStr;
|
||||
FormatComments(reportSum, commentStr);
|
||||
if (g_reportCpuFlag && g_reportThreadFlag) {
|
||||
printf(" %24s %-30s | %-30s %10d %10d %10d | %-32s | (%.0lf%%)\n", strEventCount.c_str(), configName.c_str(),
|
||||
reportSum->threadName.c_str(), reportSum->pid, reportSum->tid, reportSum->cpu, commentStr.c_str(),
|
||||
reportSum->scaleSum * ratio);
|
||||
} else if (g_reportCpuFlag) {
|
||||
printf(" %24s %-30s | %10d | %-32s | (%.0lf%%)\n", strEventCount.c_str(), configName.c_str(),
|
||||
reportSum->cpu, commentStr.c_str(), reportSum->scaleSum * ratio);
|
||||
} else {
|
||||
printf(" %24s %-30s | %-30s %10d %10d | %-32s | (%.0lf%%)\n", strEventCount.c_str(), configName.c_str(),
|
||||
reportSum->threadName.c_str(), reportSum->pid, reportSum->tid, commentStr.c_str(),
|
||||
reportSum->scaleSum * ratio);
|
||||
}
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
void SubCommandStat::InitPerMap(const std::unique_ptr<PerfEvents::ReportSum> &newPerMap,
|
||||
const PerfEvents::Summary &summary, VirtualRuntime& virtualInstance)
|
||||
{
|
||||
newPerMap->cpu = summary.cpu;
|
||||
if (g_reportCpuFlag && !g_reportThreadFlag) {
|
||||
return;
|
||||
}
|
||||
newPerMap->tid = summary.tid;
|
||||
newPerMap->pid = thread_map_.find(summary.tid)->second.pid;
|
||||
bool isTid = true;
|
||||
if (newPerMap->pid == newPerMap->tid) {
|
||||
isTid = false;
|
||||
}
|
||||
newPerMap->threadName = virtualInstance.ReadThreadName(summary.tid, isTid);
|
||||
}
|
||||
|
||||
void SubCommandStat::GetPerKey(std::string &perKey, const PerfEvents::Summary &summary)
|
||||
{
|
||||
perKey = "";
|
||||
if (g_reportCpuFlag) {
|
||||
perKey += std::to_string(summary.cpu);
|
||||
}
|
||||
if (g_reportThreadFlag) {
|
||||
perKey += std::to_string(summary.tid);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void SubCommandStat::ReportDetailInfos(
|
||||
const std::map<std::string, std::unique_ptr<PerfEvents::CountEvent>> &countEvents)
|
||||
{
|
||||
// head
|
||||
printf(" %24s %-30s | %-32s | %s\n", "count", "name", "comment", "coverage");
|
||||
std::string perKey = "";
|
||||
std::map<std::string, std::unique_ptr<PerfEvents::ReportSum>> perMaps;
|
||||
for (auto event = countEvents.begin(); event != countEvents.end(); ++event) {
|
||||
if (event->second->eventCount == 0) {
|
||||
continue;
|
||||
}
|
||||
double scale = 1.0;
|
||||
constexpr float ratio {100.0};
|
||||
std::string configName = event->first;
|
||||
perMaps.clear();
|
||||
for (auto &it : event->second->summaries) {
|
||||
GetPerKey(perKey, it);
|
||||
if (perMaps.count(perKey) == 0) {
|
||||
auto perMap = std::make_unique<PerfEvents::ReportSum>(PerfEvents::ReportSum {});
|
||||
InitPerMap(perMap, it, runtimeInstance_);
|
||||
perMaps[perKey] = std::move(perMap);
|
||||
}
|
||||
perMaps[perKey]->configName = GetDetailComments(event->second, perMaps[perKey]->commentSum,
|
||||
it, configName);
|
||||
perMaps[perKey]->eventCountSum += it.eventCount;
|
||||
if (it.time_running < it.time_enabled && it.time_running != 0) {
|
||||
perMaps[perKey]->scaleSum += 1 / (static_cast<double>(it.time_enabled) / it.time_running);
|
||||
}
|
||||
}
|
||||
for (auto iper = perMaps.begin(); iper != perMaps.end(); iper++) {
|
||||
PrintPerValue(iper->second, ratio, configName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SubCommandStat::ReportNormal(
|
||||
const std::map<std::string, std::unique_ptr<PerfEvents::CountEvent>> &countEvents)
|
||||
{
|
||||
// print head
|
||||
std::map<std::string, std::string> comments;
|
||||
GetComments(countEvents, comments);
|
||||
for (auto it = countEvents.begin(); it != countEvents.end(); it++) {
|
||||
for (auto it = countEvents.begin(); it != countEvents.end(); ++it) {
|
||||
double scale = 1.0;
|
||||
constexpr float ratio {100.0};
|
||||
std::string configName = it->first;
|
||||
std::string comment = comments[configName];
|
||||
constexpr float ratio {100.0};
|
||||
std::string strEventCount = std::to_string(it->second->eventCount);
|
||||
for (size_t i = strEventCount.size() - 1, j = 1; i > 0; --i, ++j) {
|
||||
if (j == THOUSNADS_SEPARATOR) {
|
||||
@ -163,8 +309,7 @@ void SubCommandStat::Report(
|
||||
}
|
||||
}
|
||||
|
||||
bool SubCommandStat::FindEventCount(
|
||||
const std::map<std::string, std::unique_ptr<PerfEvents::CountEvent>> &countEvents,
|
||||
bool SubCommandStat::FindEventCount(const std::map<std::string, std::unique_ptr<PerfEvents::CountEvent>> &countEvents,
|
||||
const std::string &configName, const __u64 group_id, __u64 &eventCount, double &scale)
|
||||
{
|
||||
auto itr = countEvents.find(configName);
|
||||
@ -180,6 +325,16 @@ bool SubCommandStat::FindEventCount(
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SubCommandStat::FindPerCoreEventCount(PerfEvents::Summary &summary, __u64 &eventCount, double &scale)
|
||||
{
|
||||
eventCount = summary.eventCount;
|
||||
if (summary.time_running < summary.time_enabled && summary.time_running != 0) {
|
||||
scale = static_cast<double>(summary.time_enabled) / summary.time_running;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string SubCommandStat::GetCommentConfigName(
|
||||
const std::unique_ptr<PerfEvents::CountEvent> &countEvent, std::string eventName)
|
||||
{
|
||||
@ -197,6 +352,109 @@ std::string SubCommandStat::GetCommentConfigName(
|
||||
return commentConfigName;
|
||||
}
|
||||
|
||||
void SubCommandStat::FormatComments(const std::unique_ptr<PerfEvents::ReportSum> &reportSum, std::string &commentStr)
|
||||
{
|
||||
if (reportSum->commentSum == 0) {
|
||||
return;
|
||||
}
|
||||
if (reportSum->configName == "sw-task-clock") {
|
||||
commentStr = StringPrintf("%lf cpus used", reportSum->commentSum);
|
||||
return;
|
||||
}
|
||||
if (reportSum->configName == "hw-cpu-cycles") {
|
||||
commentStr = StringPrintf("%lf GHz", reportSum->commentSum);
|
||||
return;
|
||||
}
|
||||
if (reportSum->configName == "hw-instructions") {
|
||||
commentStr = StringPrintf("%lf cycles per instruction", reportSum->commentSum);
|
||||
return;
|
||||
}
|
||||
if (reportSum->configName == "hw-branch-misses") {
|
||||
commentStr = StringPrintf("%lf miss rate", reportSum->commentSum);
|
||||
return;
|
||||
}
|
||||
|
||||
if (reportSum->commentSum > 1e9) {
|
||||
commentStr = StringPrintf("%.3lf G/sec", reportSum->commentSum / 1e9);
|
||||
return;
|
||||
}
|
||||
if (reportSum->commentSum > 1e6) {
|
||||
commentStr = StringPrintf("%.3lf M/sec", reportSum->commentSum / 1e6);
|
||||
return;
|
||||
}
|
||||
if (reportSum->commentSum > 1e3) {
|
||||
commentStr = StringPrintf("%.3lf K/sec", reportSum->commentSum / 1e3);
|
||||
return;
|
||||
}
|
||||
commentStr = StringPrintf("%.3lf /sec", reportSum->commentSum);
|
||||
}
|
||||
|
||||
std::string SubCommandStat::GetDetailComments(const std::unique_ptr<PerfEvents::CountEvent> &countEvent,
|
||||
double &comment, PerfEvents::Summary &summary, std::string &configName)
|
||||
{
|
||||
double running_time_in_sec = 0;
|
||||
double main_scale = 1.0;
|
||||
bool findRunningTime = FindPercoreRunningTime(summary, running_time_in_sec, main_scale);
|
||||
if (configName == GetCommentConfigName(countEvent, "sw-cpu-clock")) {
|
||||
comment = 0;
|
||||
return "sw-cpu-clock";
|
||||
}
|
||||
double scale = 1.0;
|
||||
if (summary.time_running < summary.time_enabled && summary.time_running != 0) {
|
||||
scale = static_cast<double>(summary.time_enabled) / summary.time_running;
|
||||
}
|
||||
if (configName == GetCommentConfigName(countEvent, "sw-task-clock")) {
|
||||
comment += countEvent->used_cpus * scale;
|
||||
return "sw-task-clock";
|
||||
}
|
||||
if (configName == GetCommentConfigName(countEvent, "hw-cpu-cycles")) {
|
||||
if (findRunningTime) {
|
||||
double hz = 0;
|
||||
if (running_time_in_sec != 0) {
|
||||
hz = summary.eventCount / (running_time_in_sec / scale);
|
||||
}
|
||||
comment += hz / 1e9;
|
||||
} else {
|
||||
comment += 0;
|
||||
}
|
||||
return "hw-cpu-cycles";
|
||||
}
|
||||
if (configName == GetCommentConfigName(countEvent, "hw-instructions") && summary.eventCount != 0) {
|
||||
double otherScale = 1.0;
|
||||
__u64 cpuCyclesCount = 0;
|
||||
bool other = FindPerCoreEventCount(summary, cpuCyclesCount, otherScale);
|
||||
if (other || (IsMonitoredAtAllTime(otherScale) && IsMonitoredAtAllTime(scale))) {
|
||||
comment += static_cast<double>(cpuCyclesCount) / summary.eventCount;
|
||||
return "hw-instructions";
|
||||
}
|
||||
}
|
||||
if (configName == GetCommentConfigName(countEvent, "hw-branch-misses")) {
|
||||
double otherScale = 1.0;
|
||||
__u64 branchInstructionsCount = 0;
|
||||
bool other = FindPerCoreEventCount(summary, branchInstructionsCount, otherScale);
|
||||
if ((other || (IsMonitoredAtAllTime(otherScale) && IsMonitoredAtAllTime(scale))) &&
|
||||
branchInstructionsCount != 0) {
|
||||
comment += (static_cast<double>(summary.eventCount) / branchInstructionsCount) * ONE_HUNDRED;
|
||||
return "hw-branch-misses";
|
||||
}
|
||||
}
|
||||
return HandleOtherConfig(comment, summary, running_time_in_sec, scale, findRunningTime);
|
||||
}
|
||||
|
||||
std::string SubCommandStat::HandleOtherConfig(double &comment, PerfEvents::Summary &summary, double running_time_in_sec,
|
||||
double scale, bool findRunningTime)
|
||||
{
|
||||
comment = 0;
|
||||
if (findRunningTime) {
|
||||
double rate = 0;
|
||||
if (scale != 0) {
|
||||
rate = summary.eventCount / (running_time_in_sec / scale);
|
||||
}
|
||||
comment += rate;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
bool SubCommandStat::IsMonitoredAtAllTime(const double &scale)
|
||||
{
|
||||
constexpr double SCALE_ERROR_LIMIT = 1e-5;
|
||||
@ -314,6 +572,19 @@ bool SubCommandStat::FindRunningTime(
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SubCommandStat::FindPercoreRunningTime(PerfEvents::Summary &summary, double &running_time_int_sec,
|
||||
double &main_scale)
|
||||
{
|
||||
if (summary.eventCount == 0) {
|
||||
return false;
|
||||
}
|
||||
running_time_int_sec = summary.eventCount / 1e9;
|
||||
if (summary.time_running < summary.time_enabled && summary.time_running != 0) {
|
||||
main_scale = static_cast<double>(summary.time_enabled) /summary.time_running;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SubCommandStat::CheckOptionPidAndApp(std::vector<pid_t> pids)
|
||||
{
|
||||
if (!CheckOptionPid(pids)) {
|
||||
@ -361,7 +632,7 @@ bool SubCommandStat::OnSubCommand(std::vector<std::string> &args)
|
||||
std::vector<pid_t> pids;
|
||||
for (auto selectPid : selectPids_) {
|
||||
pids.push_back(selectPid);
|
||||
std::vector<pid_t> subTids = GetSubthreadIDs(selectPid);
|
||||
std::vector<pid_t> subTids = GetSubthreadIDs(selectPid, thread_map_);
|
||||
if (!subTids.empty()) {
|
||||
pids.insert(pids.end(), subTids.begin(), subTids.end());
|
||||
}
|
||||
@ -376,9 +647,12 @@ bool SubCommandStat::OnSubCommand(std::vector<std::string> &args)
|
||||
HLOGV("CheckOptionPidAndApp() failed");
|
||||
return false;
|
||||
}
|
||||
SetReportFlags(perCpus_, perThreads_);
|
||||
perfEvents_.SetSystemTarget(targetSystemWide_);
|
||||
perfEvents_.SetTimeOut(timeStopSec_);
|
||||
perfEvents_.SetTimeReport(timeReportMs_);
|
||||
perfEvents_.SetPerCpu(perCpus_);
|
||||
perfEvents_.SetPerThread(perThreads_);
|
||||
perfEvents_.SetVerboseReport(verboseReport_);
|
||||
perfEvents_.SetInherit(!noCreateNew_);
|
||||
perfEvents_.SetTrackedCommand(trackedCommand_);
|
||||
|
@ -522,6 +522,24 @@ std::vector<pid_t> GetSubthreadIDs(const pid_t pid)
|
||||
return res;
|
||||
}
|
||||
|
||||
std::vector<pid_t> GetSubthreadIDs(const pid_t pid, std::map<pid_t, ThreadInfos> &thread_map)
|
||||
{
|
||||
std::string path {"/proc/"};
|
||||
path += std::to_string(pid);
|
||||
path += "/task/";
|
||||
auto tids = GetSubDirs(path);
|
||||
std::vector<pid_t> res{};
|
||||
for (auto tidStr : tids) {
|
||||
ThreadInfos info;
|
||||
pid_t tid = static_cast<pid_t>(std::stoul(tidStr, nullptr));
|
||||
info.tid = tid;
|
||||
info.pid = pid;
|
||||
thread_map[tid] = info;
|
||||
res.push_back(tid);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
bool StringStartsWith(const std::string &string, const std::string &with)
|
||||
{
|
||||
return string.find(with) == 0;
|
||||
@ -588,16 +606,8 @@ pid_t GetAppPackagePid(const std::string &appPackage, const pid_t oldPid, const
|
||||
}
|
||||
std::string fileName {basePath + subDir};
|
||||
fileName += "/cmdline";
|
||||
if (IsSameCommand(ReadFileToString(fileName), appPackage)) {
|
||||
res = std::stoul(subDir, nullptr);
|
||||
if (res == oldPid) {
|
||||
res = -1;
|
||||
continue;
|
||||
}
|
||||
if (res >= 0) {
|
||||
HLOGD("[GetAppPackagePid]: get appid for %s is %d", appPackage.c_str(), res);
|
||||
return res;
|
||||
}
|
||||
if (!IsNeedCheckSamePid(fileName, appPackage, subDir, res, oldPid)) {
|
||||
return res;
|
||||
}
|
||||
}
|
||||
std::this_thread::sleep_for(milliseconds(checkAppMs));
|
||||
@ -606,6 +616,23 @@ pid_t GetAppPackagePid(const std::string &appPackage, const pid_t oldPid, const
|
||||
return res;
|
||||
}
|
||||
|
||||
bool IsNeedCheckSamePid(const std::string &fileName, const std::string &appPackage, const std::string &subDir,
|
||||
pid_t &res, const pid_t oldPid)
|
||||
{
|
||||
if (IsSameCommand(ReadFileToString(fileName), appPackage)) {
|
||||
res = std::stoul(subDir, nullptr);
|
||||
if (res == oldPid) {
|
||||
res = -1;
|
||||
return true;
|
||||
}
|
||||
if (res >= 0) {
|
||||
HLOGD("[GetAppPackagePid]: get appid for %s is %d", appPackage.c_str(), res);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CheckAppIsRunning (std::vector<pid_t> &selectPids, const std::string &appPackage, int checkAppMs)
|
||||
{
|
||||
if (!appPackage.empty()) {
|
||||
|
Loading…
Reference in New Issue
Block a user