Merge "Refactor cpu stats pullers" into pi-dev

This commit is contained in:
Chenjie Yu
2018-03-08 00:24:00 +00:00
committed by Android (Google) Code Review
20 changed files with 270 additions and 571 deletions

View File

@@ -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 \

View File

@@ -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;
}

View File

@@ -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 <fstream>
#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<shared_ptr<LogEvent>>* 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<LogEvent>(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

View File

@@ -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 <utils/String16.h>
#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<std::shared_ptr<LogEvent>>* data) override;
};
} // namespace statsd
} // namespace os
} // namespace android

View File

@@ -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 <fstream>
#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<shared_ptr<LogEvent>>* 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<LogEvent>(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

View File

@@ -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 <utils/String16.h>
#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<std::shared_ptr<LogEvent>>* data) override;
};
} // namespace statsd
} // namespace os
} // namespace android

View File

@@ -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 <fstream>
#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<shared_ptr<LogEvent>>* 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<LogEvent>(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

View File

@@ -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 <utils/String16.h>
#include "StatsPuller.h"
namespace android {
namespace os {
namespace statsd {
class KernelUidCpuActiveTimeReader : public StatsPuller {
public:
KernelUidCpuActiveTimeReader();
bool PullInternal(vector<std::shared_ptr<LogEvent>>* data) override;
};
} // namespace statsd
} // namespace os
} // namespace android

View File

@@ -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 <fstream>
#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<shared_ptr<LogEvent>>* 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<LogEvent>(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

View File

@@ -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 <utils/String16.h>
#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<std::shared_ptr<LogEvent>>* data) override;
};
} // namespace statsd
} // namespace os
} // namespace android

View File

@@ -21,10 +21,6 @@
#include <cutils/log.h>
#include <algorithm>
#include <climits>
#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<int, PullAtomInfo> 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<int, PullAtomInfo> 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<int, PullAtomInfo> 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<int, PullAtomInfo> 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()}}};

View File

@@ -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;

View File

@@ -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);
}

View File

@@ -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;
}

View File

@@ -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);
}

View File

@@ -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

View File

@@ -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;

View File

@@ -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;

View File

@@ -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};

View File

@@ -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<StatsLogEventWrapper> 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<StatsLogEventWrapper> 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<StatsLogEventWrapper> 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<StatsLogEventWrapper> 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<StatsLogEventWrapper> 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;