| Chenjie Yu | 9da105b | 2018-01-13 12:41:08 -0800 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (C) 2018 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 | |
| Tej Singh | 484524a | 2018-02-01 15:10:05 -0800 | [diff] [blame] | 17 | #define DEBUG false // STOPSHIP if true |
| Chenjie Yu | 9da105b | 2018-01-13 12:41:08 -0800 | [diff] [blame] | 18 | #include "Log.h" |
| 19 | |
| 20 | #include <fstream> |
| 21 | |
| 22 | #include "KernelUidCpuActiveTimeReader.h" |
| 23 | #include "guardrail/StatsdStats.h" |
| 24 | #include "logd/LogEvent.h" |
| 25 | #include "statslog.h" |
| Yangster-mac | 330af58 | 2018-02-08 15:24:38 -0800 | [diff] [blame^] | 26 | #include "stats_log_util.h" |
| Chenjie Yu | 9da105b | 2018-01-13 12:41:08 -0800 | [diff] [blame] | 27 | |
| 28 | using std::make_shared; |
| 29 | using std::shared_ptr; |
| 30 | using std::ifstream; |
| 31 | |
| 32 | namespace android { |
| 33 | namespace os { |
| 34 | namespace statsd { |
| 35 | |
| 36 | static const string sProcFile = "/proc/uid_concurrent_active_time"; |
| 37 | static const int kLineBufferSize = 1024; |
| 38 | |
| 39 | /** |
| 40 | * Reads /proc/uid_concurrent_active_time which has the format: |
| 41 | * active: X (X is # cores) |
| 42 | * [uid0]: [time-0] [time-1] [time-2] ... (# entries = # cores) |
| 43 | * [uid1]: [time-0] [time-1] [time-2] ... ... |
| 44 | * ... |
| 45 | * Time-N means the CPU time a UID spent running concurrently with N other processes. |
| 46 | * The file contains a monotonically increasing count of time for a single boot. |
| 47 | */ |
| 48 | KernelUidCpuActiveTimeReader::KernelUidCpuActiveTimeReader() : StatsPuller(android::util::CPU_ACTIVE_TIME) { |
| 49 | } |
| 50 | |
| 51 | bool KernelUidCpuActiveTimeReader::PullInternal(vector<shared_ptr<LogEvent>>* data) { |
| 52 | data->clear(); |
| 53 | |
| 54 | ifstream fin; |
| 55 | fin.open(sProcFile); |
| 56 | if (!fin.good()) { |
| 57 | VLOG("Failed to read pseudo file %s", sProcFile.c_str()); |
| 58 | return false; |
| 59 | } |
| 60 | |
| Yangster-mac | 330af58 | 2018-02-08 15:24:38 -0800 | [diff] [blame^] | 61 | int64_t wallClockTimestampNs = getWallClockNs(); |
| 62 | int64_t elapsedTimestampNs = getElapsedRealtimeNs(); |
| 63 | |
| Chenjie Yu | 9da105b | 2018-01-13 12:41:08 -0800 | [diff] [blame] | 64 | char buf[kLineBufferSize]; |
| 65 | char* pch; |
| 66 | while (!fin.eof()) { |
| 67 | fin.getline(buf, kLineBufferSize); |
| 68 | pch = strtok(buf, " :"); |
| 69 | if (pch == NULL) break; |
| 70 | uint64_t uid = std::stoull(pch); |
| 71 | pch = strtok(NULL, " "); |
| 72 | uint64_t timeMs; |
| 73 | int idx = 0; |
| 74 | do { |
| 75 | timeMs = std::stoull(pch); |
| Yangster-mac | 330af58 | 2018-02-08 15:24:38 -0800 | [diff] [blame^] | 76 | auto ptr = make_shared<LogEvent>(mTagId, wallClockTimestampNs, elapsedTimestampNs); |
| Chenjie Yu | 9da105b | 2018-01-13 12:41:08 -0800 | [diff] [blame] | 77 | ptr->write(uid); |
| 78 | ptr->write(idx); |
| 79 | ptr->write(timeMs); |
| 80 | ptr->init(); |
| 81 | data->push_back(ptr); |
| 82 | VLOG("uid %lld, freq idx %d, active time %lld", (long long)uid, idx, (long long)timeMs); |
| 83 | idx++; |
| 84 | pch = strtok(NULL, " "); |
| 85 | } while (pch != NULL); |
| 86 | } |
| 87 | return true; |
| 88 | } |
| 89 | |
| 90 | } // namespace statsd |
| 91 | } // namespace os |
| 92 | } // namespace android |