1 /*
2 * Copyright (C) 2019 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 #define LOG_TAG "libpixelpowerstats"
17
18 #include "GpuStateResidencyDataProvider.h"
19
20 #include <android-base/logging.h>
21
22 #include <fstream>
23 #include <sstream>
24
25 namespace android {
26 namespace hardware {
27 namespace google {
28 namespace pixel {
29 namespace powerstats {
30
GpuStateResidencyDataProvider(uint32_t id)31 GpuStateResidencyDataProvider::GpuStateResidencyDataProvider(uint32_t id)
32 : mPowerEntityId(id), mActiveId(0) /* (TODO (b/117228832): enable this) , mSuspendId(1) */ {}
33
getTotalTime(const std::string & path,uint64_t & totalTimeMs)34 bool GpuStateResidencyDataProvider::getTotalTime(const std::string &path, uint64_t &totalTimeMs) {
35 std::ifstream inFile(path, std::ifstream::in);
36 if (!inFile.is_open()) {
37 PLOG(ERROR) << __func__ << ":Failed to open file " << path;
38 return false;
39 }
40
41 std::string line;
42 std::getline(inFile, line);
43 std::istringstream lineStream(line, std::istringstream::in);
44
45 totalTimeMs = 0;
46 uint64_t curTimeMs = 0;
47 while (lineStream >> curTimeMs) {
48 totalTimeMs += curTimeMs;
49 }
50 return true;
51 }
52
getResults(std::unordered_map<uint32_t,PowerEntityStateResidencyResult> & results)53 bool GpuStateResidencyDataProvider::getResults(
54 std::unordered_map<uint32_t, PowerEntityStateResidencyResult> &results) {
55 uint64_t totalActiveTimeUs = 0;
56 if (!getTotalTime("/sys/class/kgsl/kgsl-3d0/gpu_clock_stats", totalActiveTimeUs)) {
57 LOG(ERROR) << __func__ << "Failed to get results for GPU:Active";
58 return false;
59 }
60
61 /* (TODO (b/117228832): enable this)
62 uint64_t totalSuspendTimeMs = 0;
63 if (!getTotalTime("/sys/class/kgsl/kgsl-3d0/devfreq/suspend_time", totalSuspendTimeMs)) {
64 LOG(ERROR) << __func__ << "Failed to get results for GPU:Suspend";
65 return false;
66 }
67 */
68
69 PowerEntityStateResidencyResult result = {
70 .powerEntityId = mPowerEntityId,
71 .stateResidencyData = {
72 {.powerEntityStateId = mActiveId, .totalTimeInStateMs = totalActiveTimeUs / 1000},
73 /* (TODO (b/117228832): enable this)
74 {.powerEntityStateId = mSuspendId, .totalTimeInStateMs = totalSuspendTimeMs},
75 */
76 }};
77
78 results.emplace(std::make_pair(mPowerEntityId, result));
79 return true;
80 }
81
getStateSpaces()82 std::vector<PowerEntityStateSpace> GpuStateResidencyDataProvider::getStateSpaces() {
83 return {{.powerEntityId = mPowerEntityId,
84 .states = {
85 {.powerEntityStateId = mActiveId, .powerEntityStateName = "Active"},
86 /* (TODO (b/117228832): enable this)
87 {.powerEntityStateId = mSuspendId, .powerEntityStateName = "Suspend"}
88 */
89 }}};
90 }
91
92 } // namespace powerstats
93 } // namespace pixel
94 } // namespace google
95 } // namespace hardware
96 } // namespace android