Loading services/core/java/com/android/server/cpu/CpuInfoReader.java +146 −13 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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"; Loading @@ -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<>(); Loading @@ -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; } /** Loading Loading @@ -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"); Loading Loading @@ -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); Loading Loading @@ -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. * Loading Loading @@ -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; Loading Loading @@ -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; Loading @@ -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 Loading @@ -657,6 +769,8 @@ public final class CpuInfoReader { .append(avgTimeInStateCpuFreqKHz == MISSING_FREQUENCY ? "missing" : avgTimeInStateCpuFreqKHz) .append(", latestCpuUsageStats = ").append(latestCpuUsageStats) .append(", mNormalizedAvailableCpuFreqKHz = ") .append(mNormalizedAvailableCpuFreqKHz) .append(" }").toString(); } Loading @@ -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); } } Loading Loading @@ -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; Loading Loading @@ -796,8 +929,8 @@ public final class CpuInfoReader { @Override public String toString() { return "FrequencyPair{cpuFreqKHz=" + cpuFreqKHz + ", scalingFreqKHz=" + scalingFreqKHz + '}'; return "FrequencyPair{cpuFreqKHz = " + cpuFreqKHz + ", scalingFreqKHz = " + scalingFreqKHz + '}'; } } Loading services/tests/mockingservicestests/src/com/android/server/cpu/CpuInfoReaderTest.java +44 −35 File changed.Preview size limit exceeded, changes collapsed. Show changes Loading
services/core/java/com/android/server/cpu/CpuInfoReader.java +146 −13 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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"; Loading @@ -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<>(); Loading @@ -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; } /** Loading Loading @@ -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"); Loading Loading @@ -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); Loading Loading @@ -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. * Loading Loading @@ -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; Loading Loading @@ -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; Loading @@ -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 Loading @@ -657,6 +769,8 @@ public final class CpuInfoReader { .append(avgTimeInStateCpuFreqKHz == MISSING_FREQUENCY ? "missing" : avgTimeInStateCpuFreqKHz) .append(", latestCpuUsageStats = ").append(latestCpuUsageStats) .append(", mNormalizedAvailableCpuFreqKHz = ") .append(mNormalizedAvailableCpuFreqKHz) .append(" }").toString(); } Loading @@ -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); } } Loading Loading @@ -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; Loading Loading @@ -796,8 +929,8 @@ public final class CpuInfoReader { @Override public String toString() { return "FrequencyPair{cpuFreqKHz=" + cpuFreqKHz + ", scalingFreqKHz=" + scalingFreqKHz + '}'; return "FrequencyPair{cpuFreqKHz = " + cpuFreqKHz + ", scalingFreqKHz = " + scalingFreqKHz + '}'; } } Loading
services/tests/mockingservicestests/src/com/android/server/cpu/CpuInfoReaderTest.java +44 −35 File changed.Preview size limit exceeded, changes collapsed. Show changes