1/*
2 * Copyright (C) 2021 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#include <iostream>
16#include <sstream>
17#include <thread>
18#include "unistd.h"
19#include "include/sp_utils.h"
20#include "include/ByTrace.h"
21#include "include/sp_log.h"
22#include "include/common.h"
23namespace OHOS {
24namespace SmartPerf {
25void ByTrace::SetTraceConfig(int mSum, int mInterval, long long mThreshold, int mLowfps, int mCurNum) const
26{
27    sum = mSum;
28    interval = mInterval;
29    threshold = mThreshold;
30    lowfps = mLowfps;
31    curNum = mCurNum;
32    LOGI("ByTrace::SetTraceConfig mSum(%d) mInterval(%d) mThreshold(%lld) mLowfps(%d) mCurNum(%d)", mSum, mInterval,
33        mThreshold, mLowfps, mCurNum);
34}
35void ByTrace::ThreadGetTrace() const
36{
37    std::string result;
38    std::string cmdString;
39    if (SPUtils::IsHmKernel()) {
40        cmdString = CMD_COMMAND_MAP.at(CmdCommand::HITRACE_1024);
41    } else {
42        cmdString = CMD_COMMAND_MAP.at(CmdCommand::HITRACE_2048);
43    }
44    std::string time = std::to_string(SPUtils::GetCurTime());
45    std::string traceFile = "/data/local/tmp/sptrace_" + time + ".ftrace";
46    std::string traceCmdExe = cmdString + traceFile;
47    SPUtils::LoadCmd(traceCmdExe, result);
48    LOGI("TRACE threadGetTrace  CMD(%s)", traceCmdExe.c_str());
49}
50TraceStatus ByTrace::CheckFpsJitters(std::vector<long long> jitters, int cfps) const
51{
52    times++;
53    int two = 2;
54    long long curTime = SPUtils::GetCurTime();
55    if (curNum <= sum && currentTrigger < 0 && times > two) {
56        for (size_t i = 0; i < jitters.size(); i++) {
57            long long normalJitter = jitters[i] / 1e6;
58            if (normalJitter > threshold || cfps < lowfps) {
59                TriggerCatch(curTime);
60            }
61        }
62    }
63    if ((curTime - lastTriggerTime) / 1e3 > interval && currentTrigger == 1) {
64        currentTrigger = -1;
65    }
66    return TraceStatus::TRACE_FINISH;
67}
68void ByTrace::TriggerCatch(long long curTime) const
69{
70    if ((curTime - lastTriggerTime) / 1e3 > interval && !CheckHitraceId()) {
71        std::thread tStart([this] { this->ThreadGetTrace(); });
72        currentTrigger = 1;
73        lastTriggerTime = curTime;
74        curNum++;
75        tStart.detach();
76    }
77}
78
79bool ByTrace::CheckHitraceId() const
80{
81    std::string result;
82    std::string hitrace = CMD_COMMAND_MAP.at(CmdCommand::HITRACE_CMD);
83    SPUtils::LoadCmd(hitrace, result);
84    if (result.empty()) {
85        return false;
86    }
87    if (result.find("-t") != std::string::npos) {
88        return true;
89    }
90    return false;
91}
92}
93}
94