From ec67661bdfe1814039f625575176678219acc7b1 Mon Sep 17 00:00:00 2001 From: Chenjie Yu Date: Wed, 7 Mar 2018 09:19:17 -0800 Subject: [PATCH] Refactor cpu stats pullers use same cpu stats readers with BatteryStats so that 1) both throttle to avoid too frequent pulls 2) cached value is served within throttle interval to avoid double pulling by both statsd and BatteryStats To run unit tests: bit FrameworksCoreTests:com.android.internal.os.KernelUidCpuFreqTimeReaderTest bit FrameworksCoreTests:com.android.internal.os.KernelUidCpuClusterTimeReaderTest bit FrameworksCoreTests:com.android.internal.os.KernelUidCpuActiveTimeReaderTest make -j56 statsd_test && adb sync data && adb shell /data/nativetest64/statsd_test/statsd_test Test: cts test, unit test Bug: 73745189 Bug: 73780619 Bug: 73360959 Merged-In: I10a9bc91ca67fa812f4cd71c4fbd73c1a5ba580e Change-Id: I10a9bc91ca67fa812f4cd71c4fbd73c1a5ba580e --- cmds/statsd/Android.mk | 4 - cmds/statsd/src/atoms.proto | 16 ++- .../src/external/CpuTimePerUidFreqPuller.cpp | 100 ------------------ .../src/external/CpuTimePerUidFreqPuller.h | 42 -------- .../src/external/CpuTimePerUidPuller.cpp | 90 ---------------- .../statsd/src/external/CpuTimePerUidPuller.h | 42 -------- .../external/KernelUidCpuActiveTimeReader.cpp | 92 ---------------- .../external/KernelUidCpuActiveTimeReader.h | 34 ------ .../KernelUidCpuClusterTimeReader.cpp | 90 ---------------- .../external/KernelUidCpuClusterTimeReader.h | 42 -------- .../src/external/StatsPullerManagerImpl.cpp | 47 ++++---- .../tests/external/puller_util_test.cpp | 2 +- .../os/KernelUidCpuActiveTimeReader.java | 11 ++ .../os/KernelUidCpuClusterTimeReader.java | 17 +++ .../os/KernelUidCpuFreqTimeReader.java | 11 ++ .../internal/os/KernelUidCpuTimeReader.java | 24 +++++ .../os/KernelUidCpuActiveTimeReaderTest.java | 24 +++++ .../os/KernelUidCpuClusterTimeReaderTest.java | 28 +++++ .../os/KernelUidCpuFreqTimeReaderTest.java | 40 +++++++ .../server/stats/StatsCompanionService.java | 85 ++++++++++++++- 20 files changed, 270 insertions(+), 571 deletions(-) delete mode 100644 cmds/statsd/src/external/CpuTimePerUidFreqPuller.cpp delete mode 100644 cmds/statsd/src/external/CpuTimePerUidFreqPuller.h delete mode 100644 cmds/statsd/src/external/CpuTimePerUidPuller.cpp delete mode 100644 cmds/statsd/src/external/CpuTimePerUidPuller.h delete mode 100644 cmds/statsd/src/external/KernelUidCpuActiveTimeReader.cpp delete mode 100644 cmds/statsd/src/external/KernelUidCpuActiveTimeReader.h delete mode 100644 cmds/statsd/src/external/KernelUidCpuClusterTimeReader.cpp delete mode 100644 cmds/statsd/src/external/KernelUidCpuClusterTimeReader.h diff --git a/cmds/statsd/Android.mk b/cmds/statsd/Android.mk index 8ecb538a16066..605198f4b72a2 100644 --- a/cmds/statsd/Android.mk +++ b/cmds/statsd/Android.mk @@ -40,10 +40,6 @@ statsd_common_src := \ src/external/SubsystemSleepStatePuller.cpp \ src/external/ResourceHealthManagerPuller.cpp \ src/external/ResourceThermalManagerPuller.cpp \ - src/external/CpuTimePerUidPuller.cpp \ - src/external/CpuTimePerUidFreqPuller.cpp \ - src/external/KernelUidCpuActiveTimeReader.cpp \ - src/external/KernelUidCpuClusterTimeReader.cpp \ src/external/StatsPullerManagerImpl.cpp \ src/external/puller_util.cpp \ src/logd/LogEvent.cpp \ diff --git a/cmds/statsd/src/atoms.proto b/cmds/statsd/src/atoms.proto index fa96e113280e1..9bfbd38f89323 100644 --- a/cmds/statsd/src/atoms.proto +++ b/cmds/statsd/src/atoms.proto @@ -1489,7 +1489,7 @@ message CpuTimePerFreq { * Note that isolated process uid time should be attributed to host uids. */ message CpuTimePerUid { - optional uint64 uid = 1; + optional int32 uid = 1; optional uint64 user_time_millis = 2; optional uint64 sys_time_millis = 3; } @@ -1500,8 +1500,8 @@ message CpuTimePerUid { * For each uid, we order the time by descending frequencies. */ message CpuTimePerUidFreq { - optional uint64 uid = 1; - optional uint64 freq_idx = 2; + optional int32 uid = 1; + optional uint32 freq_index = 2; optional uint64 time_millis = 3; } @@ -1634,10 +1634,8 @@ message SystemUptime { * The file contains a monotonically increasing count of time for a single boot. */ message CpuActiveTime { - optional uint64 uid = 1; - optional uint32 cluster_number = 2; - optional uint64 idx = 3; - optional uint64 time_millis = 4; + optional int32 uid = 1; + optional uint64 time_millis = 2; } /** @@ -1650,8 +1648,8 @@ message CpuActiveTime { * The file contains a monotonically increasing count of time for a single boot. */ message CpuClusterTime { - optional uint64 uid = 1; - optional uint64 idx = 2; + optional int32 uid = 1; + optional int32 cluster_index = 2; optional uint64 time_millis = 3; } diff --git a/cmds/statsd/src/external/CpuTimePerUidFreqPuller.cpp b/cmds/statsd/src/external/CpuTimePerUidFreqPuller.cpp deleted file mode 100644 index d1d9d3778267f..0000000000000 --- a/cmds/statsd/src/external/CpuTimePerUidFreqPuller.cpp +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright (C) 2017 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 false // STOPSHIP if true -#include "Log.h" - -#include -#include "external/CpuTimePerUidFreqPuller.h" - -#include "../guardrail/StatsdStats.h" -#include "CpuTimePerUidFreqPuller.h" -#include "guardrail/StatsdStats.h" -#include "logd/LogEvent.h" -#include "statslog.h" -#include "stats_log_util.h" - -using std::make_shared; -using std::shared_ptr; -using std::ifstream; - -namespace android { -namespace os { -namespace statsd { - -static const string sProcFile = "/proc/uid_time_in_state"; -static const int kLineBufferSize = 1024; - -/** - * Reads /proc/uid_time_in_state which has the format: - * - * uid: [freq1] [freq2] [freq3] ... - * [uid1]: [time in freq1] [time in freq2] [time in freq3] ... - * [uid2]: [time in freq1] [time in freq2] [time in freq3] ... - * ... - * - * This provides the times a UID's processes spent executing at each different cpu frequency. - * The file contains a monotonically increasing count of time for a single boot. - */ -CpuTimePerUidFreqPuller::CpuTimePerUidFreqPuller() - : StatsPuller(android::util::CPU_TIME_PER_UID_FREQ) { -} - -bool CpuTimePerUidFreqPuller::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; - } - - int64_t wallClockTimestampNs = getWallClockNs(); - int64_t elapsedTimestampNs = getElapsedRealtimeNs(); - - char buf[kLineBufferSize]; - // first line prints the format and frequencies - fin.getline(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(android::util::CPU_TIME_PER_UID_FREQ, - wallClockTimestampNs, elapsedTimestampNs); - ptr->write(uid); - ptr->write(idx); - ptr->write(timeMs); - ptr->init(); - data->push_back(ptr); - VLOG("uid %lld, freq idx %d, sys 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/CpuTimePerUidFreqPuller.h b/cmds/statsd/src/external/CpuTimePerUidFreqPuller.h deleted file mode 100644 index 6f6c669fbea90..0000000000000 --- a/cmds/statsd/src/external/CpuTimePerUidFreqPuller.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (C) 2017 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 CpuTimePerUidFreqPuller : public StatsPuller { - public: - CpuTimePerUidFreqPuller(); - bool PullInternal(vector>* data) override; -}; - -} // namespace statsd -} // namespace os -} // namespace android diff --git a/cmds/statsd/src/external/CpuTimePerUidPuller.cpp b/cmds/statsd/src/external/CpuTimePerUidPuller.cpp deleted file mode 100644 index 568b8f0c0c535..0000000000000 --- a/cmds/statsd/src/external/CpuTimePerUidPuller.cpp +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright (C) 2017 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 false // STOPSHIP if true -#include "Log.h" - -#include -#include "external/CpuTimePerUidPuller.h" - -#include "CpuTimePerUidPuller.h" -#include "guardrail/StatsdStats.h" -#include "logd/LogEvent.h" -#include "statslog.h" -#include "stats_log_util.h" - -using std::make_shared; -using std::shared_ptr; -using std::ifstream; - -namespace android { -namespace os { -namespace statsd { - -static const string sProcFile = "/proc/uid_cputime/show_uid_stat"; -static const int kLineBufferSize = 1024; - -/** - * Reads /proc/uid_cputime/show_uid_stat which has the line format: - * - * uid: user_time_micro_seconds system_time_micro_seconds power_in_milli-amp-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. - */ -CpuTimePerUidPuller::CpuTimePerUidPuller() : StatsPuller(android::util::CPU_TIME_PER_UID) { -} - -bool CpuTimePerUidPuller::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; - } - - int64_t wallClockTimestampNs = getWallClockNs(); - int64_t elapsedTimestampNs = getElapsedRealtimeNs(); - 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(buf, " "); - uint64_t userTimeMs = std::stoull(pch); - pch = strtok(buf, " "); - uint64_t sysTimeMs = std::stoull(pch); - - auto ptr = make_shared(android::util::CPU_TIME_PER_UID, - wallClockTimestampNs, elapsedTimestampNs); - ptr->write(uid); - ptr->write(userTimeMs); - ptr->write(sysTimeMs); - ptr->init(); - data->push_back(ptr); - VLOG("uid %lld, user time %lld, sys time %lld", (long long)uid, (long long)userTimeMs, - (long long)sysTimeMs); - } - return true; -} - -} // namespace statsd -} // namespace os -} // namespace android diff --git a/cmds/statsd/src/external/CpuTimePerUidPuller.h b/cmds/statsd/src/external/CpuTimePerUidPuller.h deleted file mode 100644 index d0d39d03aa5d0..0000000000000 --- a/cmds/statsd/src/external/CpuTimePerUidPuller.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (C) 2017 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 CpuTimePerUidPuller : public StatsPuller { - public: - CpuTimePerUidPuller(); - bool PullInternal(vector>* data) override; -}; - -} // namespace statsd -} // namespace os -} // namespace android diff --git a/cmds/statsd/src/external/KernelUidCpuActiveTimeReader.cpp b/cmds/statsd/src/external/KernelUidCpuActiveTimeReader.cpp deleted file mode 100644 index 0b545ccb36587..0000000000000 --- a/cmds/statsd/src/external/KernelUidCpuActiveTimeReader.cpp +++ /dev/null @@ -1,92 +0,0 @@ -/* - * 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 false // STOPSHIP if true -#include "Log.h" - -#include - -#include "KernelUidCpuActiveTimeReader.h" -#include "guardrail/StatsdStats.h" -#include "logd/LogEvent.h" -#include "statslog.h" -#include "stats_log_util.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; - } - - int64_t wallClockTimestampNs = getWallClockNs(); - int64_t elapsedTimestampNs = getElapsedRealtimeNs(); - - 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, wallClockTimestampNs, elapsedTimestampNs); - 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 deleted file mode 100644 index fcae35fa6eb5b..0000000000000 --- a/cmds/statsd/src/external/KernelUidCpuActiveTimeReader.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * 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 deleted file mode 100644 index cc80204b105eb..0000000000000 --- a/cmds/statsd/src/external/KernelUidCpuClusterTimeReader.cpp +++ /dev/null @@ -1,90 +0,0 @@ -/* - * 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 false // STOPSHIP if true -#include "Log.h" - -#include -#include "KernelUidCpuClusterTimeReader.h" -#include "guardrail/StatsdStats.h" -#include "logd/LogEvent.h" -#include "statslog.h" -#include "stats_log_util.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; - } - - int64_t wallClockTimestampNs = getWallClockNs(); - int64_t elapsedTimestampNs = getElapsedRealtimeNs(); - 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, wallClockTimestampNs, elapsedTimestampNs); - 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 deleted file mode 100644 index 90236ae007623..0000000000000 --- a/cmds/statsd/src/external/KernelUidCpuClusterTimeReader.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * 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 880dfd1cd6c77..72a00cb6834e0 100644 --- a/cmds/statsd/src/external/StatsPullerManagerImpl.cpp +++ b/cmds/statsd/src/external/StatsPullerManagerImpl.cpp @@ -21,10 +21,6 @@ #include #include #include -#include "CpuTimePerUidFreqPuller.h" -#include "CpuTimePerUidPuller.h" -#include "KernelUidCpuActiveTimeReader.h" -#include "KernelUidCpuClusterTimeReader.h" #include "ResourceHealthManagerPuller.h" #include "ResourceThermalManagerPuller.h" #include "StatsCompanionServicePuller.h" @@ -51,27 +47,19 @@ namespace statsd { const std::map StatsPullerManagerImpl::kAllPullAtomInfo = { // wifi_bytes_transfer {android::util::WIFI_BYTES_TRANSFER, - {{2, 3, 4, 5}, - {}, - 1, + {{2, 3, 4, 5}, {}, 1, new StatsCompanionServicePuller(android::util::WIFI_BYTES_TRANSFER)}}, // wifi_bytes_transfer_by_fg_bg {android::util::WIFI_BYTES_TRANSFER_BY_FG_BG, - {{3, 4, 5, 6}, - {2}, - 1, + {{3, 4, 5, 6}, {2}, 1, new StatsCompanionServicePuller(android::util::WIFI_BYTES_TRANSFER_BY_FG_BG)}}, // mobile_bytes_transfer {android::util::MOBILE_BYTES_TRANSFER, - {{2, 3, 4, 5}, - {}, - 1, + {{2, 3, 4, 5}, {}, 1, new StatsCompanionServicePuller(android::util::MOBILE_BYTES_TRANSFER)}}, // mobile_bytes_transfer_by_fg_bg {android::util::MOBILE_BYTES_TRANSFER_BY_FG_BG, - {{3, 4, 5, 6}, - {2}, - 1, + {{3, 4, 5, 6}, {2}, 1, new StatsCompanionServicePuller(android::util::MOBILE_BYTES_TRANSFER_BY_FG_BG)}}, // bluetooth_bytes_transfer {android::util::BLUETOOTH_BYTES_TRANSFER, @@ -80,14 +68,26 @@ const std::map StatsPullerManagerImpl::kAllPullAtomInfo = { {android::util::KERNEL_WAKELOCK, {{}, {}, 1, new StatsCompanionServicePuller(android::util::KERNEL_WAKELOCK)}}, // subsystem_sleep_state - {android::util::SUBSYSTEM_SLEEP_STATE, {{}, {}, 1, new SubsystemSleepStatePuller()}}, + {android::util::SUBSYSTEM_SLEEP_STATE, + {{}, {}, 1, new SubsystemSleepStatePuller()}}, // cpu_time_per_freq {android::util::CPU_TIME_PER_FREQ, {{3}, {2}, 1, new StatsCompanionServicePuller(android::util::CPU_TIME_PER_FREQ)}}, // cpu_time_per_uid - {android::util::CPU_TIME_PER_UID, {{2, 3}, {}, 1, new CpuTimePerUidPuller()}}, + {android::util::CPU_TIME_PER_UID, + {{2, 3}, {}, 1, new StatsCompanionServicePuller(android::util::CPU_TIME_PER_UID)}}, // cpu_time_per_uid_freq - {android::util::CPU_TIME_PER_UID_FREQ, {{3}, {2}, 1, new CpuTimePerUidFreqPuller()}}, + // the throttling is 3sec, handled in frameworks/base/core/java/com/android/internal/os/KernelCpuProcReader + {android::util::CPU_TIME_PER_UID_FREQ, + {{4}, {2,3}, 0, new StatsCompanionServicePuller(android::util::CPU_TIME_PER_UID_FREQ)}}, + // cpu_active_time + // the throttling is 3sec, handled in frameworks/base/core/java/com/android/internal/os/KernelCpuProcReader + {android::util::CPU_ACTIVE_TIME, + {{2}, {}, 0, new StatsCompanionServicePuller(android::util::CPU_ACTIVE_TIME)}}, + // cpu_cluster_time + // the throttling is 3sec, handled in frameworks/base/core/java/com/android/internal/os/KernelCpuProcReader + {android::util::CPU_CLUSTER_TIME, + {{3}, {2}, 0, new StatsCompanionServicePuller(android::util::CPU_CLUSTER_TIME)}}, // wifi_activity_energy_info {android::util::WIFI_ACTIVITY_ENERGY_INFO, {{}, {}, 1, new StatsCompanionServicePuller(android::util::WIFI_ACTIVITY_ENERGY_INFO)}}, @@ -103,10 +103,6 @@ const std::map StatsPullerManagerImpl::kAllPullAtomInfo = { // system_uptime {android::util::SYSTEM_UPTIME, {{}, {}, 1, new StatsCompanionServicePuller(android::util::SYSTEM_UPTIME)}}, - // cpu_active_time - {android::util::CPU_ACTIVE_TIME, {{3}, {2}, 1, new KernelUidCpuActiveTimeReader()}}, - // cpu_cluster_time - {android::util::CPU_CLUSTER_TIME, {{3}, {2}, 1, new KernelUidCpuClusterTimeReader()}}, // disk_space {android::util::DISK_SPACE, {{}, {}, 1, new StatsCompanionServicePuller(android::util::DISK_SPACE)}}, @@ -118,7 +114,10 @@ const std::map StatsPullerManagerImpl::kAllPullAtomInfo = { {{}, {}, 1, new ResourceHealthManagerPuller(android::util::FULL_BATTERY_CAPACITY)}}, // process_memory_state {android::util::PROCESS_MEMORY_STATE, - {{4,5,6,7,8}, {2,3}, 0, new StatsCompanionServicePuller(android::util::PROCESS_MEMORY_STATE)}}, + {{4,5,6,7,8}, + {2,3}, + 0, + new StatsCompanionServicePuller(android::util::PROCESS_MEMORY_STATE)}}, // temperature {android::util::TEMPERATURE, {{}, {}, 1, new ResourceThermalManagerPuller()}}}; diff --git a/cmds/statsd/tests/external/puller_util_test.cpp b/cmds/statsd/tests/external/puller_util_test.cpp index 7d9c8a8208eef..fc6e42010710c 100644 --- a/cmds/statsd/tests/external/puller_util_test.cpp +++ b/cmds/statsd/tests/external/puller_util_test.cpp @@ -34,7 +34,7 @@ using testing::Contains; * Test merge isolated and host uid */ -int uidAtomTagId = android::util::CPU_TIME_PER_UID_FREQ; +int uidAtomTagId = android::util::CPU_CLUSTER_TIME; int nonUidAtomTagId = android::util::SYSTEM_UPTIME; int timestamp = 1234; int isolatedUid = 30; diff --git a/core/java/com/android/internal/os/KernelUidCpuActiveTimeReader.java b/core/java/com/android/internal/os/KernelUidCpuActiveTimeReader.java index ce45f3c988cbd..e790e08520cbc 100644 --- a/core/java/com/android/internal/os/KernelUidCpuActiveTimeReader.java +++ b/core/java/com/android/internal/os/KernelUidCpuActiveTimeReader.java @@ -123,6 +123,17 @@ public class KernelUidCpuActiveTimeReader extends } } + public void readAbsolute(Callback cb) { + synchronized (mProcReader) { + readDelta(null); + int total = mLastUidCpuActiveTimeMs.size(); + for (int i = 0; i < total; i ++){ + int uid = mLastUidCpuActiveTimeMs.keyAt(i); + cb.onUidCpuActiveTime(uid, mLastUidCpuActiveTimeMs.get(uid).longValue()); + } + } + } + public void removeUid(int uid) { mLastUidCpuActiveTimeMs.delete(uid); } diff --git a/core/java/com/android/internal/os/KernelUidCpuClusterTimeReader.java b/core/java/com/android/internal/os/KernelUidCpuClusterTimeReader.java index c21b7665c7ae4..bf5b5203eb3f7 100644 --- a/core/java/com/android/internal/os/KernelUidCpuClusterTimeReader.java +++ b/core/java/com/android/internal/os/KernelUidCpuClusterTimeReader.java @@ -65,6 +65,7 @@ public class KernelUidCpuClusterTimeReader extends private double[] mCurTime; // Reuse to avoid GC. private long[] mDeltaTime; // Reuse to avoid GC. + private long[] mCurTimeRounded; // Reuse to avoid GC. public interface Callback extends KernelUidCpuTimeReaderBase.Callback { /** @@ -137,6 +138,21 @@ public class KernelUidCpuClusterTimeReader extends } } + public void readAbsolute(Callback cb) { + synchronized (mProcReader) { + readDelta(null); + int total = mLastUidPolicyTimeMs.size(); + for (int i = 0; i < total; i ++){ + int uid = mLastUidPolicyTimeMs.keyAt(i); + double[] lastTimes = mLastUidPolicyTimeMs.get(uid); + for (int j = 0; j < mNumClusters; j++) { + mCurTimeRounded[j] = (long) lastTimes[j]; + } + cb.onUidCpuPolicyTime(uid, mCurTimeRounded); + } + } + } + private void processUid(IntBuffer buf, @Nullable Callback cb) { int uid = buf.get(); double[] lastTimes = mLastUidPolicyTimeMs.get(uid); @@ -189,6 +205,7 @@ public class KernelUidCpuClusterTimeReader extends mNumCoresOnCluster = numCoresOnCluster; mCurTime = new double[numClusters]; mDeltaTime = new long[numClusters]; + mCurTimeRounded = new long[numClusters]; return true; } diff --git a/core/java/com/android/internal/os/KernelUidCpuFreqTimeReader.java b/core/java/com/android/internal/os/KernelUidCpuFreqTimeReader.java index a0787a039dbe1..f65074f65d874 100644 --- a/core/java/com/android/internal/os/KernelUidCpuFreqTimeReader.java +++ b/core/java/com/android/internal/os/KernelUidCpuFreqTimeReader.java @@ -226,6 +226,17 @@ public class KernelUidCpuFreqTimeReader extends } } + public void readAbsolute(Callback cb) { + synchronized (mProcReader) { + readDelta(null); + int total = mLastUidCpuFreqTimeMs.size(); + for (int i = 0; i < total; i ++){ + int uid = mLastUidCpuFreqTimeMs.keyAt(i); + cb.onUidCpuFreqTime(uid, mLastUidCpuFreqTimeMs.get(uid)); + } + } + } + public void removeUid(int uid) { mLastUidCpuFreqTimeMs.delete(uid); } diff --git a/core/java/com/android/internal/os/KernelUidCpuTimeReader.java b/core/java/com/android/internal/os/KernelUidCpuTimeReader.java index 4263b832bd4fe..97b7211e5e878 100644 --- a/core/java/com/android/internal/os/KernelUidCpuTimeReader.java +++ b/core/java/com/android/internal/os/KernelUidCpuTimeReader.java @@ -134,6 +134,30 @@ public class KernelUidCpuTimeReader extends mLastTimeReadUs = nowUs; } + /** + * Reads the proc file, calling into the callback with raw absolute value of time for each UID. + * @param callback The callback to invoke for each line of the proc file. + */ + public void readAbsolute(Callback callback) { + final int oldMask = StrictMode.allowThreadDiskReadsMask(); + try (BufferedReader reader = new BufferedReader(new FileReader(sProcFile))) { + TextUtils.SimpleStringSplitter splitter = new TextUtils.SimpleStringSplitter(' '); + String line; + while ((line = reader.readLine()) != null) { + splitter.setString(line); + final String uidStr = splitter.next(); + final int uid = Integer.parseInt(uidStr.substring(0, uidStr.length() - 1), 10); + final long userTimeUs = Long.parseLong(splitter.next(), 10); + final long systemTimeUs = Long.parseLong(splitter.next(), 10); + callback.onUidCpuTime(uid, userTimeUs, systemTimeUs); + } + } catch (IOException e) { + Slog.e(TAG, "Failed to read uid_cputime: " + e.getMessage()); + } finally { + StrictMode.setThreadPolicyMask(oldMask); + } + } + /** * Removes the UID from the kernel module and from internal accounting data. Only * {@link BatteryStatsImpl} and its child processes should call this, as the change on Kernel is diff --git a/core/tests/coretests/src/com/android/internal/os/KernelUidCpuActiveTimeReaderTest.java b/core/tests/coretests/src/com/android/internal/os/KernelUidCpuActiveTimeReaderTest.java index 312af16cc8a66..06f51c9c42a8f 100644 --- a/core/tests/coretests/src/com/android/internal/os/KernelUidCpuActiveTimeReaderTest.java +++ b/core/tests/coretests/src/com/android/internal/os/KernelUidCpuActiveTimeReaderTest.java @@ -103,6 +103,30 @@ public class KernelUidCpuActiveTimeReaderTest { verifyNoMoreInteractions(mCallback); } + @Test + public void testReadAbsolute() throws Exception { + final int cores = 8; + final int[] uids = {1, 22, 333, 4444, 5555}; + + final long[][] times = increaseTime(new long[uids.length][cores]); + when(mProcReader.readBytes()).thenReturn(getUidTimesBytes(uids, times)); + mReader.readAbsolute(mCallback); + for (int i = 0; i < uids.length; i++) { + verify(mCallback).onUidCpuActiveTime(uids[i], getTotal(times[i])); + } + verifyNoMoreInteractions(mCallback); + + // Verify that a second call still returns absolute values + Mockito.reset(mCallback); + final long[][] times1 = increaseTime(times); + when(mProcReader.readBytes()).thenReturn(getUidTimesBytes(uids, times1)); + mReader.readAbsolute(mCallback); + for (int i = 0; i < uids.length; i++) { + verify(mCallback).onUidCpuActiveTime(uids[i], getTotal(times1[i])); + } + verifyNoMoreInteractions(mCallback); + } + @Test public void testReadDelta_malformedData() throws Exception { final int cores = 8; diff --git a/core/tests/coretests/src/com/android/internal/os/KernelUidCpuClusterTimeReaderTest.java b/core/tests/coretests/src/com/android/internal/os/KernelUidCpuClusterTimeReaderTest.java index d21f541345291..85dce020ddd4f 100644 --- a/core/tests/coretests/src/com/android/internal/os/KernelUidCpuClusterTimeReaderTest.java +++ b/core/tests/coretests/src/com/android/internal/os/KernelUidCpuClusterTimeReaderTest.java @@ -113,6 +113,34 @@ public class KernelUidCpuClusterTimeReaderTest { } + @Test + public void testReadAbsolute() throws Exception { + VerifiableCallback cb = new VerifiableCallback(); + final int cores = 6; + final int[] clusters = {2, 4}; + final int[] uids = {1, 22, 333, 4444, 5555}; + + // Verify return absolute value + final long[][] times = increaseTime(new long[uids.length][cores]); + when(mProcReader.readBytes()).thenReturn(getUidTimesBytes(uids, clusters, times)); + mReader.readAbsolute(cb); + for (int i = 0; i < uids.length; i++) { + cb.verify(uids[i], getTotal(clusters, times[i])); + } + cb.verifyNoMoreInteractions(); + + // Verify that a second call should return the same absolute value + cb.clear(); + Mockito.reset(mProcReader); + final long[][] times1 = increaseTime(times); + when(mProcReader.readBytes()).thenReturn(getUidTimesBytes(uids, clusters, times1)); + mReader.readAbsolute(cb); + for (int i = 0; i < uids.length; i++) { + cb.verify(uids[i], getTotal(clusters, times1[i])); + } + cb.verifyNoMoreInteractions(); + } + @Test public void testReadDelta_malformedData() throws Exception { final int cores = 6; diff --git a/core/tests/coretests/src/com/android/internal/os/KernelUidCpuFreqTimeReaderTest.java b/core/tests/coretests/src/com/android/internal/os/KernelUidCpuFreqTimeReaderTest.java index 09507218d01a2..a6b99c30315a5 100644 --- a/core/tests/coretests/src/com/android/internal/os/KernelUidCpuFreqTimeReaderTest.java +++ b/core/tests/coretests/src/com/android/internal/os/KernelUidCpuFreqTimeReaderTest.java @@ -296,6 +296,46 @@ public class KernelUidCpuFreqTimeReaderTest { cb.verifyNoMoreInteractions(); } + @Test + public void testReadAbsolute() throws Exception { + VerifiableCallback cb = new VerifiableCallback(); + final long[] freqs = {110, 123, 145, 167, 289, 997}; + final int[] uids = {1, 22, 333, 444, 555}; + final long[][] times = new long[uids.length][freqs.length]; + for (int i = 0; i < uids.length; ++i) { + for (int j = 0; j < freqs.length; ++j) { + times[i][j] = uids[i] * freqs[j] * 10; + } + } + when(mBufferedReader.readLine()).thenReturn(getFreqsLine(freqs)); + long[] actualFreqs = mKernelUidCpuFreqTimeReader.readFreqs(mBufferedReader, mPowerProfile); + + assertArrayEquals(freqs, actualFreqs); + // Verify that the absolute values are returned + when(mProcReader.readBytes()).thenReturn(getUidTimesBytes(uids, times)); + mKernelUidCpuFreqTimeReader.readAbsolute(cb); + for (int i = 0; i < uids.length; ++i) { + cb.verify(uids[i], times[i]); + } + cb.verifyNoMoreInteractions(); + + // Verify that a second call should still return absolute values + cb.clear(); + Mockito.reset(mProcReader); + final long[][] newTimes1 = new long[uids.length][freqs.length]; + for (int i = 0; i < uids.length; ++i) { + for (int j = 0; j < freqs.length; ++j) { + newTimes1[i][j] = times[i][j] + (uids[i] + freqs[j]) * 50; + } + } + when(mProcReader.readBytes()).thenReturn(getUidTimesBytes(uids, newTimes1)); + mKernelUidCpuFreqTimeReader.readAbsolute(cb); + for (int i = 0; i < uids.length; ++i) { + cb.verify(uids[i], newTimes1[i]); + } + cb.verifyNoMoreInteractions(); + } + @Test public void testReadDelta_malformedData() throws Exception { final long[] freqs = {1, 12, 123, 1234, 12345, 123456}; diff --git a/services/core/java/com/android/server/stats/StatsCompanionService.java b/services/core/java/com/android/server/stats/StatsCompanionService.java index 6e017cd0a3d17..64a2570c56315 100644 --- a/services/core/java/com/android/server/stats/StatsCompanionService.java +++ b/services/core/java/com/android/server/stats/StatsCompanionService.java @@ -61,12 +61,17 @@ import android.util.StatsLog; import com.android.internal.annotations.GuardedBy; import com.android.internal.net.NetworkStatsFactory; import com.android.internal.os.KernelCpuSpeedReader; +import com.android.internal.os.KernelUidCpuTimeReader; +import com.android.internal.os.KernelUidCpuClusterTimeReader; +import com.android.internal.os.KernelUidCpuActiveTimeReader; +import com.android.internal.os.KernelUidCpuFreqTimeReader; import com.android.internal.os.KernelWakelockReader; import com.android.internal.os.KernelWakelockStats; import com.android.internal.os.PowerProfile; import com.android.server.LocalServices; import com.android.server.SystemService; +import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.Map; @@ -106,7 +111,6 @@ public class StatsCompanionService extends IStatsCompanionService.Stub { private final ShutdownEventReceiver mShutdownEventReceiver; private final KernelWakelockReader mKernelWakelockReader = new KernelWakelockReader(); private final KernelWakelockStats mTmpWakelockStats = new KernelWakelockStats(); - private final KernelCpuSpeedReader[] mKernelCpuSpeedReaders; private IWifiManager mWifiManager = null; private TelephonyManager mTelephony = null; private final StatFs mStatFsData = new StatFs(Environment.getDataDirectory().getAbsolutePath()); @@ -115,6 +119,15 @@ public class StatsCompanionService extends IStatsCompanionService.Stub { private final StatFs mStatFsTemp = new StatFs(Environment.getDownloadCacheDirectory().getAbsolutePath()); + private KernelUidCpuTimeReader mKernelUidCpuTimeReader = new KernelUidCpuTimeReader(); + private KernelCpuSpeedReader[] mKernelCpuSpeedReaders; + private KernelUidCpuFreqTimeReader mKernelUidCpuFreqTimeReader = + new KernelUidCpuFreqTimeReader(); + private KernelUidCpuActiveTimeReader mKernelUidCpuActiveTimeReader = + new KernelUidCpuActiveTimeReader(); + private KernelUidCpuClusterTimeReader mKernelUidCpuClusterTimeReader = + new KernelUidCpuClusterTimeReader(); + public StatsCompanionService(Context context) { super(); mContext = context; @@ -159,6 +172,13 @@ public class StatsCompanionService extends IStatsCompanionService.Stub { numSpeedSteps); firstCpuOfCluster += powerProfile.getNumCoresInCpuCluster(i); } + // use default throttling in + // frameworks/base/core/java/com/android/internal/os/KernelCpuProcReader + mKernelUidCpuFreqTimeReader.setThrottleInterval(0); + long[] freqs = mKernelUidCpuFreqTimeReader.readFreqs(powerProfile); + mKernelUidCpuFreqTimeReader.setReadBinary(true); + mKernelUidCpuClusterTimeReader.setThrottleInterval(0); + mKernelUidCpuActiveTimeReader.setThrottleInterval(0); } @Override @@ -676,6 +696,53 @@ public class StatsCompanionService extends IStatsCompanionService.Stub { } } + private void pullKernelUidCpuTime(int tagId, List pulledData) { + long elapsedNanos = SystemClock.elapsedRealtimeNanos(); + mKernelUidCpuTimeReader.readAbsolute((uid, userTimeUs, systemTimeUs) -> { + StatsLogEventWrapper e = new StatsLogEventWrapper(elapsedNanos, tagId, 3); + e.writeInt(uid); + e.writeLong(userTimeUs); + e.writeLong(systemTimeUs); + pulledData.add(e); + }); + } + + private void pullKernelUidCpuFreqTime(int tagId, List pulledData) { + long elapsedNanos = SystemClock.elapsedRealtimeNanos(); + mKernelUidCpuFreqTimeReader.readAbsolute((uid, cpuFreqTimeMs) -> { + for (int freqIndex = 0; freqIndex < cpuFreqTimeMs.length; ++freqIndex) { + StatsLogEventWrapper e = new StatsLogEventWrapper(elapsedNanos, tagId, 3); + e.writeInt(uid); + e.writeInt(freqIndex); + e.writeLong(cpuFreqTimeMs[freqIndex]); + pulledData.add(e); + } + }); + } + + private void pullKernelUidCpuClusterTime(int tagId, List pulledData) { + long elapsedNanos = SystemClock.elapsedRealtimeNanos(); + mKernelUidCpuClusterTimeReader.readAbsolute((uid, cpuClusterTimesMs) -> { + for (int i = 0; i < cpuClusterTimesMs.length; i++) { + StatsLogEventWrapper e = new StatsLogEventWrapper(elapsedNanos, tagId, 3); + e.writeInt(uid); + e.writeInt(i); + e.writeLong(cpuClusterTimesMs[i]); + pulledData.add(e); + } + }); + } + + private void pullKernelUidCpuActiveTime(int tagId, List pulledData) { + long elapsedNanos = SystemClock.elapsedRealtimeNanos(); + mKernelUidCpuActiveTimeReader.readAbsolute((uid, cpuActiveTimesMs) -> { + StatsLogEventWrapper e = new StatsLogEventWrapper(elapsedNanos, tagId, 2); + e.writeInt(uid); + e.writeLong((long)cpuActiveTimesMs); + pulledData.add(e); + }); + } + private void pullWifiActivityEnergyInfo(int tagId, List pulledData) { long token = Binder.clearCallingIdentity(); if (mWifiManager == null) { @@ -828,6 +895,22 @@ public class StatsCompanionService extends IStatsCompanionService.Stub { pullCpuTimePerFreq(tagId, ret); break; } + case StatsLog.CPU_TIME_PER_UID: { + pullKernelUidCpuTime(tagId, ret); + break; + } + case StatsLog.CPU_TIME_PER_UID_FREQ: { + pullKernelUidCpuFreqTime(tagId, ret); + break; + } + case StatsLog.CPU_CLUSTER_TIME: { + pullKernelUidCpuClusterTime(tagId, ret); + break; + } + case StatsLog.CPU_ACTIVE_TIME: { + pullKernelUidCpuActiveTime(tagId, ret); + break; + } case StatsLog.WIFI_ACTIVITY_ENERGY_INFO: { pullWifiActivityEnergyInfo(tagId, ret); break;