From 9da105bb321e4c28db6fd88a2d6cb01852ffefe2 Mon Sep 17 00:00:00 2001 From: Chenjie Yu Date: Sat, 13 Jan 2018 12:41:08 -0800 Subject: [PATCH] add atoms for cpu power calculation Test: will add cts tests for them Change-Id: Ifefa3697ff64e8c484f79d08caf053bfc712b794 --- cmds/statsd/src/atoms.proto | 48 ++++++++++ .../external/KernelUidCpuActiveTimeReader.cpp | 89 +++++++++++++++++++ .../external/KernelUidCpuActiveTimeReader.h | 34 +++++++ .../KernelUidCpuClusterTimeReader.cpp | 88 ++++++++++++++++++ .../external/KernelUidCpuClusterTimeReader.h | 42 +++++++++ .../src/external/StatsPullerManagerImpl.cpp | 2 + .../server/stats/StatsCompanionService.java | 15 ++++ 7 files changed, 318 insertions(+) create mode 100644 cmds/statsd/src/external/KernelUidCpuActiveTimeReader.cpp create mode 100644 cmds/statsd/src/external/KernelUidCpuActiveTimeReader.h create mode 100644 cmds/statsd/src/external/KernelUidCpuClusterTimeReader.cpp create mode 100644 cmds/statsd/src/external/KernelUidCpuClusterTimeReader.h diff --git a/cmds/statsd/src/atoms.proto b/cmds/statsd/src/atoms.proto index f840894db416a..ef99c9f4d7e33 100644 --- a/cmds/statsd/src/atoms.proto +++ b/cmds/statsd/src/atoms.proto @@ -103,6 +103,10 @@ message Atom { WifiActivityEnergyInfo wifi_activity_energy_info = 10011; ModemActivityInfo modem_activity_info = 10012; MemoryStat memory_stat = 10013; + CpuSuspendTime cpu_suspend_time = 10014; + CpuIdleTime cpu_idle_time = 10015; + CpuActiveTime cpu_active_time = 10016; + CpuClusterTime cpu_cluster_time = 10017; } } @@ -1223,3 +1227,47 @@ message LmkEventOccurred { } optional State state = 4; } + +/* + * Cpu syspend time for cpu power calculation. + */ +message CpuSuspendTime { + optional uint64 time = 1; +} + +/* + * Cpu idle time for cpu power calculation. + */ +message CpuIdleTime { + optional uint64 time = 1; +} + +/* + * Reads from /proc/uid_concurrent_active_time which has the format: + * active: X (X is # cores) + * [uid0]: [time-0] [time-1] [time-2] ... (# entries = # cores) + * [uid1]: [time-0] [time-1] [time-2] ... ... + * ... + * Time-N means the CPU time a UID spent running concurrently with N other processes. + * The file contains a monotonically increasing count of time for a single boot. + */ +message CpuActiveTime { + optional uint64 uid = 1; + optional uint64 idx = 2; + optional uint64 time_ms = 3; +} + +/** + * Reads from /proc/uid_concurrent_policy_time which has the format: + * policy0: X policy4: Y (there are X cores on policy0, Y cores on policy4) + * [uid0]: [time-0-0] [time-0-1] ... [time-1-0] [time-1-1] ... + * [uid1]: [time-0-0] [time-0-1] ... [time-1-0] [time-1-1] ... + * ... + * Time-X-Y means the time a UID spent on clusterX running concurrently with Y other processes. + * The file contains a monotonically increasing count of time for a single boot. + */ +message CpuClusterTime { + optional uint64 uid = 1; + optional uint64 idx = 2; + optional uint64 time_ms = 3; +} \ No newline at end of file diff --git a/cmds/statsd/src/external/KernelUidCpuActiveTimeReader.cpp b/cmds/statsd/src/external/KernelUidCpuActiveTimeReader.cpp new file mode 100644 index 0000000000000..7a2d1991a5389 --- /dev/null +++ b/cmds/statsd/src/external/KernelUidCpuActiveTimeReader.cpp @@ -0,0 +1,89 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define DEBUG true // STOPSHIP if true +#include "Log.h" + +#include + +#include "KernelUidCpuActiveTimeReader.h" +#include "guardrail/StatsdStats.h" +#include "logd/LogEvent.h" +#include "statslog.h" + +using std::make_shared; +using std::shared_ptr; +using std::ifstream; + +namespace android { +namespace os { +namespace statsd { + +static const string sProcFile = "/proc/uid_concurrent_active_time"; +static const int kLineBufferSize = 1024; + +/** + * Reads /proc/uid_concurrent_active_time which has the format: + * active: X (X is # cores) + * [uid0]: [time-0] [time-1] [time-2] ... (# entries = # cores) + * [uid1]: [time-0] [time-1] [time-2] ... ... + * ... + * Time-N means the CPU time a UID spent running concurrently with N other processes. + * The file contains a monotonically increasing count of time for a single boot. + */ +KernelUidCpuActiveTimeReader::KernelUidCpuActiveTimeReader() : StatsPuller(android::util::CPU_ACTIVE_TIME) { +} + +bool KernelUidCpuActiveTimeReader::PullInternal(vector>* data) { + data->clear(); + + ifstream fin; + fin.open(sProcFile); + if (!fin.good()) { + VLOG("Failed to read pseudo file %s", sProcFile.c_str()); + return false; + } + + uint64_t timestamp = time(nullptr) * NS_PER_SEC; + char buf[kLineBufferSize]; + char* pch; + while (!fin.eof()) { + fin.getline(buf, kLineBufferSize); + pch = strtok(buf, " :"); + if (pch == NULL) break; + uint64_t uid = std::stoull(pch); + pch = strtok(NULL, " "); + uint64_t timeMs; + int idx = 0; + do { + timeMs = std::stoull(pch); + auto ptr = make_shared(mTagId, timestamp); + ptr->write(uid); + ptr->write(idx); + ptr->write(timeMs); + ptr->init(); + data->push_back(ptr); + VLOG("uid %lld, freq idx %d, active time %lld", (long long)uid, idx, (long long)timeMs); + idx++; + pch = strtok(NULL, " "); + } while (pch != NULL); + } + return true; +} + +} // namespace statsd +} // namespace os +} // namespace android diff --git a/cmds/statsd/src/external/KernelUidCpuActiveTimeReader.h b/cmds/statsd/src/external/KernelUidCpuActiveTimeReader.h new file mode 100644 index 0000000000000..fcae35fa6eb5b --- /dev/null +++ b/cmds/statsd/src/external/KernelUidCpuActiveTimeReader.h @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include +#include "StatsPuller.h" + +namespace android { +namespace os { +namespace statsd { + +class KernelUidCpuActiveTimeReader : public StatsPuller { + public: + KernelUidCpuActiveTimeReader(); + bool PullInternal(vector>* data) override; +}; + +} // namespace statsd +} // namespace os +} // namespace android diff --git a/cmds/statsd/src/external/KernelUidCpuClusterTimeReader.cpp b/cmds/statsd/src/external/KernelUidCpuClusterTimeReader.cpp new file mode 100644 index 0000000000000..7426e743c40f8 --- /dev/null +++ b/cmds/statsd/src/external/KernelUidCpuClusterTimeReader.cpp @@ -0,0 +1,88 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define DEBUG true // STOPSHIP if true +#include "Log.h" + +#include +#include "KernelUidCpuClusterTimeReader.h" +#include "guardrail/StatsdStats.h" +#include "logd/LogEvent.h" +#include "statslog.h" + +using std::make_shared; +using std::shared_ptr; +using std::ifstream; + +namespace android { +namespace os { +namespace statsd { + +static const string sProcFile = "/proc/uid_concurrent_policy_time"; +static const int kLineBufferSize = 1024; + +/** + * Reads /proc/uid_concurrent_policy_time which has the format: + * policy0: X policy4: Y (there are X cores on policy0, Y cores on policy4) + * [uid0]: [time-0-0] [time-0-1] ... [time-1-0] [time-1-1] ... + * [uid1]: [time-0-0] [time-0-1] ... [time-1-0] [time-1-1] ... + * ... + * Time-X-Y means the time a UID spent on clusterX running concurrently with Y other processes. + * The file contains a monotonically increasing count of time for a single boot. + */ +KernelUidCpuClusterTimeReader::KernelUidCpuClusterTimeReader() : StatsPuller(android::util::CPU_CLUSTER_TIME) { +} + +bool KernelUidCpuClusterTimeReader::PullInternal(vector>* data) { + data->clear(); + + ifstream fin; + fin.open(sProcFile); + if (!fin.good()) { + VLOG("Failed to read pseudo file %s", sProcFile.c_str()); + return false; + } + + uint64_t timestamp = time(nullptr) * NS_PER_SEC; + char buf[kLineBufferSize]; + char* pch; + while (!fin.eof()) { + fin.getline(buf, kLineBufferSize); + pch = strtok(buf, " :"); + if (pch == NULL) break; + uint64_t uid = std::stoull(pch); + pch = strtok(NULL, " "); + uint64_t timeMs; + int idx = 0; + do { + timeMs = std::stoull(pch); + auto ptr = make_shared(mTagId, timestamp); + ptr->write(uid); + ptr->write(idx); + ptr->write(timeMs); + ptr->init(); + data->push_back(ptr); + VLOG("uid %lld, freq idx %d, cluster time %lld", (long long)uid, idx, (long long)timeMs); + idx++; + pch = strtok(NULL, " "); + } while (pch != NULL); + } + return true; +} + +} // namespace statsd +} // namespace os +} // namespace android diff --git a/cmds/statsd/src/external/KernelUidCpuClusterTimeReader.h b/cmds/statsd/src/external/KernelUidCpuClusterTimeReader.h new file mode 100644 index 0000000000000..90236ae007623 --- /dev/null +++ b/cmds/statsd/src/external/KernelUidCpuClusterTimeReader.h @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include +#include "StatsPuller.h" + +namespace android { +namespace os { +namespace statsd { + +/** + * Reads /proc/uid_cputime/show_uid_stat which has the line format: + * + * uid: user_time_micro_seconds system_time_micro_seconds + * + * This provides the time a UID's processes spent executing in user-space and kernel-space. + * The file contains a monotonically increasing count of time for a single boot. + */ +class KernelUidCpuClusterTimeReader : public StatsPuller { + public: + KernelUidCpuClusterTimeReader(); + bool PullInternal(vector>* data) override; +}; + +} // namespace statsd +} // namespace os +} // namespace android diff --git a/cmds/statsd/src/external/StatsPullerManagerImpl.cpp b/cmds/statsd/src/external/StatsPullerManagerImpl.cpp index bb2e8c08dfe6f..79f1a5d84174c 100644 --- a/cmds/statsd/src/external/StatsPullerManagerImpl.cpp +++ b/cmds/statsd/src/external/StatsPullerManagerImpl.cpp @@ -64,6 +64,8 @@ StatsPullerManagerImpl::StatsPullerManagerImpl() mPullers.insert({android::util::CPU_TIME_PER_FREQ, make_shared(android::util::CPU_TIME_PER_FREQ)}); mPullers.insert({android::util::CPU_TIME_PER_UID, make_shared()}); mPullers.insert({android::util::CPU_TIME_PER_UID_FREQ, make_shared()}); + mPullers.insert({android::util::CPU_SUSPEND_TIME, make_shared(android::util::CPU_SUSPEND_TIME)}); + mPullers.insert({android::util::CPU_IDLE_TIME, make_shared(android::util::CPU_IDLE_TIME)}); mStatsCompanionService = StatsService::getStatsCompanionService(); } diff --git a/services/core/java/com/android/server/stats/StatsCompanionService.java b/services/core/java/com/android/server/stats/StatsCompanionService.java index 2f5e2f8665f95..4cb5e089bd83a 100644 --- a/services/core/java/com/android/server/stats/StatsCompanionService.java +++ b/services/core/java/com/android/server/stats/StatsCompanionService.java @@ -28,6 +28,7 @@ import android.content.pm.UserInfo; import android.net.NetworkStats; import android.net.wifi.IWifiManager; import android.net.wifi.WifiActivityEnergyInfo; +import android.os.SystemClock; import android.telephony.ModemActivityInfo; import android.telephony.TelephonyManager; import android.os.BatteryStatsInternal; @@ -621,6 +622,20 @@ public class StatsCompanionService extends IStatsCompanionService.Stub { } break; } + case StatsLog.CPU_SUSPEND_TIME: { + List ret = new ArrayList(); + StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, 1); + e.writeLong(SystemClock.elapsedRealtime()); + ret.add(e); + break; + } + case StatsLog.CPU_IDLE_TIME: { + List ret = new ArrayList(); + StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, 1); + e.writeLong(SystemClock.uptimeMillis()); + ret.add(e); + break; + } default: Slog.w(TAG, "No such tagId data as " + tagId); return null;