Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ec67661b authored by Chenjie Yu's avatar Chenjie Yu
Browse files

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
parent 8c76ca03
Loading
Loading
Loading
Loading
+0 −4
Original line number Original line Diff line number Diff line
@@ -40,10 +40,6 @@ statsd_common_src := \
    src/external/SubsystemSleepStatePuller.cpp \
    src/external/SubsystemSleepStatePuller.cpp \
    src/external/ResourceHealthManagerPuller.cpp \
    src/external/ResourceHealthManagerPuller.cpp \
    src/external/ResourceThermalManagerPuller.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/StatsPullerManagerImpl.cpp \
    src/external/puller_util.cpp \
    src/external/puller_util.cpp \
    src/logd/LogEvent.cpp \
    src/logd/LogEvent.cpp \
+7 −9
Original line number Original line Diff line number Diff line
@@ -1489,7 +1489,7 @@ message CpuTimePerFreq {
 * Note that isolated process uid time should be attributed to host uids.
 * Note that isolated process uid time should be attributed to host uids.
 */
 */
message CpuTimePerUid {
message CpuTimePerUid {
    optional uint64 uid = 1;
    optional int32 uid = 1;
    optional uint64 user_time_millis = 2;
    optional uint64 user_time_millis = 2;
    optional uint64 sys_time_millis = 3;
    optional uint64 sys_time_millis = 3;
}
}
@@ -1500,8 +1500,8 @@ message CpuTimePerUid {
 * For each uid, we order the time by descending frequencies.
 * For each uid, we order the time by descending frequencies.
 */
 */
message CpuTimePerUidFreq {
message CpuTimePerUidFreq {
    optional uint64 uid = 1;
    optional int32 uid = 1;
    optional uint64 freq_idx = 2;
    optional uint32 freq_index = 2;
    optional uint64 time_millis = 3;
    optional uint64 time_millis = 3;
}
}


@@ -1634,10 +1634,8 @@ message SystemUptime {
 * The file contains a monotonically increasing count of time for a single boot.
 * The file contains a monotonically increasing count of time for a single boot.
 */
 */
message CpuActiveTime {
message CpuActiveTime {
    optional uint64 uid = 1;
    optional int32 uid = 1;
    optional uint32 cluster_number = 2;
    optional uint64 time_millis = 2;
    optional uint64 idx = 3;
    optional uint64 time_millis = 4;
}
}


/**
/**
@@ -1650,8 +1648,8 @@ message CpuActiveTime {
 * The file contains a monotonically increasing count of time for a single boot.
 * The file contains a monotonically increasing count of time for a single boot.
 */
 */
message CpuClusterTime {
message CpuClusterTime {
    optional uint64 uid = 1;
    optional int32 uid = 1;
    optional uint64 idx = 2;
    optional int32 cluster_index = 2;
    optional uint64 time_millis = 3;
    optional uint64 time_millis = 3;
}
}


+0 −100
Original line number Original line Diff line number Diff line
/*
 * 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
+0 −42
Original line number Original line Diff line number Diff line
/*
 * 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
+0 −90
Original line number Original line Diff line number Diff line
/*
 * 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
Loading