Update CpuInfoReader to compute normalized available CPU frequency.
- Guard against reading CpuInfos too frequently. - Implement dump logic in CpuInfoReader. - Guard against zero time value in the time_in_state file. Test: atest CpuInfoReaderTest Bug: 242722241 (cherry picked from https://googleplex-android-review.googlesource.com/q/commit:67bc88121775785907a3aebd87db7c4bdef5fff9) Merged-In: I9fc109c43fe0bd5f1d16135ad3167325ae502e15 Change-Id: I9fc109c43fe0bd5f1d16135ad3167325ae502e15
This commit is contained in:
committed by
Cherrypicker Worker
parent
f5549dfd72
commit
aabb81ecb5
@@ -21,8 +21,10 @@ import static com.android.server.cpu.CpuMonitorService.TAG;
|
||||
|
||||
import android.annotation.IntDef;
|
||||
import android.annotation.Nullable;
|
||||
import android.os.SystemClock;
|
||||
import android.system.Os;
|
||||
import android.system.OsConstants;
|
||||
import android.util.IndentingPrintWriter;
|
||||
import android.util.IntArray;
|
||||
import android.util.LongSparseLongArray;
|
||||
import android.util.SparseArray;
|
||||
@@ -50,6 +52,9 @@ public final class CpuInfoReader {
|
||||
private static final String POLICY_DIR_PREFIX = "policy";
|
||||
private static final String RELATED_CPUS_FILE = "related_cpus";
|
||||
private static final String AFFECTED_CPUS_FILE = "affected_cpus";
|
||||
// TODO(b/263154344): Avoid reading from cpuinfo_cur_freq because non-root users don't have
|
||||
// read permission for this file. The file permissions are set by the Kernel. Instead, read
|
||||
// the current frequency only from scaling_cur_freq.
|
||||
private static final String CUR_CPUFREQ_FILE = "cpuinfo_cur_freq";
|
||||
private static final String MAX_CPUFREQ_FILE = "cpuinfo_max_freq";
|
||||
private static final String CUR_SCALING_FREQ_FILE = "scaling_cur_freq";
|
||||
@@ -70,16 +75,18 @@ public final class CpuInfoReader {
|
||||
private static final Pattern TIME_IN_STATE_PATTERN =
|
||||
Pattern.compile("(?<freqKHz>[0-9]+)\\s(?<time>[0-9]+)");
|
||||
private static final long MILLIS_PER_CLOCK_TICK = 1000L / Os.sysconf(OsConstants._SC_CLK_TCK);
|
||||
private static final long MIN_READ_INTERVAL_MILLISECONDS = 500;
|
||||
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
@IntDef(prefix = {"FLAG_CPUSET_CATEGORY_"}, flag = true, value = {
|
||||
FLAG_CPUSET_CATEGORY_TOP_APP,
|
||||
FLAG_CPUSET_CATEGORY_BACKGROUND
|
||||
})
|
||||
private @interface CpusetCategory{}
|
||||
/** package **/ @interface CpusetCategory{}
|
||||
|
||||
// TODO(b/242722241): Protect updatable variables with a local lock.
|
||||
private final File mCpusetDir;
|
||||
private final long mMinReadIntervalMillis;
|
||||
private final SparseIntArray mCpusetCategoriesByCpus = new SparseIntArray();
|
||||
private final SparseArray<File> mCpuFreqPolicyDirsById = new SparseArray<>();
|
||||
private final SparseArray<StaticPolicyInfo> mStaticPolicyInfoById = new SparseArray<>();
|
||||
@@ -90,16 +97,20 @@ public final class CpuInfoReader {
|
||||
private SparseArray<CpuUsageStats> mCumulativeCpuUsageStats = new SparseArray<>();
|
||||
private boolean mIsEnabled;
|
||||
private boolean mHasTimeInStateFile;
|
||||
private long mLastReadUptimeMillis;
|
||||
private SparseArray<CpuInfo> mLastReadCpuInfos;
|
||||
|
||||
public CpuInfoReader() {
|
||||
this(new File(CPUSET_DIR_PATH), new File(CPUFREQ_DIR_PATH), new File(PROC_STAT_FILE_PATH));
|
||||
this(new File(CPUSET_DIR_PATH), new File(CPUFREQ_DIR_PATH), new File(PROC_STAT_FILE_PATH),
|
||||
MIN_READ_INTERVAL_MILLISECONDS);
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
CpuInfoReader(File cpusetDir, File cpuFreqDir, File procStatFile) {
|
||||
CpuInfoReader(File cpusetDir, File cpuFreqDir, File procStatFile, long minReadIntervalMillis) {
|
||||
mCpusetDir = cpusetDir;
|
||||
mCpuFreqDir = cpuFreqDir;
|
||||
mProcStatFile = procStatFile;
|
||||
mMinReadIntervalMillis = minReadIntervalMillis;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -167,6 +178,16 @@ public final class CpuInfoReader {
|
||||
if (!mIsEnabled) {
|
||||
return null;
|
||||
}
|
||||
long uptimeMillis = SystemClock.uptimeMillis();
|
||||
if (mLastReadUptimeMillis > 0
|
||||
&& uptimeMillis - mLastReadUptimeMillis < mMinReadIntervalMillis) {
|
||||
Slogf.w(TAG, "Skipping reading from device and returning the last read CpuInfos. "
|
||||
+ "Last read was %d ms ago, min read interval is %d ms",
|
||||
uptimeMillis - mLastReadUptimeMillis, mMinReadIntervalMillis);
|
||||
return mLastReadCpuInfos;
|
||||
}
|
||||
mLastReadUptimeMillis = uptimeMillis;
|
||||
mLastReadCpuInfos = null;
|
||||
SparseArray<CpuUsageStats> cpuUsageStatsByCpus = readLatestCpuUsageStats();
|
||||
if (cpuUsageStatsByCpus == null || cpuUsageStatsByCpus.size() == 0) {
|
||||
Slogf.e(TAG, "Failed to read latest CPU usage stats");
|
||||
@@ -202,6 +223,12 @@ public final class CpuInfoReader {
|
||||
+ " policy ID %d", policyId);
|
||||
continue;
|
||||
}
|
||||
if (curFreqKHz > maxFreqKHz) {
|
||||
Slogf.w(TAG, "Current CPU frequency (%d) is greater than maximum CPU frequency"
|
||||
+ " (%d) for policy ID (%d). Skipping CPU frequency policy", curFreqKHz,
|
||||
maxFreqKHz, policyId);
|
||||
continue;
|
||||
}
|
||||
for (int coreIdx = 0; coreIdx < staticPolicyInfo.relatedCpuCores.size(); coreIdx++) {
|
||||
int relatedCpuCore = staticPolicyInfo.relatedCpuCores.get(coreIdx);
|
||||
CpuInfo prevCpuInfo = cpuInfoByCpus.get(relatedCpuCore);
|
||||
@@ -241,9 +268,73 @@ public final class CpuInfoReader {
|
||||
}
|
||||
}
|
||||
}
|
||||
mLastReadCpuInfos = cpuInfoByCpus;
|
||||
return cpuInfoByCpus;
|
||||
}
|
||||
|
||||
/** Dumps the current state. */
|
||||
public void dump(IndentingPrintWriter writer) {
|
||||
writer.printf("*%s*\n", getClass().getSimpleName());
|
||||
writer.increaseIndent(); // Add intend for the outermost block.
|
||||
|
||||
writer.printf("mCpusetDir = %s\n", mCpusetDir.getAbsolutePath());
|
||||
writer.printf("mCpuFreqDir = %s\n", mCpuFreqDir.getAbsolutePath());
|
||||
writer.printf("mProcStatFile = %s\n", mProcStatFile.getAbsolutePath());
|
||||
writer.printf("mIsEnabled = %s\n", mIsEnabled);
|
||||
writer.printf("mHasTimeInStateFile = %s\n", mHasTimeInStateFile);
|
||||
writer.printf("mLastReadUptimeMillis = %d\n", mLastReadUptimeMillis);
|
||||
writer.printf("mMinReadIntervalMillis = %d\n", mMinReadIntervalMillis);
|
||||
|
||||
writer.printf("Cpuset categories by CPU core:\n");
|
||||
writer.increaseIndent();
|
||||
for (int i = 0; i < mCpusetCategoriesByCpus.size(); i++) {
|
||||
writer.printf("CPU core id = %d, %s\n", mCpusetCategoriesByCpus.keyAt(i),
|
||||
toCpusetCategoriesStr(mCpusetCategoriesByCpus.valueAt(i)));
|
||||
}
|
||||
writer.decreaseIndent();
|
||||
|
||||
writer.println("Cpu frequency policy directories by policy id:");
|
||||
writer.increaseIndent();
|
||||
for (int i = 0; i < mCpuFreqPolicyDirsById.size(); i++) {
|
||||
writer.printf("Policy id = %d, Dir = %s\n", mCpuFreqPolicyDirsById.keyAt(i),
|
||||
mCpuFreqPolicyDirsById.valueAt(i));
|
||||
}
|
||||
writer.decreaseIndent();
|
||||
|
||||
writer.println("Static cpu frequency policy infos by policy id:");
|
||||
writer.increaseIndent();
|
||||
for (int i = 0; i < mStaticPolicyInfoById.size(); i++) {
|
||||
writer.printf("Policy id = %d, %s\n", mStaticPolicyInfoById.keyAt(i),
|
||||
mStaticPolicyInfoById.valueAt(i));
|
||||
}
|
||||
writer.decreaseIndent();
|
||||
|
||||
writer.println("Cpu time in frequency state by policy id:");
|
||||
writer.increaseIndent();
|
||||
for (int i = 0; i < mTimeInStateByPolicyId.size(); i++) {
|
||||
writer.printf("Policy id = %d, Time(millis) in state by CPU frequency(KHz) = %s\n",
|
||||
mTimeInStateByPolicyId.keyAt(i), mTimeInStateByPolicyId.valueAt(i));
|
||||
}
|
||||
writer.decreaseIndent();
|
||||
|
||||
writer.println("Last read CPU infos:");
|
||||
writer.increaseIndent();
|
||||
for (int i = 0; i < mLastReadCpuInfos.size(); i++) {
|
||||
writer.printf("%s\n", mLastReadCpuInfos.valueAt(i));
|
||||
}
|
||||
writer.decreaseIndent();
|
||||
|
||||
writer.println("Latest cumulative CPU usage stats by CPU core:");
|
||||
writer.increaseIndent();
|
||||
for (int i = 0; i < mCumulativeCpuUsageStats.size(); i++) {
|
||||
writer.printf("CPU core id = %d, %s\n", mCumulativeCpuUsageStats.keyAt(i),
|
||||
mCumulativeCpuUsageStats.valueAt(i));
|
||||
}
|
||||
writer.decreaseIndent();
|
||||
|
||||
writer.decreaseIndent(); // Remove intend for the outermost block.
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the CPU frequency for testing.
|
||||
*
|
||||
@@ -496,6 +587,9 @@ public final class CpuInfoReader {
|
||||
for (int i = 0; i < timeInState.size(); i++) {
|
||||
totalTimeInState += timeInState.valueAt(i);
|
||||
}
|
||||
if (totalTimeInState == 0) {
|
||||
return CpuInfo.MISSING_FREQUENCY;
|
||||
}
|
||||
double avgFreqKHz = 0;
|
||||
for (int i = 0; i < timeInState.size(); i++) {
|
||||
avgFreqKHz += (timeInState.keyAt(i) * timeInState.valueAt(i)) / totalTimeInState;
|
||||
@@ -624,16 +718,29 @@ public final class CpuInfoReader {
|
||||
@CpusetCategory
|
||||
public final int cpusetCategories;
|
||||
public final boolean isOnline;
|
||||
public final long maxCpuFreqKHz;
|
||||
// Values in the below fields may be missing when a CPU core is offline.
|
||||
public final long curCpuFreqKHz;
|
||||
public final long maxCpuFreqKHz;
|
||||
public final long avgTimeInStateCpuFreqKHz;
|
||||
@Nullable
|
||||
public final CpuUsageStats latestCpuUsageStats;
|
||||
|
||||
private long mNormalizedAvailableCpuFreqKHz;
|
||||
|
||||
CpuInfo(int cpuCore, @CpusetCategory int cpusetCategories, boolean isOnline,
|
||||
long curCpuFreqKHz, long maxCpuFreqKHz, long avgTimeInStateCpuFreqKHz,
|
||||
CpuUsageStats latestCpuUsageStats) {
|
||||
this(cpuCore, cpusetCategories, isOnline, curCpuFreqKHz, maxCpuFreqKHz,
|
||||
avgTimeInStateCpuFreqKHz, /* normalizedAvailableCpuFreqKHz= */ 0,
|
||||
latestCpuUsageStats);
|
||||
this.mNormalizedAvailableCpuFreqKHz = computeNormalizedAvailableCpuFreqKHz();
|
||||
}
|
||||
|
||||
// Should be used only for testing.
|
||||
@VisibleForTesting
|
||||
CpuInfo(int cpuCore, @CpusetCategory int cpusetCategories, boolean isOnline,
|
||||
long curCpuFreqKHz, long maxCpuFreqKHz, long avgTimeInStateCpuFreqKHz,
|
||||
long normalizedAvailableCpuFreqKHz, CpuUsageStats latestCpuUsageStats) {
|
||||
this.cpuCore = cpuCore;
|
||||
this.cpusetCategories = cpusetCategories;
|
||||
this.isOnline = isOnline;
|
||||
@@ -641,6 +748,11 @@ public final class CpuInfoReader {
|
||||
this.maxCpuFreqKHz = maxCpuFreqKHz;
|
||||
this.avgTimeInStateCpuFreqKHz = avgTimeInStateCpuFreqKHz;
|
||||
this.latestCpuUsageStats = latestCpuUsageStats;
|
||||
this.mNormalizedAvailableCpuFreqKHz = normalizedAvailableCpuFreqKHz;
|
||||
}
|
||||
|
||||
public long getNormalizedAvailableCpuFreqKHz() {
|
||||
return mNormalizedAvailableCpuFreqKHz;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -657,6 +769,8 @@ public final class CpuInfoReader {
|
||||
.append(avgTimeInStateCpuFreqKHz == MISSING_FREQUENCY ? "missing"
|
||||
: avgTimeInStateCpuFreqKHz)
|
||||
.append(", latestCpuUsageStats = ").append(latestCpuUsageStats)
|
||||
.append(", mNormalizedAvailableCpuFreqKHz = ")
|
||||
.append(mNormalizedAvailableCpuFreqKHz)
|
||||
.append(" }").toString();
|
||||
}
|
||||
|
||||
@@ -673,13 +787,32 @@ public final class CpuInfoReader {
|
||||
&& isOnline == other.isOnline && curCpuFreqKHz == other.curCpuFreqKHz
|
||||
&& maxCpuFreqKHz == other.maxCpuFreqKHz
|
||||
&& avgTimeInStateCpuFreqKHz == other.avgTimeInStateCpuFreqKHz
|
||||
&& latestCpuUsageStats.equals(other.latestCpuUsageStats);
|
||||
&& latestCpuUsageStats.equals(other.latestCpuUsageStats)
|
||||
&& mNormalizedAvailableCpuFreqKHz == other.mNormalizedAvailableCpuFreqKHz;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(cpuCore, cpusetCategories, isOnline, curCpuFreqKHz, maxCpuFreqKHz,
|
||||
avgTimeInStateCpuFreqKHz, latestCpuUsageStats);
|
||||
avgTimeInStateCpuFreqKHz, latestCpuUsageStats, mNormalizedAvailableCpuFreqKHz);
|
||||
}
|
||||
|
||||
private long computeNormalizedAvailableCpuFreqKHz() {
|
||||
if (!isOnline) {
|
||||
return MISSING_FREQUENCY;
|
||||
}
|
||||
long totalTimeMillis = latestCpuUsageStats.getTotalTimeMillis();
|
||||
if (totalTimeMillis == 0) {
|
||||
Slogf.wtf(TAG, "Total CPU time millis is 0. This shouldn't happen unless stats are"
|
||||
+ " polled too frequently");
|
||||
return MISSING_FREQUENCY;
|
||||
}
|
||||
double nonIdlePercent = 100.0 * (totalTimeMillis
|
||||
- (double) latestCpuUsageStats.idleTimeMillis) / totalTimeMillis;
|
||||
long curFreqKHz = avgTimeInStateCpuFreqKHz == MISSING_FREQUENCY
|
||||
? curCpuFreqKHz : avgTimeInStateCpuFreqKHz;
|
||||
double availablePercent = 100.0 - (nonIdlePercent * curFreqKHz / maxCpuFreqKHz);
|
||||
return (long) ((availablePercent * maxCpuFreqKHz) / 100.0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -712,7 +845,7 @@ public final class CpuInfoReader {
|
||||
this.guestNiceTimeMillis = guestNiceTimeMillis;
|
||||
}
|
||||
|
||||
public long getTotalTime() {
|
||||
public long getTotalTimeMillis() {
|
||||
return userTimeMillis + niceTimeMillis + systemTimeMillis + idleTimeMillis
|
||||
+ iowaitTimeMillis + irqTimeMillis + softirqTimeMillis + stealTimeMillis
|
||||
+ guestTimeMillis + guestNiceTimeMillis;
|
||||
@@ -796,8 +929,8 @@ public final class CpuInfoReader {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "FrequencyPair{cpuFreqKHz=" + cpuFreqKHz + ", scalingFreqKHz=" + scalingFreqKHz
|
||||
+ '}';
|
||||
return "FrequencyPair{cpuFreqKHz = " + cpuFreqKHz + ", scalingFreqKHz = "
|
||||
+ scalingFreqKHz + '}';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -812,7 +945,7 @@ public final class CpuInfoReader {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "StaticPolicyInfo{maxCpuFreqPair=" + maxCpuFreqPair + ", relatedCpuCores="
|
||||
return "StaticPolicyInfo{maxCpuFreqPair = " + maxCpuFreqPair + ", relatedCpuCores = "
|
||||
+ relatedCpuCores + '}';
|
||||
}
|
||||
}
|
||||
@@ -831,9 +964,9 @@ public final class CpuInfoReader {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "DynamicPolicyInfo{curCpuFreqPair=" + curCpuFreqPair
|
||||
+ ", avgTimeInStateCpuFreqKHz=" + avgTimeInStateCpuFreqKHz
|
||||
+ ", affectedCpuCores=" + affectedCpuCores + '}';
|
||||
return "DynamicPolicyInfo{curCpuFreqPair = " + curCpuFreqPair
|
||||
+ ", avgTimeInStateCpuFreqKHz = " + avgTimeInStateCpuFreqKHz
|
||||
+ ", affectedCpuCores = " + affectedCpuCores + '}';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -92,6 +92,7 @@ public final class CpuInfoReaderTest extends ExpectableTestCase {
|
||||
expectedCpuInfos.append(0, new CpuInfoReader.CpuInfo(/* cpuCore= */ 0,
|
||||
FLAG_CPUSET_CATEGORY_TOP_APP, /* isOnline= */ true, /* curCpuFreqKHz= */ 1_230_000,
|
||||
/* maxCpuFreqKHz= */ 2_500_000, /* avgTimeInStateCpuFreqKHz= */ 488_095,
|
||||
/* normalizedAvailableCpuFreqKHz= */ 2_402_267,
|
||||
new CpuInfoReader.CpuUsageStats(/* userTimeMillis= */ 32_249_610,
|
||||
/* niceTimeMillis= */ 7_950_930, /* systemTimeMillis= */ 52_227_050,
|
||||
/* idleTimeMillis= */ 409_036_950, /* iowaitTimeMillis= */ 1_322_810,
|
||||
@@ -101,6 +102,7 @@ public final class CpuInfoReaderTest extends ExpectableTestCase {
|
||||
expectedCpuInfos.append(1, new CpuInfoReader.CpuInfo(/* cpuCore= */ 1,
|
||||
FLAG_CPUSET_CATEGORY_TOP_APP, /* isOnline= */ true, /* curCpuFreqKHz= */ 1_450_000,
|
||||
/* maxCpuFreqKHz= */ 2_800_000, /* avgTimeInStateCpuFreqKHz= */ 502_380,
|
||||
/* normalizedAvailableCpuFreqKHz= */ 2_693_525,
|
||||
new CpuInfoReader.CpuUsageStats(/* userTimeMillis= */ 28_949_280,
|
||||
/* niceTimeMillis= */ 7_799_450, /* systemTimeMillis= */ 54_004_020,
|
||||
/* idleTimeMillis= */ 402_707_120, /* iowaitTimeMillis= */ 1_186_960,
|
||||
@@ -111,6 +113,7 @@ public final class CpuInfoReaderTest extends ExpectableTestCase {
|
||||
FLAG_CPUSET_CATEGORY_TOP_APP | FLAG_CPUSET_CATEGORY_BACKGROUND,
|
||||
/* isOnline= */ true, /* curCpuFreqKHz= */ 1_000_000,
|
||||
/* maxCpuFreqKHz= */ 2_000_000, /* avgTimeInStateCpuFreqKHz= */ 464_285,
|
||||
/* normalizedAvailableCpuFreqKHz= */ 1_901_608,
|
||||
new CpuInfoReader.CpuUsageStats(/* userTimeMillis= */ 28_959_280,
|
||||
/* niceTimeMillis= */ 7_789_450, /* systemTimeMillis= */ 54_014_020,
|
||||
/* idleTimeMillis= */ 402_717_120, /* iowaitTimeMillis= */ 1_166_960,
|
||||
@@ -121,6 +124,7 @@ public final class CpuInfoReaderTest extends ExpectableTestCase {
|
||||
FLAG_CPUSET_CATEGORY_TOP_APP | FLAG_CPUSET_CATEGORY_BACKGROUND,
|
||||
/* isOnline= */ true, /* curCpuFreqKHz= */ 1_000_000,
|
||||
/* maxCpuFreqKHz= */ 2_000_000, /* avgTimeInStateCpuFreqKHz= */ 464_285,
|
||||
/* normalizedAvailableCpuFreqKHz= */ 1_907_125,
|
||||
new CpuInfoReader.CpuUsageStats(/* userTimeMillis= */ 32_349_610,
|
||||
/* niceTimeMillis= */ 7_850_930, /* systemTimeMillis= */ 52_127_050,
|
||||
/* idleTimeMillis= */ 409_136_950, /* iowaitTimeMillis= */ 1_332_810,
|
||||
@@ -139,6 +143,7 @@ public final class CpuInfoReaderTest extends ExpectableTestCase {
|
||||
expectedCpuInfos.append(0, new CpuInfoReader.CpuInfo(/* cpuCore= */ 0,
|
||||
FLAG_CPUSET_CATEGORY_TOP_APP, /* isOnline= */ true, /* curCpuFreqKHz= */ 1_000_000,
|
||||
/* maxCpuFreqKHz= */ 2_500_000, /* avgTimeInStateCpuFreqKHz= */ 419_354,
|
||||
/* normalizedAvailableCpuFreqKHz= */ 2_425_919,
|
||||
new CpuInfoReader.CpuUsageStats(/* userTimeMillis= */ 10_000_000,
|
||||
/* niceTimeMillis= */ 1_000_000, /* systemTimeMillis= */ 10_000_000,
|
||||
/* idleTimeMillis= */ 110_000_000, /* iowaitTimeMillis= */ 1_100_000,
|
||||
@@ -148,6 +153,7 @@ public final class CpuInfoReaderTest extends ExpectableTestCase {
|
||||
expectedCpuInfos.append(1, new CpuInfoReader.CpuInfo(/* cpuCore= */ 1,
|
||||
FLAG_CPUSET_CATEGORY_TOP_APP, /* isOnline= */ true, /* curCpuFreqKHz= */ 2_800_000,
|
||||
/* maxCpuFreqKHz= */ 2_800_000, /* avgTimeInStateCpuFreqKHz= */ 429_032,
|
||||
/* normalizedAvailableCpuFreqKHz= */ 2_403_009,
|
||||
new CpuInfoReader.CpuUsageStats(/* userTimeMillis= */ 900_000,
|
||||
/* niceTimeMillis= */ 1_000_000, /* systemTimeMillis= */ 10_000_000,
|
||||
/* idleTimeMillis= */ 1_000_000, /* iowaitTimeMillis= */ 90_000,
|
||||
@@ -158,6 +164,7 @@ public final class CpuInfoReaderTest extends ExpectableTestCase {
|
||||
FLAG_CPUSET_CATEGORY_TOP_APP | FLAG_CPUSET_CATEGORY_BACKGROUND,
|
||||
/* isOnline= */ true, /* curCpuFreqKHz= */ 2_000_000,
|
||||
/* maxCpuFreqKHz= */ 2_000_000, /* avgTimeInStateCpuFreqKHz= */ 403_225,
|
||||
/* normalizedAvailableCpuFreqKHz= */ 1_688_209,
|
||||
new CpuInfoReader.CpuUsageStats(/* userTimeMillis= */ 10_000_000,
|
||||
/* niceTimeMillis= */ 2_000_000, /* systemTimeMillis= */ 0,
|
||||
/* idleTimeMillis= */ 10_000_000, /* iowaitTimeMillis= */ 1_000_000,
|
||||
@@ -168,6 +175,7 @@ public final class CpuInfoReaderTest extends ExpectableTestCase {
|
||||
FLAG_CPUSET_CATEGORY_TOP_APP | FLAG_CPUSET_CATEGORY_BACKGROUND,
|
||||
/* isOnline= */ false, /* curCpuFreqKHz= */ MISSING_FREQUENCY,
|
||||
/* maxCpuFreqKHz= */ 2_000_000, /* avgTimeInStateCpuFreqKHz= */ MISSING_FREQUENCY,
|
||||
/* normalizedAvailableCpuFreqKHz= */ MISSING_FREQUENCY,
|
||||
new CpuInfoReader.CpuUsageStats(/* userTimeMillis= */ 2_000_000,
|
||||
/* niceTimeMillis= */ 1_000_000, /* systemTimeMillis= */ 1_000_000,
|
||||
/* idleTimeMillis= */ 100_000, /* iowaitTimeMillis= */ 100_000,
|
||||
@@ -189,6 +197,7 @@ public final class CpuInfoReaderTest extends ExpectableTestCase {
|
||||
expectedCpuInfos.append(0, new CpuInfoReader.CpuInfo(/* cpuCore= */ 0,
|
||||
FLAG_CPUSET_CATEGORY_TOP_APP, /* isOnline= */ true, /* curCpuFreqKHz= */ 1_230_000,
|
||||
/* maxCpuFreqKHz= */ 2_500_000, /* avgTimeInStateCpuFreqKHz= */ MISSING_FREQUENCY,
|
||||
/* normalizedAvailableCpuFreqKHz= */ 2_253_713,
|
||||
new CpuInfoReader.CpuUsageStats(/* userTimeMillis= */ 32_249_610,
|
||||
/* niceTimeMillis= */ 7_950_930, /* systemTimeMillis= */ 52_227_050,
|
||||
/* idleTimeMillis= */ 409_036_950, /* iowaitTimeMillis= */ 1_322_810,
|
||||
@@ -198,6 +207,7 @@ public final class CpuInfoReaderTest extends ExpectableTestCase {
|
||||
expectedCpuInfos.append(1, new CpuInfoReader.CpuInfo(/* cpuCore= */ 1,
|
||||
FLAG_CPUSET_CATEGORY_TOP_APP, /* isOnline= */ true, /* curCpuFreqKHz= */ 1_450_000,
|
||||
/* maxCpuFreqKHz= */ 2_800_000, /* avgTimeInStateCpuFreqKHz= */ MISSING_FREQUENCY,
|
||||
/* normalizedAvailableCpuFreqKHz= */ 2_492_687,
|
||||
new CpuInfoReader.CpuUsageStats(/* userTimeMillis= */ 28_949_280,
|
||||
/* niceTimeMillis= */ 7_799_450, /* systemTimeMillis= */ 54_004_020,
|
||||
/* idleTimeMillis= */ 402_707_120, /* iowaitTimeMillis= */ 1_186_960,
|
||||
@@ -208,6 +218,7 @@ public final class CpuInfoReaderTest extends ExpectableTestCase {
|
||||
FLAG_CPUSET_CATEGORY_TOP_APP | FLAG_CPUSET_CATEGORY_BACKGROUND,
|
||||
/* isOnline= */ true, /* curCpuFreqKHz= */ 1_000_000,
|
||||
/* maxCpuFreqKHz= */ 2_000_000, /* avgTimeInStateCpuFreqKHz= */ MISSING_FREQUENCY,
|
||||
/* normalizedAvailableCpuFreqKHz= */ 1_788_079,
|
||||
new CpuInfoReader.CpuUsageStats(/* userTimeMillis= */ 28_959_280,
|
||||
/* niceTimeMillis= */ 7_789_450, /* systemTimeMillis= */ 54_014_020,
|
||||
/* idleTimeMillis= */ 402_717_120, /* iowaitTimeMillis= */ 1_166_960,
|
||||
@@ -218,6 +229,7 @@ public final class CpuInfoReaderTest extends ExpectableTestCase {
|
||||
FLAG_CPUSET_CATEGORY_TOP_APP | FLAG_CPUSET_CATEGORY_BACKGROUND,
|
||||
/* isOnline= */ true, /* curCpuFreqKHz= */ 1_000_000,
|
||||
/* maxCpuFreqKHz= */ 2_000_000, /* avgTimeInStateCpuFreqKHz= */ MISSING_FREQUENCY,
|
||||
/* normalizedAvailableCpuFreqKHz= */ 1_799_962,
|
||||
new CpuInfoReader.CpuUsageStats(/* userTimeMillis= */ 32_349_610,
|
||||
/* niceTimeMillis= */ 7_850_930, /* systemTimeMillis= */ 52_127_050,
|
||||
/* idleTimeMillis= */ 409_136_950, /* iowaitTimeMillis= */ 1_332_810,
|
||||
@@ -237,6 +249,7 @@ public final class CpuInfoReaderTest extends ExpectableTestCase {
|
||||
expectedCpuInfos.append(0, new CpuInfoReader.CpuInfo(/* cpuCore= */ 0,
|
||||
FLAG_CPUSET_CATEGORY_TOP_APP, /* isOnline= */ true, /* curCpuFreqKHz= */ 1_000_000,
|
||||
/* maxCpuFreqKHz= */ 2_500_000, /* avgTimeInStateCpuFreqKHz= */ MISSING_FREQUENCY,
|
||||
/* normalizedAvailableCpuFreqKHz= */ 2323347,
|
||||
new CpuInfoReader.CpuUsageStats(/* userTimeMillis= */ 10_000_000,
|
||||
/* niceTimeMillis= */ 1_000_000, /* systemTimeMillis= */ 10_000_000,
|
||||
/* idleTimeMillis= */ 110_000_000, /* iowaitTimeMillis= */ 1_100_000,
|
||||
@@ -246,6 +259,7 @@ public final class CpuInfoReaderTest extends ExpectableTestCase {
|
||||
expectedCpuInfos.append(1, new CpuInfoReader.CpuInfo(/* cpuCore= */ 1,
|
||||
FLAG_CPUSET_CATEGORY_TOP_APP, /* isOnline= */ true, /* curCpuFreqKHz= */ 2_800_000,
|
||||
/* maxCpuFreqKHz= */ 2_800_000, /* avgTimeInStateCpuFreqKHz= */ MISSING_FREQUENCY,
|
||||
/* normalizedAvailableCpuFreqKHz= */ 209111,
|
||||
new CpuInfoReader.CpuUsageStats(/* userTimeMillis= */ 900_000,
|
||||
/* niceTimeMillis= */ 1_000_000, /* systemTimeMillis= */ 10_000_000,
|
||||
/* idleTimeMillis= */ 1_000_000, /* iowaitTimeMillis= */ 90_000,
|
||||
@@ -256,6 +270,7 @@ public final class CpuInfoReaderTest extends ExpectableTestCase {
|
||||
FLAG_CPUSET_CATEGORY_TOP_APP | FLAG_CPUSET_CATEGORY_BACKGROUND,
|
||||
/* isOnline= */ true, /* curCpuFreqKHz= */ 2_000_000,
|
||||
/* maxCpuFreqKHz= */ 2_000_000, /* avgTimeInStateCpuFreqKHz= */ MISSING_FREQUENCY,
|
||||
/* normalizedAvailableCpuFreqKHz= */ 453514,
|
||||
new CpuInfoReader.CpuUsageStats(/* userTimeMillis= */ 10_000_000,
|
||||
/* niceTimeMillis= */ 2_000_000, /* systemTimeMillis= */ 0,
|
||||
/* idleTimeMillis= */ 10_000_000, /* iowaitTimeMillis= */ 1_000_000,
|
||||
@@ -266,6 +281,7 @@ public final class CpuInfoReaderTest extends ExpectableTestCase {
|
||||
FLAG_CPUSET_CATEGORY_TOP_APP | FLAG_CPUSET_CATEGORY_BACKGROUND,
|
||||
/* isOnline= */ true, /* curCpuFreqKHz= */ 2_000_000,
|
||||
/* maxCpuFreqKHz= */ 2_000_000, /* avgTimeInStateCpuFreqKHz= */ MISSING_FREQUENCY,
|
||||
/* normalizedAvailableCpuFreqKHz= */ 37728,
|
||||
new CpuInfoReader.CpuUsageStats(/* userTimeMillis= */ 2_000_000,
|
||||
/* niceTimeMillis= */ 1_000_000, /* systemTimeMillis= */ 1_000_000,
|
||||
/* idleTimeMillis= */ 100_000, /* iowaitTimeMillis= */ 100_000,
|
||||
@@ -323,38 +339,8 @@ public final class CpuInfoReaderTest extends ExpectableTestCase {
|
||||
|
||||
SparseArray<CpuInfoReader.CpuInfo> actualCpuInfos = cpuInfoReader.readCpuInfos();
|
||||
SparseArray<CpuInfoReader.CpuInfo> expectedCpuInfos = new SparseArray<>();
|
||||
expectedCpuInfos.append(1, new CpuInfoReader.CpuInfo(/* cpuCore= */ 1,
|
||||
FLAG_CPUSET_CATEGORY_TOP_APP, /* isOnline= */ true, /* curCpuFreqKHz= */ 3_000_000,
|
||||
/* maxCpuFreqKHz= */ 1_000_000, /* avgTimeInStateCpuFreqKHz= */ MISSING_FREQUENCY,
|
||||
new CpuInfoReader.CpuUsageStats(/* userTimeMillis= */ 28_949_280,
|
||||
/* niceTimeMillis= */ 7_799_450, /* systemTimeMillis= */ 54_004_020,
|
||||
/* idleTimeMillis= */ 402_707_120, /* iowaitTimeMillis= */ 1_186_960,
|
||||
/* irqTimeMillis= */ 14_786_940, /* softirqTimeMillis= */ 1_498_130,
|
||||
/* stealTimeMillis= */ 78_780, /* guestTimeMillis= */ 0,
|
||||
/* guestNiceTimeMillis= */ 0)));
|
||||
expectedCpuInfos.append(2, new CpuInfoReader.CpuInfo(/* cpuCore= */ 2,
|
||||
FLAG_CPUSET_CATEGORY_TOP_APP | FLAG_CPUSET_CATEGORY_BACKGROUND,
|
||||
/* isOnline= */ true, /* curCpuFreqKHz= */ 9, /* maxCpuFreqKHz= */ 2,
|
||||
/* avgTimeInStateCpuFreqKHz= */ MISSING_FREQUENCY,
|
||||
new CpuInfoReader.CpuUsageStats(/* userTimeMillis= */ 28_959_280,
|
||||
/* niceTimeMillis= */ 7_789_450, /* systemTimeMillis= */ 54_014_020,
|
||||
/* idleTimeMillis= */ 402_717_120, /* iowaitTimeMillis= */ 1_166_960,
|
||||
/* irqTimeMillis= */ 14_796_940, /* softirqTimeMillis= */ 1_478_130,
|
||||
/* stealTimeMillis= */ 88_780, /* guestTimeMillis= */ 0,
|
||||
/* guestNiceTimeMillis= */ 0)));
|
||||
expectedCpuInfos.append(3, new CpuInfoReader.CpuInfo(/* cpuCore= */ 3,
|
||||
FLAG_CPUSET_CATEGORY_TOP_APP | FLAG_CPUSET_CATEGORY_BACKGROUND,
|
||||
/* isOnline= */ true, /* curCpuFreqKHz= */ 9, /* maxCpuFreqKHz= */ 2,
|
||||
/* avgTimeInStateCpuFreqKHz= */ MISSING_FREQUENCY,
|
||||
new CpuInfoReader.CpuUsageStats(/* userTimeMillis= */ 32_349_610,
|
||||
/* niceTimeMillis= */ 7_850_930, /* systemTimeMillis= */ 52_127_050,
|
||||
/* idleTimeMillis= */ 409_136_950, /* iowaitTimeMillis= */ 1_332_810,
|
||||
/* irqTimeMillis= */ 8_136_740, /* softirqTimeMillis= */ 438_970,
|
||||
/* stealTimeMillis= */ 71_950, /* guestTimeMillis= */ 0,
|
||||
/* guestNiceTimeMillis= */ 0)));
|
||||
|
||||
compareCpuInfos("CPU infos with corrupted CPU frequency", expectedCpuInfos,
|
||||
actualCpuInfos);
|
||||
compareCpuInfos("CPU infos with corrupted CPU frequency", expectedCpuInfos, actualCpuInfos);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -368,6 +354,7 @@ public final class CpuInfoReaderTest extends ExpectableTestCase {
|
||||
expectedCpuInfos.append(0, new CpuInfoReader.CpuInfo(/* cpuCore= */ 0,
|
||||
FLAG_CPUSET_CATEGORY_TOP_APP, /* isOnline= */ true, /* curCpuFreqKHz= */ 1_230_000,
|
||||
/* maxCpuFreqKHz= */ 2_500_000, /* avgTimeInStateCpuFreqKHz= */ 488_095,
|
||||
/* normalizedAvailableCpuFreqKHz= */ 2_402_267,
|
||||
new CpuInfoReader.CpuUsageStats(/* userTimeMillis= */ 32_249_610,
|
||||
/* niceTimeMillis= */ 7_950_930, /* systemTimeMillis= */ 52_227_050,
|
||||
/* idleTimeMillis= */ 409_036_950, /* iowaitTimeMillis= */ 1_322_810,
|
||||
@@ -377,6 +364,7 @@ public final class CpuInfoReaderTest extends ExpectableTestCase {
|
||||
expectedCpuInfos.append(1, new CpuInfoReader.CpuInfo(/* cpuCore= */ 1,
|
||||
FLAG_CPUSET_CATEGORY_TOP_APP, /* isOnline= */ true, /* curCpuFreqKHz= */ 1_450_000,
|
||||
/* maxCpuFreqKHz= */ 2_800_000, /* avgTimeInStateCpuFreqKHz= */ 502_380,
|
||||
/* normalizedAvailableCpuFreqKHz= */ 2_693_525,
|
||||
new CpuInfoReader.CpuUsageStats(/* userTimeMillis= */ 28_949_280,
|
||||
/* niceTimeMillis= */ 7_799_450, /* systemTimeMillis= */ 54_004_020,
|
||||
/* idleTimeMillis= */ 402_707_120, /* iowaitTimeMillis= */ 1_186_960,
|
||||
@@ -393,7 +381,7 @@ public final class CpuInfoReaderTest extends ExpectableTestCase {
|
||||
assertWithMessage("Make empty dir %s", emptyDir).that(emptyDir.mkdir()).isTrue();
|
||||
CpuInfoReader cpuInfoReader = new CpuInfoReader(emptyDir, getCacheFile(
|
||||
VALID_CPUFREQ_WITH_TIME_IN_STATE_DIR),
|
||||
getCacheFile(VALID_PROC_STAT));
|
||||
getCacheFile(VALID_PROC_STAT), /* minReadIntervalMillis= */0);
|
||||
|
||||
assertWithMessage("Init CPU reader info").that(cpuInfoReader.init()).isFalse();
|
||||
|
||||
@@ -406,7 +394,7 @@ public final class CpuInfoReaderTest extends ExpectableTestCase {
|
||||
File emptyDir = getCacheFile(EMPTY_DIR);
|
||||
assertWithMessage("Make empty dir %s", emptyDir).that(emptyDir.mkdir()).isTrue();
|
||||
CpuInfoReader cpuInfoReader = new CpuInfoReader(getCacheFile(VALID_CPUSET_DIR), emptyDir,
|
||||
getCacheFile(VALID_PROC_STAT));
|
||||
getCacheFile(VALID_PROC_STAT), /* minReadIntervalMillis= */0);
|
||||
|
||||
assertWithMessage("Init CPU reader info").that(cpuInfoReader.init()).isFalse();
|
||||
|
||||
@@ -420,12 +408,32 @@ public final class CpuInfoReaderTest extends ExpectableTestCase {
|
||||
assertWithMessage("Create empty file %s", emptyFile).that(emptyFile.createNewFile())
|
||||
.isTrue();
|
||||
CpuInfoReader cpuInfoReader = new CpuInfoReader(getCacheFile(VALID_CPUSET_DIR),
|
||||
getCacheFile(VALID_CPUFREQ_WITH_TIME_IN_STATE_DIR), getCacheFile(EMPTY_FILE));
|
||||
getCacheFile(VALID_CPUFREQ_WITH_TIME_IN_STATE_DIR), getCacheFile(EMPTY_FILE),
|
||||
/* minReadIntervalMillis= */0);
|
||||
|
||||
assertWithMessage("Cpu infos with empty proc stat").that(cpuInfoReader.readCpuInfos())
|
||||
.isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReadingTooFrequentlyReturnsLastReadCpuInfos() throws Exception {
|
||||
CpuInfoReader cpuInfoReader = new CpuInfoReader(getCacheFile(VALID_CPUSET_DIR),
|
||||
getCacheFile(VALID_CPUFREQ_WITH_TIME_IN_STATE_DIR), getCacheFile(VALID_PROC_STAT),
|
||||
/* minReadIntervalMillis= */ 60_000);
|
||||
assertWithMessage("Initialize CPU info reader").that(cpuInfoReader.init()).isTrue();
|
||||
|
||||
SparseArray<CpuInfoReader.CpuInfo> firstCpuInfos = cpuInfoReader.readCpuInfos();
|
||||
assertWithMessage("CPU infos first snapshot").that(firstCpuInfos).isNotNull();
|
||||
assertWithMessage("CPU infos first snapshot size").that(firstCpuInfos.size())
|
||||
.isGreaterThan(0);
|
||||
|
||||
SparseArray<CpuInfoReader.CpuInfo> secondCpuInfos = cpuInfoReader.readCpuInfos();
|
||||
compareCpuInfos("CPU infos second snapshot", firstCpuInfos, secondCpuInfos);
|
||||
|
||||
SparseArray<CpuInfoReader.CpuInfo> thirdCpuInfos = cpuInfoReader.readCpuInfos();
|
||||
compareCpuInfos("CPU infos third snapshot", firstCpuInfos, thirdCpuInfos);
|
||||
}
|
||||
|
||||
private void compareCpuInfos(String message,
|
||||
SparseArray<CpuInfoReader.CpuInfo> expected,
|
||||
SparseArray<CpuInfoReader.CpuInfo> actual) {
|
||||
@@ -462,7 +470,8 @@ public final class CpuInfoReaderTest extends ExpectableTestCase {
|
||||
|
||||
private static CpuInfoReader newCpuInfoReader(File cpusetDir, File cpuFreqDir,
|
||||
File procStatFile) {
|
||||
CpuInfoReader cpuInfoReader = new CpuInfoReader(cpusetDir, cpuFreqDir, procStatFile);
|
||||
CpuInfoReader cpuInfoReader = new CpuInfoReader(cpusetDir, cpuFreqDir, procStatFile,
|
||||
/* minReadIntervalMillis= */ 0);
|
||||
assertWithMessage("Initialize CPU info reader").that(cpuInfoReader.init()).isTrue();
|
||||
return cpuInfoReader;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user