I develop a widget on Android which display many useful informations.
I am trying to modify this method to return the percent of use of one cpu core, in order to have the percent of use of each core !!!
On my HTC One X, i have in " /proc/stat ":
cpu 183549 10728 236016 3754379 7530 41 1013 0 0 0
cpu0 141962 5990 196956 720894 3333 41 970 0 0 0
cpu1 23400 2550 23158 980901 2211 0 23 0 0 0
cpu2 13602 1637 12561 1019126 1216 0 18 0 0 0
cpu3 4585 551 3341 1033458 770 0 2 0 0 0
I use this method to return the percent of use of all cpu core.
public float readUsage() {
try {
RandomAccessFile reader = new RandomAccessFile("/proc/stat", "r");
String load = reader.readLine();
String[] toks = load.split(" ");
long idle1 = Long.parseLong(toks[5]);
long cpu1 = Long.parseLong(toks[2]) + Long.parseLong(toks[3]) + Long.parseLong(toks[4])
+ Long.parseLong(toks[6]) + Long.parseLong(toks[7]) + Long.parseLong(toks[8]);
try {
Thread.sleep(800);
} catch (Exception e) {}
reader.seek(0);
load = reader.readLine();
reader.close();
toks = load.split(" ");
long idle2 = Long.parseLong(toks[5]);
long cpu2 = Long.parseLong(toks[2]) + Long.parseLong(toks[3]) + Long.parseLong(toks[4])
+ Long.parseLong(toks[6]) + Long.parseLong(toks[7]) + Long.parseLong(toks[8]);
return (float)(cpu2 - cpu1) / ((cpu2 + idle2) - (cpu1 + idle1));
} catch (IOException ex) {
ex.printStackTrace();
}
return 0;
}
I am trying this to get cpu1's use, but it doesn't work:
public float readUsageCPU0() {
try {
RandomAccessFile reader = new RandomAccessFile("/proc/stat", "r");
reader.seek(0);
String load = reader.readLine();
load = reader.readLine();
load = reader.readLine();
String[] toks = load.split(" ");
long idle1 = Long.parseLong(toks[5]);
long cpu1 = Long.parseLong(toks[2]) + Long.parseLong(toks[3]) + Long.parseLong(toks[4])
+ Long.parseLong(toks[6]) + Long.parseLong(toks[7]) + Long.parseLong(toks[8]);
try {
Thread.sleep(500);
} catch (Exception e) {}
reader.seek(0);
load = reader.readLine();
load = reader.readLine();
load = reader.readLine();
reader.close();
toks = load.split(" ");
long idle2 = Long.parseLong(toks[5]);
long cpu2 = Long.parseLong(toks[2]) + Long.parseLong(toks[3]) + Long.parseLong(toks[4])
+ Long.parseLong(toks[6]) + Long.parseLong(toks[7]) + Long.parseLong(toks[8]);
return (float)(cpu2 - cpu1) / ((cpu2 + idle2) - (cpu1 + idle1));
} catch (IOException ex) {
ex.printStackTrace();
}
return 0;
}
This allows to read one line and the cursor stays at the end of the line:
String load = reader.readLine();
So, I tried to use it twice to get CPU0's use and third to get CPU1. But the result is always 0 or 100 ... I don't understand why!
Am I using the right way? Am I using the right file? Is this result normal?
public class CpuStat {
private static final String TAG = "CpuUsage";
private RandomAccessFile statFile;
private CpuInfo mCpuInfoTotal;
private ArrayList<CpuInfo> mCpuInfoList;
public CpuStat() {
}
public void update() {
try {
createFile();
parseFile();
closeFile();
} catch (FileNotFoundException e) {
statFile = null;
Log.e(TAG, "cannot open /proc/stat: " + e);
} catch (IOException e) {
Log.e(TAG, "cannot close /proc/stat: " + e);
}
}
private void createFile() throws FileNotFoundException {
statFile = new RandomAccessFile("/proc/stat", "r");
}
public void closeFile() throws IOException {
if (statFile != null)
statFile.close();
}
private void parseFile() {
if (statFile != null) {
try {
statFile.seek(0);
String cpuLine = "";
int cpuId = -1;
do {
cpuLine = statFile.readLine();
parseCpuLine(cpuId, cpuLine);
cpuId++;
} while (cpuLine != null);
} catch (IOException e) {
Log.e(TAG, "Ops: " + e);
}
}
}
private void parseCpuLine(int cpuId, String cpuLine) {
if (cpuLine != null && cpuLine.length() > 0) {
String[] parts = cpuLine.split("[ ]+");
String cpuLabel = "cpu";
if ( parts[0].indexOf(cpuLabel) != -1) {
createCpuInfo(cpuId, parts);
}
} else {
Log.e(TAG, "unable to get cpu line");
}
}
private void createCpuInfo(int cpuId, String[] parts) {
if (cpuId == -1) {
if (mCpuInfoTotal == null)
mCpuInfoTotal = new CpuInfo();
mCpuInfoTotal.update(parts);
} else {
if (mCpuInfoList == null)
mCpuInfoList = new ArrayList<CpuInfo>();
if (cpuId < mCpuInfoList.size())
mCpuInfoList.get(cpuId).update(parts);
else {
CpuInfo info = new CpuInfo();
info.update(parts);
mCpuInfoList.add(info);
}
}
}
public int getCpuUsage(int cpuId) {
update();
int usage = 0;
if (mCpuInfoList != null) {
int cpuCount = mCpuInfoList.size();
if (cpuCount > 0) {
cpuCount--;
if (cpuId == cpuCount) { // -1 total cpu usage
usage = mCpuInfoList.get(0).getUsage();
} else {
if (cpuId <= cpuCount)
usage = mCpuInfoList.get(cpuId).getUsage();
else
usage = -1;
}
}
}
return usage;
}
public int getTotalCpuUsage() {
update();
int usage = 0;
if (mCpuInfoTotal != null)
usage = mCpuInfoTotal.getUsage();
return usage;
}
public String toString() {
update();
StringBuffer buf = new StringBuffer();
if (mCpuInfoTotal != null) {
buf.append("Cpu Total : ");
buf.append(mCpuInfoTotal.getUsage());
buf.append("%");
}
if (mCpuInfoList != null) {
for (int i=0; i < mCpuInfoList.size(); i++) {
CpuInfo info = mCpuInfoList.get(i);
buf.append(" Cpu Core(" + i + ") : ");
buf.append(info.getUsage());
buf.append("%");
info.getUsage();
}
}
return buf.toString();
}
public class CpuInfo {
private int mUsage;
private long mLastTotal;
private long mLastIdle;
public CpuInfo() {
mUsage = 0;
mLastTotal = 0;
mLastIdle = 0;
}
private int getUsage() {
return mUsage;
}
public void update(String[] parts) {
// the columns are:
//
// 0 "cpu": the string "cpu" that identifies the line
// 1 user: normal processes executing in user mode
// 2 nice: niced processes executing in user mode
// 3 system: processes executing in kernel mode
// 4 idle: twiddling thumbs
// 5 iowait: waiting for I/O to complete
// 6 irq: servicing interrupts
// 7 softirq: servicing softirqs
//
long idle = Long.parseLong(parts[4], 10);
long total = 0;
boolean head = true;
for (String part : parts) {
if (head) {
head = false;
continue;
}
total += Long.parseLong(part, 10);
}
long diffIdle = idle - mLastIdle;
long diffTotal = total - mLastTotal;
mUsage = (int)((float)(diffTotal - diffIdle) / diffTotal * 100);
mLastTotal = total;
mLastIdle = idle;
Log.i(TAG, "CPU total=" + total + "; idle=" + idle + "; usage=" + mUsage);
}
}
}