1/* 2 * Copyright (c) Huawei Technologies Co., Ltd. 2023. All rights reserved. 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 16#include "gpu_data_plugin.h" 17#include <ctime> 18#include "gpu_plugin_result.pbencoder.h" 19 20namespace { 21using namespace OHOS::Developtools::Profiler; 22const std::string GPU_PATH = "/sys/class/devfreq/gpufreq/gpu_scene_aware/utilisation"; 23} // namespace 24 25int GpuDataPlugin::Start(const uint8_t* configData, uint32_t configSize) 26{ 27 CHECK_TRUE(protoConfig_.ParseFromArray(configData, configSize) > 0, RET_FAIL, 28 "%s:parseFromArray failed!", __func__); 29 30 if (protoConfig_.pid() > 0) { 31 pid_ = protoConfig_.pid(); 32 } 33 34 file_.open(GPU_PATH); 35 if (!file_.is_open()) { 36 PROFILER_LOG_ERROR(LOG_CORE, "%s:failed to open(%s)", __func__, GPU_PATH.c_str()); 37 return RET_FAIL; 38 } 39 PROFILER_LOG_INFO(LOG_CORE, "%s:start success!", __func__); 40 return RET_SUCC; 41} 42 43int GpuDataPlugin::ReportOptimize(RandomWriteCtx* randomWrite) 44{ 45 ProtoEncoder::GpuData dataProto(randomWrite); 46 WriteGpuDataInfo(dataProto); 47 int msgSize = dataProto.Finish(); 48 return msgSize; 49} 50 51int GpuDataPlugin::Report(uint8_t* data, uint32_t dataSize) 52{ 53 GpuData dataProto; 54 uint32_t length; 55 WriteGpuDataInfo(dataProto); 56 57 length = dataProto.ByteSizeLong(); 58 if (length > dataSize) { 59 return -length; 60 } 61 if (dataProto.SerializeToArray(data, length) > 0) { 62 return length; 63 } 64 return 0; 65} 66 67int GpuDataPlugin::Stop() 68{ 69 file_.close(); 70 PROFILER_LOG_INFO(LOG_CORE, "%s:stop success!", __func__); 71 return 0; 72} 73 74int GpuDataPlugin::ReadFile() 75{ 76 file_.clear(); 77 file_.seekg(0); 78 std::string line; 79 std::getline(file_, line); 80 if (line == "") { 81 return RET_FAIL; 82 } 83 for (char charac : line) { 84 if (!isdigit(charac)) { 85 PROFILER_LOG_ERROR(LOG_CORE, "invalid file content for (%s)", GPU_PATH.c_str()); 86 return RET_FAIL; 87 } 88 } 89 return stoi(line); 90} 91 92template <typename T> void GpuDataPlugin::WriteGpuDataInfo(T& gpuData) 93{ 94 int ret = ReadFile(); 95 if (ret == RET_FAIL) { 96 return; 97 } 98 99 constexpr uint64_t nanoSeconds = 1000000000; 100 struct timespec ts; 101 clock_gettime(CLOCK_BOOTTIME, &ts); 102 uint64_t boottime = (static_cast<uint64_t>(ts.tv_sec) * nanoSeconds + 103 static_cast<uint64_t>(ts.tv_nsec)) / 1000000; 104 gpuData.set_boottime(boottime); 105 gpuData.set_gpu_utilisation(static_cast<uint64_t>(ret)); 106} 107