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 <thread>
17#include <string>
18#include <climits>
19#include "include/sp_task.h"
20#include "include/sp_profiler_factory.h"
21#include "include/sp_utils.h"
22#include "include/FPS.h"
23#include "include/RAM.h"
24#include "include/CPU.h"
25#include "include/Capture.h"
26#include "include/startup_delay.h"
27#include "include/sp_log.h"
28#include "ByTrace.h"
29#include <cstdio>
30#include <ios>
31#include <vector>
32#include <fstream>
33#include <sstream>
34#include <regex>
35#include "unistd.h"
36#include <future>
37#include "include/common.h"
38
39namespace OHOS {
40namespace SmartPerf {
41const long long RM_0 = 0;
42const long long RM_5000 = 5000;
43const long long RM_1000 = 1000;
44const long long RM_1000000 = 1000000;
45const long long END_WAITING_TIME = 8; // End waiting time,unit seconds
46// init::-SESSIONID 12345678 -INTERVAL 1000 -PKG ohos.samples.ecg -c -g -t -p -f -r -fl 30
47static ExceptionMsg ParseToTask(std::string command, TaskInfo &taskInfo)
48{
49    std::vector<std::string> args;
50    size_t pos = 0;
51    while ((pos = command.find(" ")) != std::string::npos) {
52        args.push_back(command.substr(0, pos));
53        command.erase(0, pos + 1);
54    }
55    args.push_back(command);
56    StuckNotification snf;
57    snf.isEffective = false;
58    std::string sessionId;
59    long long interval = 1000;
60    std::string pkg;
61    bool isFPS = false;
62    std::vector<std::string> configs;
63    for (size_t i = 0; i < args.size(); i++) {
64        if (args[i] == COMMAND_MAP_REVERSE.at(CommandType::CT_SESSIONID)) {
65            sessionId = args[++i];
66        } else if (args[i] == COMMAND_MAP_REVERSE.at(CommandType::CT_INTERVAL)) {
67            interval = std::stoll(args[++i]);
68        } else if (args[i] == COMMAND_MAP_REVERSE.at(CommandType::CT_PKG)) {
69            pkg = args[++i];
70        } else if (args[i] == COMMAND_MAP_REVERSE.at(CommandType::CT_FL)) { // 获取用户fps的值,并赋给snf.   CT_FL
71            snf.fps = std::stoi(args[++i]);
72            snf.isEffective = true;
73        } else if (args[i] == COMMAND_MAP_REVERSE.at(CommandType::CT_FTL)) { // 获取frameTime的值      CT_FTL
74            snf.frameTime = std::stoi(args[++i]);
75            snf.isEffective = true;
76        } else {
77            if (args[i] == COMMAND_MAP_REVERSE.at(CommandType::CT_F)) { // 判断用户设置是否有-f
78                isFPS = true;
79            }
80            if (COMMAND_MAP.end() != COMMAND_MAP.find(args[i])) {
81                configs.push_back(args[i]);
82            }
83        }
84    }
85    if (snf.isEffective && (!isFPS)) {
86        return ExceptionMsg::TASK_CONFIG_NULL;
87    }
88    if (sessionId.empty()) {
89        LOGE("ExceptionMsg ParseToTask sessoin id is null");
90        return ExceptionMsg::SESSION_ID_NULL;
91    } else if (configs.size() == 0) {
92        LOGE("ExceptionMsg ParseToTask configs size is 0");
93        return ExceptionMsg::TASK_CONFIG_NULL;
94    }
95    taskInfo = { sessionId, pkg, configs, interval, snf };
96    return ExceptionMsg::NO_ERR;
97}
98
99static std::string MapToString(std::map<std::string, std::string> myMap)
100{
101    // 将Map转换为字符串
102    std::string str = "{ ";
103    for (auto it = myMap.begin(); it != myMap.end(); ++it) {
104        str += "\"" + it->first + "\": " + it->second + ", ";
105    }
106    const int subLen = 2;
107    str.erase(str.end() - subLen, str.end());
108    str += " }";
109    return str;
110}
111
112ErrCode SPTask::InitTask(const std::string &recvStr)
113{
114    LOGI("SPTask::InitTask start param(%s)", recvStr.c_str());
115    std::string result = "";
116    std::string hiprofiler = CMD_COMMAND_MAP.at(CmdCommand::HIPROFILER);
117    SPUtils::LoadCmd(hiprofiler, result);
118    result.clear();
119    std::string perf = CMD_COMMAND_MAP.at(CmdCommand::PERF);
120    SPUtils::LoadCmd(perf, result);
121    std::cout << recvStr << std::endl;
122    ExceptionMsg exMsg = ParseToTask(recvStr, curTaskInfo);
123    if (exMsg == ExceptionMsg::NO_ERR) {
124        isInit = true;
125        LOGI("SPTask::InitTask Ok");
126        return ErrCode::OK;
127    }
128
129    std::string errInfo = EXCEPTION_MSG_MAP.at(exMsg);
130    LOGI("SPTask::InitTask error(%s)", errInfo.c_str());
131    return ErrCode::FAILED;
132}
133
134std::future<std::map<std::string, std::string>> SPTask::AsyncCollectRam()
135{
136    std::promise<std::map<std::string, std::string>> p;
137    std::future<std::map<std::string, std::string>> futureResult;
138    for (std::string ramConfig : curTaskInfo.taskConfig) {
139        if (ramConfig.find("-r") != std::string::npos) {
140            futureResult = p.get_future();
141            std::thread([p = std::move(p)]() mutable {
142                p.set_value(RAM::GetInstance().ItemData());
143            }).detach();
144        }
145    }
146    return futureResult;
147}
148
149std::future<std::map<std::string, std::string>> SPTask::AsyncCollectCpu()
150{
151    std::promise<std::map<std::string, std::string>> p;
152    std::future<std::map<std::string, std::string>> futureResult;
153    for (std::string cpuConfig : curTaskInfo.taskConfig) {
154        if (cpuConfig.find("-c") != std::string::npos) {
155            futureResult = p.get_future();
156            std::thread([p = std::move(p)]() mutable {
157                p.set_value(CPU::GetInstance().ItemData());
158            }).detach();
159        }
160    }
161    return futureResult;
162}
163
164std::future<std::map<std::string, std::string>> SPTask::AsyncCollectFps()
165{
166    std::promise<std::map<std::string, std::string>> p;
167    std::future<std::map<std::string, std::string>> futureResult;
168    for (std::string fpsConfig : curTaskInfo.taskConfig) {
169        if (fpsConfig.find("-f") != std::string::npos) {
170            futureResult = p.get_future();
171            std::thread([p = std::move(p)]() mutable {
172                p.set_value(FPS::GetInstance().ItemData());
173            }).detach();
174        }
175    }
176    return futureResult;
177}
178
179void SPTask::CheckFutureRam(std::future<std::map<std::string, std::string>> &ramResult,
180    std::map<std::string, std::string> &dataMap)
181{
182    if (ramResult.valid()) {
183        std::map<std::string, std::string> result = ramResult.get();
184        dataMap.insert(result.begin(), result.end());
185    }
186}
187
188void SPTask::CheckFutureCpu(std::future<std::map<std::string, std::string>> &cpuResult,
189    std::map<std::string, std::string> &dataMap)
190{
191    if (cpuResult.valid()) {
192        std::map<std::string, std::string> result = cpuResult.get();
193        dataMap.insert(result.begin(), result.end());
194    }
195}
196
197void SPTask::CheckFutureFps(std::future<std::map<std::string, std::string>> &fpsResult,
198    std::map<std::string, std::string> &dataMap)
199{
200    if (fpsResult.valid()) {
201        std::map<std::string, std::string> result = fpsResult.get();
202        dataMap.insert(result.begin(), result.end());
203    }
204}
205
206void SPTask::GetItemData(std::map<std::string, std::string> &dataMap)
207{
208    for (std::string itConfig : curTaskInfo.taskConfig) {
209        if (itConfig.find("-snapshot") != std::string::npos) {
210            Capture::GetInstance().SocketMessage();
211            std::map<std::string, std::string> captureMap = Capture::GetInstance().ItemData();
212            dataMap.insert(captureMap.begin(), captureMap.end());
213        }
214
215        if (itConfig.find("-gc") != std::string::npos || itConfig.find("-o") != std::string::npos) {
216            continue;
217        }
218
219        SpProfiler *profiler = SpProfilerFactory::GetCmdProfilerItem(COMMAND_MAP.at(itConfig), false);
220        if (profiler != nullptr) {
221            std::map<std::string, std::string> itemMap = profiler->ItemData();
222            dataMap.insert(itemMap.begin(), itemMap.end());
223        }
224    }
225}
226
227void SPTask::ConfigDataThread()
228{
229    for (std::string itConfig : curTaskInfo.taskConfig) {
230        if (!sdkData) {
231            ConfigureSdkData(itConfig);
232        }
233
234        if (itConfig.find("-gc") != std::string::npos) {
235            gpuCounter.StartCollect(GpuCounter::GC_START);
236        }
237    }
238}
239
240void SPTask::ConfigureSdkData(std::string itConfig)
241{
242    if (itConfig.find("-o") != std::string::npos) {
243        sdkData = true;
244        OHOS::system::SetParameter("debug.smartperf.sdkdataenable", "1");
245        SdkDataRecv &sdkDataRecv = SdkDataRecv::GetInstance();
246        sdkDataRecv.SetRunningState(true);
247        sdk = std::thread([&sdkDataRecv, this]() { this->RunSdkServer(sdkDataRecv); });
248    }
249}
250
251void SPTask::RunSdkServer(SdkDataRecv &sdkDataRecv)
252{
253    sdkDataRecv.ServerThread(sdkvec);
254}
255
256void SPTask::ResetSdkParam()
257{
258    OHOS::system::SetParameter("debug.smartperf.sdkdataenable", "0");
259    sdkData = false;
260    SdkDataRecv &sdkDataRecv = SdkDataRecv::GetInstance();
261    sdkDataRecv.SetRunningState(false);
262    int listenFd = sdkDataRecv.GetListenFd();
263    if (listenFd != -1) {
264        close(listenFd);
265        sdkDataRecv.SetListenFd(-1);
266    }
267    if (sdk.joinable()) {
268        sdk.join();
269    }
270};
271
272void SPTask::StopSdkRecv()
273{
274    if (!sdkData || sdkvec.size() <= 0) {
275        return;
276    }
277
278    std::string outSdkDataDir = baseOutPath + "/" + curTaskInfo.sessionId;
279    char outSdkDataDirChar[PATH_MAX] = {0x00};
280    if (realpath(outSdkDataDir.c_str(), outSdkDataDirChar) == nullptr) {
281        LOGE("data dir %s is nullptr", outSdkDataDir.c_str());
282        return;
283    }
284    std::string outSdkDataPath = std::string(outSdkDataDirChar) + "/sdk_data.csv";
285    sdkDataMtx.lock();
286    std::ofstream outFile;
287    outFile.open(outSdkDataPath.c_str(), std::ios::out | std::ios::trunc);
288    if (!outFile.is_open()) {
289        LOGE("data %s open failed", outSdkDataPath.c_str());
290        return;
291    }
292    std::string title = "source,timestamp,eventName,enable,value\r";
293    outFile << title << std::endl;
294    for (const auto &item : sdkvec) {
295        outFile << item << std::endl;
296    }
297    outFile.close();
298    sdkDataMtx.unlock();
299}
300
301void SPTask::InitDataFile()
302{
303    vmap.clear();
304    sdkvec.clear();
305    gpuCounter.GetGpuCounterSaveReportData().clear();
306    SdkDataRecv::GetInstance().SetStartRecordTime();
307    startTime = SPUtils::GetCurTime();
308    std::vector<std::string> files = {
309        "sdk_data.csv",
310        "gpu_counter.csv",
311        "t_general_info.csv",
312        "t_index_info.csv",
313    };
314    std::string fileDir = baseOutPath + "/" + curTaskInfo.sessionId;
315
316    for (const auto &file: files) {
317        std::string filePath = fileDir + "/" + file;
318        char filePathChar[PATH_MAX] = {0x00};
319        if ((realpath(filePath.c_str(), filePathChar) == nullptr)) {
320            LOGE("%s is not exist, init finish.", filePath.c_str());
321            continue;
322        }
323        std::remove(filePathChar);
324    }
325}
326
327void SPTask::AsyncGetDataMap(std::function<void(std::string data)> msgTask)
328{
329    long long lastTime = SPUtils::GetCurTime();
330    asyncDataMtx.lock();
331    std::map<std::string, std::string> dataMap;
332    if (!curTaskInfo.packageName.empty()) {
333        std::string processId = "";
334        OHOS::SmartPerf::StartUpDelay sp;
335        processId = sp.GetPidByPkg(curTaskInfo.packageName);
336        SpProfilerFactory::SetProfilerPidByPkg(processId);
337    }
338    dataMap.insert(std::pair<std::string, std::string>(std::string("timestamp"), std::to_string(lastTime)));
339    std::future<std::map<std::string, std::string>> fpsResult = AsyncCollectFps();
340    std::future<std::map<std::string, std::string>> cpuResult = AsyncCollectCpu();
341    GetItemData(dataMap);
342    std::future<std::map<std::string, std::string>> ramResult = AsyncCollectRam();
343    CheckFutureFps(fpsResult, dataMap);
344    CheckFutureCpu(cpuResult, dataMap);
345    CheckFutureRam(ramResult, dataMap);
346    if (curTaskInfo.stuckInfo.isEffective) {
347        std::map<std::string, std::string> timeUsedMap = DetectionAndGrab();
348        if (!timeUsedMap.empty()) {
349            dataMap.insert(timeUsedMap.begin(), timeUsedMap.end());
350        }
351    }
352    SPData spdata;
353    spdata.values.insert(dataMap.begin(), dataMap.end());
354    if (GetRecordState()) {
355        vmap.push_back(spdata);
356    }
357    gpuCounter.GetGpuRealtimeData(dataMap);
358    SdkDataRecv::GetInstance().GetSdkDataRealtimeData(dataMap);
359    msgTask(MapToString(dataMap));
360    long long nextTime = SPUtils::GetCurTime();
361    long long costTime = nextTime - lastTime;
362    long long pTime = 998;
363    if (costTime < curTaskInfo.freq) {
364        std::this_thread::sleep_for(std::chrono::milliseconds(pTime - costTime));
365    }
366    asyncDataMtx.unlock();
367}
368
369ErrCode SPTask::StartTask(std::function<void(std::string data)> msgTask)
370{
371    LOGI("SPTask::StartTask start ");
372    RAM &ram = RAM::GetInstance();
373    ram.SetFirstFlag();
374    if (!isInit) {
375        LOGW("SPTask::StartTask initialization failed");
376        return ErrCode::FAILED;
377    }
378    isRunning = true;
379    realTimeStart = SPUtils::GetCurTime();
380    if (!curTaskInfo.packageName.empty()) {
381        SpProfilerFactory::SetProfilerPkg(curTaskInfo.packageName);
382    }
383    InitDataFile();
384    ConfigDataThread();
385    thread = std::thread([this, msgTask]() {
386        while (isRunning) {
387            AsyncGetDataMap(msgTask);
388        }
389    });
390    LOGI("SPTask::StartTask complete");
391    return ErrCode::OK;
392}
393
394void SPTask::WritePath(std::string thisBasePath)
395{
396    if (!SPUtils::FileAccess(thisBasePath)) {
397        std::string cmdResult;
398        std::string writePath = CMD_COMMAND_MAP.at(CmdCommand::WRITE_PATH) + curTaskInfo.sessionId;
399        SPUtils::LoadCmd(writePath, cmdResult);
400    }
401}
402
403void SPTask::StopGetInfo()
404{
405    bool isTcpMessage = true;
406    std::string thisBasePath = baseOutPath + "/" + curTaskInfo.sessionId;
407    WritePath(thisBasePath);
408    std::string outIndexpath = thisBasePath + "/t_index_info.csv";
409    long long endTime = SPUtils::GetCurTime();
410    long long testDuration = (endTime - startTime) / 1000;
411    const std::string gpuDataVersion = "1.1";
412    std::string screenStr = SPUtils::GetScreen();
413    size_t pos3 = screenStr.find("=");
414    std::string refreshrate = screenStr.substr(pos3 + 1);
415    std::map<std::string, std::string> taskInfoMap = {
416        { "sessionId", curTaskInfo.sessionId },
417        { "taskId", curTaskInfo.sessionId },
418        { "appName", curTaskInfo.packageName },
419        { "packageName", curTaskInfo.packageName },
420        { "startTime", std::to_string(startTime) },
421        { "endTime", std::to_string(endTime) },
422        { "testDuration", std::to_string(testDuration) },
423        { "taskName", "testtask" },
424        { "board", "hw" },
425        { "target_fps", refreshrate },
426        { "gpuDataVersion", gpuDataVersion },
427    };
428    std::map<std::string, std::string> deviceInfo = SPUtils::GetDeviceInfo();
429    std::map<std::string, std::string> cpuInfo = SPUtils::GetCpuInfo(isTcpMessage);
430    std::map<std::string, std::string> gpuInfo = SPUtils::GetGpuInfo(isTcpMessage);
431    std::map<std::string, std::string> destMap;
432    destMap.insert(taskInfoMap.begin(), taskInfoMap.end());
433    destMap.insert(deviceInfo.begin(), deviceInfo.end());
434    destMap.insert(cpuInfo.begin(), cpuInfo.end());
435    destMap.insert(gpuInfo.begin(), gpuInfo.end());
436    OHOS::SmartPerf::SpCsvUtil::WriteCsvH(destMap);
437    if (!vmap.empty()) {
438        vmap.erase(vmap.begin());
439    }
440    OHOS::SmartPerf::SpCsvUtil::WriteCsv(outIndexpath, vmap);
441}
442void SPTask::StopGpuCounterRecv()
443{
444    std::string outGpuCounterDataPath = baseOutPath + "/" + curTaskInfo.sessionId;
445
446    if (GetRecordState()) {
447        gpuCounter.GetInstance().SaveData(outGpuCounterDataPath);
448    }
449}
450void SPTask::StopTask()
451{
452    LOGI("SPTask::StopTask start");
453
454    if (GetRecordState()) {
455        StopGetInfo();
456        StopSdkRecv();
457        StopGpuCounterRecv();
458
459        vmap.clear();
460        sdkvec.clear();
461        gpuCounter.GetGpuCounterData().clear();
462        recordState = false;
463    }
464
465    ResetSdkParam();
466    gpuCounter.StopCollect();
467
468    isRunning = false;
469    isInit = false;
470    realTimeStart = 0;
471
472    if (thread.joinable()) {
473        thread.join();
474    }
475
476    KillHiperfCmd();
477
478    LOGI("SPTask::StopTask complete");
479}
480
481std::map<std::string, std::string> SPTask::DetectionAndGrab()
482{
483    std::map<std::string, std::string> templateMap;
484    if (!curTaskInfo.stuckInfo.isEffective) {
485        return templateMap;
486    }
487
488    FpsCurrentFpsTime fcf = FPS::GetInstance().GetFpsCurrentFpsTime();
489    long long nowTime = SPUtils::GetCurTime();
490    long long curframeTime = fcf.currentFpsTime / RM_1000000; // Convert to milliseconds
491    std::cout << "start::" << startCaptuerTime << std::endl;
492
493    if (startCaptuerTime > 0) {
494        long long diff =
495            startCaptuerTime > nowTime ? (LLONG_MAX - startCaptuerTime + nowTime) : (nowTime - startCaptuerTime);
496        if (diff > RM_5000 && (!CheckCounterId())) {
497            startCaptuerTime = RM_0;
498        }
499    }
500
501    if (curTaskInfo.stuckInfo.fps > fcf.fps || curTaskInfo.stuckInfo.frameTime < curframeTime) {
502        if (startCaptuerTime == 0) {
503            startCaptuerTime = nowTime;
504            std::cout << "ThreadGetHiperf::" << startCaptuerTime << std::endl;
505            ThreadGetHiperf(startCaptuerTime);
506        }
507    }
508    templateMap["fpsWarn"] = std::to_string(fcf.fps);
509    templateMap["FrameTimeWarn"] = std::to_string(fcf.currentFpsTime);
510    templateMap["TraceTime"] = std::to_string(startCaptuerTime);
511    return templateMap;
512}
513
514bool SPTask::CheckCounterId()
515{
516    std::string result;
517    std::string hiprofilerCmd = CMD_COMMAND_MAP.at(CmdCommand::HIPROFILER_CMD);
518    SPUtils::LoadCmd(hiprofilerCmd, result);
519    if (result.empty()) {
520        return false;
521    }
522
523    if (result.find("-k") != std::string::npos) {
524        return true;
525    }
526
527    return false;
528}
529std::thread SPTask::ThreadGetHiperf(long long timeStamp)
530{
531    auto thGetTrace = [this, timeStamp]() { this->GetHiperf(std::to_string(timeStamp)); };
532    std::thread spThread(thGetTrace);
533    spThread.detach();
534    return spThread;
535}
536
537void SPTask::GetHiperf(const std::string &traceName)
538{
539    std::string result;
540    std::string tmp = SetHiperf(traceName);
541    std::cout << tmp << std::endl;
542    LOGD("hiprofiler exec (%s)", tmp.c_str());
543    LOGI("hiprofiler exec trace name(%s)", traceName.c_str());
544    SPUtils::LoadCmd(tmp, result);
545    LOGI("hiprofiler exec end (%s)", result.c_str());
546}
547
548
549bool SPTask::CheckTcpParam(std::string str, std::string &errorInfo)
550{
551    std::set<std::string> keys;
552    for (auto a : COMMAND_MAP) {
553        keys.insert(a.first.substr(1)); // 不需要前面的'-'
554    }
555
556    return SPUtils::VeriyParameter(keys, str, errorInfo);
557}
558
559void SPTask::KillHiperfCmd()
560{
561    long long now = 0;
562    long long runTime = 0;
563    std::string killCmd = CMD_COMMAND_MAP.at(CmdCommand::KILL_CMD) + "-9 ";
564    std::string result;
565    std::vector<std::string> out;
566
567    if (startCaptuerTime <= 0) {
568        return;
569    }
570
571    now = SPUtils::GetCurTime();
572    runTime = now > startCaptuerTime ? now - startCaptuerTime : LLONG_MAX - startCaptuerTime + now;
573    runTime = runTime / RM_1000; // Convert to seconds
574
575    LOGI("Preparing to exit run time(%lld)", runTime);
576    do {
577        out.clear();
578        std::string hiprofilerPid = CMD_COMMAND_MAP.at(CmdCommand::HIPROFILER_PID);
579        SPUtils::LoadCmd(hiprofilerPid, result);
580        SPUtils::StrSplit(result, " ", out);
581        if (out.empty()) {
582            break;
583        }
584
585        sleep(1);
586    } while (END_WAITING_TIME - runTime++ > 0);
587
588    out.clear();
589    std::string hiprofilerPid = CMD_COMMAND_MAP.at(CmdCommand::HIPROFILER_PID);
590    SPUtils::LoadCmd(hiprofilerPid, result);
591    SPUtils::StrSplit(result, " ", out);
592    LOGI("pidof hiprofiler_cmd size(%u)", out.size());
593    for (auto it = out.begin(); out.end() != it; ++it) {
594        result.clear();
595        SPUtils::LoadCmd(killCmd + (*it), result);
596    }
597
598    return;
599}
600
601std::string SPTask::SetHiperf(const std::string &traceName)
602{
603    std::string hiPrefix = "hiprofiler_";
604    std::string dataPrefix = "perf_";
605    requestId++;
606    std::string trtmp = strOne + hiPrefix + traceName + strTwo + "\n" + strThree + std::to_string(requestId) + "\n" +
607        strFour + "\n" + strFive + hiPrefix + traceName + strSix + "\n" + strNine + strEleven + "\n" + strSeven +
608        dataPrefix + traceName + strEight + strTen + "\n" + conFig;
609    return trtmp;
610}
611
612bool SPTask::GetRecordState()
613{
614    return recordState;
615}
616void SPTask::StartRecord()
617{
618    LOGI("SPTask::StartRecord");
619    startTime = SPUtils::GetCurTime();
620    InitDataFile();
621    recordState = true;
622}
623
624void SPTask::StopRecord()
625{
626    LOGI("SPTask::StopRecord");
627    std::string outGpuCounterDataPath = baseOutPath + "/" + curTaskInfo.sessionId;
628
629    if (isInit) {
630        StopGetInfo();
631        if (sdkData) {
632            StopSdkRecv();
633        }
634        gpuCounter.GetInstance().SaveData(outGpuCounterDataPath);
635    }
636
637    vmap.clear();
638    sdkvec.clear();
639    gpuCounter.GetGpuCounterData().clear();
640
641    recordState = false;
642}
643time_t SPTask::GetRealStartTime() const
644{
645    return realTimeStart;
646}
647}
648}
649