I'm very specific on this one. I need to know if the device has a CPU which has heterogeneous cores like ARM's big.LITTLE technology, for instance, a set of 4 ARM Cortex-A53 + another set of 4 more powerfull ARM Cortex-A72, totaling 8 cores, basically 2 processors in the same chip. The processors model does not really matter.
What I'm considering is to read scaling_max_freq
of all cores and group those with different max frequencies (and then compare them) but I noticed that in some devices, the path to any core that's not cpu0 is actually a symlink to /sys/devices/system/cpu/cpu0/cpufreq/scaling_max_freq
That is, if I try to read cpu3's scaling_max_freq it will be a link to cpu0's scaling_max_freq. I wonder if in this case I can consider we're not running in a heterogeneous.
CPU class
public final class CPU {
// To be formatted with specific core number
private static final String CPU_DIR = "/sys/devices/system/cpu/cpu%d";
private static final String CPUFREQ_DIR = CPU_DIR + "/cpufreq";
public static final String SCALING_MAX_FREQ = CPUFREQ_DIR + "/scaling_max_freq";
private static final String DEFAULT_FREQS = "200000 400000 800000 1200000";
private CPU() {
}
// Here I'd replace 0 with (other) core number
@NonNull
public static synchronized String[] getAvailFreqs() {
String[] split;
String freqs = FileUtils.readFile(format(SCALING_AVAIL_FREQS, 0), DEFAULT_FREQS);
try {
split = freqs.split(" ");
} catch (Exception e) {
split = DEFAULT_FREQS.split(" ");
}
return split;
}
// Here I'd replace 0 with (other) core number
public static synchronized int getMaxFreq() {
try {
return Integer.parseInt(FileUtils.readFile(format(SCALING_MAX_FREQ, 0), "1200000"));
} catch (Exception ignored){}
return 1200000;
}
private static String format(String format, Object arg) {
return String.format(Locale.US, format, arg);
}
}
FileUtils class
public final class FileUtils {
private FileUtils() {
}
public static String readFile(String pathname, String defaultOutput) {
return baseReadSingleLineFile(new File(pathname), defaultOutput);
}
public static String readFile(File file, String defaultOutput) {
return baseReadSingleLineFile(file, defaultOutput);
}
// Async
private static String baseReadSingleLineFile(File file, String defaultOutput) {
String ret = defaultOutput;
Thread thread = new Thread(() -> {
if (file.isFile() || file.exists()) {
if (file.canRead()) {
try {
FileInputStream inputStream = new FileInputStream(file);
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
String line = reader.readLine(); // Fisrt line
reader.close();
inputStream.close();
ret = line;
} catch (Exception ignored) {}
} else
// Uses cat command
ret = RootUtils.readFile(file, defaultOutput);
}
});
thread.start();
// 3 seconds timeout
long endTimeMillis = System.currentTimeMillis() + 3000;
while (thread.isAlive())
if (System.currentTimeMillis() > endTimeMillis)
return defaultOutput;
return ret;
}
}