fixed multi-core support; cleaned up some bugs

This commit is contained in:
HappyZ 2017-01-27 15:46:01 -08:00
parent 8149f6f021
commit 111c5b6116
3 changed files with 235 additions and 160 deletions

View File

@ -40,7 +40,6 @@ public class MainActivity extends Activity {
protected static final String udpserver_pathport = "~/mobileRDMABeach/UDPServer 32000 ";
protected static final String binaryFolderPath = "/data/local/tmp/";
protected static final String binary_tcpdump = "tcpdump";
protected static final int oneMB = 1048576;
private static final String TAG = "MainActivity";
private static final int mVersion = Build.VERSION.SDK_INT;
// the configs
@ -66,7 +65,7 @@ public class MainActivity extends Activity {
protected static int UDPfinishTime = 0;
protected static double reportedFinishTime = 0.0;
protected static int repeatCounts = 3;
protected static int bytes2send = 10 * oneMB; // default 10MB
protected static int bytes2send = 10 * Utilities.oneMB; // default 10MB
protected static int currentBandwidth = -1; // bps, default is -1, indicating unlimited
protected static TextView txt_results;
protected static Handler myHandler;
@ -550,9 +549,10 @@ public class MainActivity extends Activity {
}
/**
* Intialize parameters etc.
* Initialize parameters etc.
*/
protected void initialization() {
// must have root privilege in order to run
try {
Runtime.getRuntime().exec("su");
@ -561,12 +561,26 @@ public class MainActivity extends Activity {
} catch (Throwable e) {
Toast.makeText(this, R.string.warn_root, Toast.LENGTH_LONG).show();
}
// must have storage permission
Utilities.verifyStoragePermissions(this);
// permission error
if (!Utilities.canWriteOnExternalStorage()) {
Log.d(TAG, "Permission error: cannot write on external storage.");
MainActivity.myHandler.post(new Runnable() {
@Override
public void run() {
MainActivity.txt_results.append("Can't write on external storage!\n");
}
});
}
// handler that updates the ui at main thread
// it's used in sslogger thus will be modded in receiver activity also
// do not modify this
myHandler = new Handler();
// sslogger intent
intentSSLogger = new Intent(this, SSLogger.class);
// grab WiFi service and check if wifi is enabled
@ -638,39 +652,39 @@ public class MainActivity extends Activity {
@Override
public void onClick(View v) {
final CharSequence[] mItems={
(bytes2send == (oneMB/2))?"Current: 0.5MB":"0.5MB",
(bytes2send == (oneMB))?"Current: 1MB":"1MB",
(bytes2send == (2*oneMB))?"Current: 2MB":"2MB",
(bytes2send == (5*oneMB))?"Current: 5MB":"5MB",
(bytes2send == (10*oneMB))?"Current: 10MB":"10MB",
(bytes2send == (20*oneMB))?"Current: 20MB":"20MB",
(bytes2send == (50*oneMB))?"Current: 50MB":"50MB",
(bytes2send == (100*oneMB))?"Current: 100MB":"100MB",
(bytes2send == (200*oneMB))?"Current: 200MB":"200MB",
(bytes2send == (500*oneMB))?"Current: 500MB":"500MB",
(bytes2send == (1000*oneMB))?"Current: 1GB":"1GB"};
(bytes2send == (Utilities.oneMB/2))?"Current: 0.5MB":"0.5MB",
(bytes2send == (Utilities.oneMB))?"Current: 1MB":"1MB",
(bytes2send == (2*Utilities.oneMB))?"Current: 2MB":"2MB",
(bytes2send == (5*Utilities.oneMB))?"Current: 5MB":"5MB",
(bytes2send == (10*Utilities.oneMB))?"Current: 10MB":"10MB",
(bytes2send == (20*Utilities.oneMB))?"Current: 20MB":"20MB",
(bytes2send == (50*Utilities.oneMB))?"Current: 50MB":"50MB",
(bytes2send == (100*Utilities.oneMB))?"Current: 100MB":"100MB",
(bytes2send == (200*Utilities.oneMB))?"Current: 200MB":"200MB",
(bytes2send == (500*Utilities.oneMB))?"Current: 500MB":"500MB",
(bytes2send == (1000*Utilities.oneMB))?"Current: 1GB":"1GB"};
AlertDialog.Builder mDialog = new AlertDialog.Builder(MainActivity.this);
mDialog.setItems(mItems, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if (which < 3) {
bytes2send = oneMB/2;
bytes2send = Utilities.oneMB/2;
for (int i = 0; i < which; ++i)
bytes2send *= 2;
} else if (which < 6) {
bytes2send = 5 * oneMB;
bytes2send = 5 * Utilities.oneMB;
for (int i = 3; i < which; ++i)
bytes2send *= 2;
} else if (which < 9) {
bytes2send = 50 * oneMB;
bytes2send = 50 * Utilities.oneMB;
for (int i = 6; i < which; ++i)
bytes2send *= 2;
} else if (which == 9) {
bytes2send = 500 * oneMB;
bytes2send = 500 * Utilities.oneMB;
} else if (which == 10) {
bytes2send = 1000 * oneMB;
bytes2send = 1000 * Utilities.oneMB;
} else {
bytes2send = 10 * oneMB; // default 10MB
bytes2send = 10 * Utilities.oneMB; // default 10MB
}
if (isVerbose) {
Log.d(TAG, "outgoing/incoming bytes is set to " + bytes2send);
@ -716,7 +730,7 @@ public class MainActivity extends Activity {
out.add("Disable TCPDump");
}
try {
Process proc = Runtime.getRuntime().exec("ls /sys/class/net");
Process proc = Runtime.getRuntime().exec("su -c ls /sys/class/net");
proc.waitFor();
String line;
BufferedReader is = new BufferedReader(new InputStreamReader(proc.getInputStream()));

View File

@ -57,13 +57,6 @@ public class SSLogger extends Service {
String[] cpuUsage = new String[MainActivity.coreNum + 1]; // placeholder for each core
String[] cpuFreq = new String[MainActivity.coreNum]; // placeholder for each core
// first line to write is instruction
tmp = "# timestamp totalUsage";
for (i = 0; i < MainActivity.coreNum; ++i) {
tmp += " cpu" + i + " freq" + i;
}
tmp += "\n";
// if SSLogger is set to run
while(isRunning) {
@ -77,7 +70,7 @@ public class SSLogger extends Service {
readFrequency(cpuFreq);
// construct bytes for cpuRaw log
tmp += mTime + " " + cpuUsage[0];
tmp = mTime + " " + cpuUsage[0];
for (i = 0; i < MainActivity.coreNum; ++i) {
tmp += " " + cpuUsage[i + 1] + " " + cpuFreq[i];
}
@ -186,12 +179,6 @@ public class SSLogger extends Service {
// permission error
if (!Utilities.canWriteOnExternalStorage()) {
MainActivity.myHandler.post(new Runnable() {
@Override
public void run() {
MainActivity.txt_results.append("Can't write sdcard\n");
}
});
onDestroy();
}

View File

@ -24,6 +24,7 @@ import java.util.Collections;
import java.util.Date;
import java.util.Enumeration;
import java.util.List;
import java.util.Locale;
/**
* Created by yanzi on 10/1/15.
@ -33,8 +34,9 @@ public class Utilities {
private static final String TAG = "Utilities";
// variables
protected static String myInetIP = "127.0.0.1";
protected static String myMAC = "";
static int oneMB = 1048576;
static String myInetIP = null;
static String myMAC = null;
// Storage Permissions
private static final int REQUEST_EXTERNAL_STORAGE = 1;
@ -43,13 +45,15 @@ public class Utilities {
Manifest.permission.WRITE_EXTERNAL_STORAGE
};
/**
* Android 6.0 + required
* Checks if the app has permission to write to device storage
* If the app does not has permission then the user will be prompted to grant permissions
* @param activity
* @param activity:
*/
public static void verifyStoragePermissions(Activity activity) {
static void verifyStoragePermissions(Activity activity) {
// Check if we have write permission
int permission = ActivityCompat.checkSelfPermission(
activity, Manifest.permission.WRITE_EXTERNAL_STORAGE);
@ -69,7 +73,7 @@ public class Utilities {
* check if we can write on external storage
* @return true/false
*/
public static boolean canWriteOnExternalStorage() {
static boolean canWriteOnExternalStorage() {
String state = Environment.getExternalStorageState();
if (Environment.MEDIA_MOUNTED.equals(state)) {
return true;
@ -80,11 +84,13 @@ public class Utilities {
/**
* get the ip and mac addresses
*/
protected static void getSelfIdentity(String interface_name, boolean useIPv4) {
static void getSelfIdentity(String interface_name, boolean useIPv4) {
String name;
Enumeration<NetworkInterface> networks;
Enumeration<InetAddress> inetAddresses;
NetworkInterface network;
myInetIP = null;
myMAC = null;
try {
networks = NetworkInterface.getNetworkInterfaces();
@ -109,7 +115,6 @@ public class Utilities {
}
myMAC = sb.toString();
}
Log.d(TAG, "myMAC: " + myMAC);
// get the ip address
inetAddresses = network.getInetAddresses();
@ -132,21 +137,32 @@ public class Utilities {
}
}
}
Log.d(TAG, "myIP: " + myInetIP);
}
} catch (SocketException e) {
e.printStackTrace();
}
if (myMAC == null) {
Log.d(TAG, "Failed to get MAC from interface " + interface_name);
myMAC = "00:00:00:00:00:00";
}
if (myInetIP == null) {
Log.d(TAG, "Failed to get IP from interface " + interface_name);
myInetIP = "127.0.0.1";
}
Log.d(TAG, "myMAC: " + myMAC);
Log.d(TAG, "myIP: " + myInetIP);
}
/**
* parse binary file output
* @param output
* @param output:
* @return double
*/
protected static double parseBinOutput(String output) {
static double parseBinOutput(String output) {
String[] toks = output.trim().split(":");
if (toks.length == 2) {
return Double.parseDouble(toks[1]);
@ -158,7 +174,7 @@ public class Utilities {
* get the number of cores of device
* @return int > 0
*/
protected static int getNumCores() {
static int getNumCores() {
Process proc;
BufferedReader stdout_buf;
String stdout;
@ -202,40 +218,45 @@ public class Utilities {
*/
protected static int getMyPID(String inName, boolean flag) {
String commd;
Process proc;
BufferedReader stdout_buf;
String stdout;
// get commd ready
if (flag)
commd = "su -c busybox ps | grep "
+ inName + " | grep -v grep | head -1 | awk '{print $1}'";
else
commd = "su -c busybox ps | grep "
+ inName + " | grep -v grep | head -1 | awk '{print $3}'";
try {
Process proc = Runtime.getRuntime().exec(commd);
proc = Runtime.getRuntime().exec(commd);
proc.waitFor();
String line;
StringBuilder out = new StringBuilder();
BufferedReader is = new BufferedReader(
new InputStreamReader(proc.getInputStream()));
while ((line = is.readLine()) != null) {
out.append(line).append("\n");
// read std out
stdout_buf = new BufferedReader(new InputStreamReader(
proc.getInputStream()));
stdout = stdout_buf.readLine();
stdout_buf.close();
if (! stdout.equals("")) {
Log.d(TAG, inName + "PID: " + stdout);
return Integer.parseInt(stdout);
}
String tmp = out.toString().trim();
if (!tmp.equals("")) {
return Integer.parseInt(tmp);
}
} catch (InterruptedException unimportant) {
Log.d(TAG, "InterruptedException but unimportant");
} catch (IOException e) {
Log.d(TAG, "IOException but unimportant");
} catch (InterruptedException | IOException ignored) {
Log.d(TAG, "Faild to fetch PID for " + inName);
}
return -1;
}
/**
* check if a file exists
* @param myFile
* @param myFile:
* @return true/false
*/
protected static boolean fileExist(String myFile) {
static boolean fileExist(String myFile) {
File file = new File(myFile);
if (file.exists() && file.isFile())
return true;
@ -244,11 +265,11 @@ public class Utilities {
/**
* check if a directory exists
* @param myDirectory
* @param myDirectory:
* @param createIfNot: try to create the folder if directory does not exist
* @return true/false
*/
protected static boolean dirExist(String myDirectory, boolean createIfNot) {
static boolean dirExist(String myDirectory, boolean createIfNot) {
File file = new File(myDirectory);
if (file.exists() && file.isDirectory())
return true;
@ -264,116 +285,154 @@ public class Utilities {
}
/**
* parse CPU for a folder
* @param folderName
* post parse CPU for a folder
* @param folderName:
* @return true/false
*/
protected static boolean parseCPUforFolder(String folderName) {
static boolean parseCPUforFolder(String folderName) {
Process proc;
BufferedReader stdout_buf, br;
FileOutputStream os_cpu;
String cpuFile, line, tmp;
int i, offset;
try {
Process proc = Runtime.getRuntime().exec(
proc = Runtime.getRuntime().exec(
"su && cd " + MainActivity.outFolderPath + "/"
+ folderName + " && ls *.cpuRaw");
proc.waitFor();
InputStream stdout = proc.getInputStream();
byte[] buffer = new byte[20];
int read;
StringBuilder out = new StringBuilder();
while(true){
read = stdout.read(buffer);
if(read<0){
Log.d(TAG, "Failed in parseCPUforFolder: ls nothing");
break;
}
out.append(new String(buffer, 0, read));
if(read<20){
break;
}
}
if (!out.toString().equals("")) {
String[] cpuFiles = out.toString().split("\\n");
for (int i = 0; i < cpuFiles.length; ++i) {
try {
BufferedReader br = new BufferedReader(
new FileReader(
MainActivity.outFolderPath + "/"
+ folderName + "/" + cpuFiles[i]));
FileOutputStream os_cpu = new FileOutputStream(
new File(
MainActivity.outFolderPath + "/"
+ folderName,
cpuFiles[i].replace("cpuRaw", "cpu")));
String line;
while ((line = br.readLine()) != null) {
String[] toks = line.split("\\s+");
// format for Ana's script:
// time
// cpuTotal idle
// cpuTotal used
// cpu0 idle
// cpu0 used
// cpu0 freq
// cpu1 freq
// cpuTotal normal process user mode
// cpuTotal niced process in user mode
// cpuTotal kernal mode
// cpuTotal IO
// cpuTotal hardware interrupts
// cpuTotal software interrupts
// cpu0 normal process user mode
// cpu0 niced process in user mode
// cpu0 kernal mode
// cpu0 IO
// cpu0 hardware interrupts
// cpu0 software interrupts
os_cpu.write((toks[0] + " " // time
// cpuTotal toks[1-11]
+ toks[5] + " " // cpuTotal idle
// cpuTotal used
+ (Long.parseLong(toks[2]) + Long.parseLong(toks[3])
+ Long.parseLong(toks[4]) + Long.parseLong(toks[6])
+ Long.parseLong(toks[7]) + Long.parseLong(toks[8])) + " "
// cpu 0 toks[12-22]
+ toks[16] + " " // cpu0 idle
// cpu0 used
+ (Long.parseLong(toks[13]) + Long.parseLong(toks[14])
+ Long.parseLong(toks[15]) + Long.parseLong(toks[17])
+ Long.parseLong(toks[18]) + Long.parseLong(toks[19])) + " "
// cpu 0 freq toks[23]
+ toks[23] + " "
// cpu 1 freq toks[35]
+ toks[35] + " "
// cpuTotal details
+ toks[2] + " " + toks[3] + " " + toks[4] + " "
+ toks[6] + " " + toks[7] + " " + toks[8] + " "
// cpu0 details
+ toks[13] + " " + toks[14] + " " + toks[15] + " "
+ toks[17] + " " + toks[18] + " " + toks[19]).getBytes());
// cpu 1 toks[24-34]
os_cpu.write("\n".getBytes());
os_cpu.flush();
}
os_cpu.close();
} catch (IOException unimportant) {
return false;
// read std out
stdout_buf = new BufferedReader(new InputStreamReader(
proc.getInputStream()));
while ((cpuFile = stdout_buf.readLine()) != null) {
br = new BufferedReader(new FileReader(
MainActivity.outFolderPath + "/"
+ folderName + "/" + cpuFile));
os_cpu = new FileOutputStream(new File(
MainActivity.outFolderPath + "/"
+ folderName + "/" + cpuFile.replace("cpuRaw", "cpu")));
while ((line = br.readLine()) != null) {
String[] s = line.split("\\s+");
/*
* each line format as the following
* [ // 0 1 2 3 4 5 6 7 8 9-11
* timestamp, "cpu", user, nice, system, idle, iowait, irq, softirq, 0, 0, 0,
* // 12 13 14 15 16 17 18 19 20-22 23
* "cpu0", user, nice, system, idle, iowait, irq, softirq, 0, 0, 0, frequency,
* ...
* ]
*/
tmp = s[0] + " " // timestamp
+ s[5] + " " // cpu_total idle
+ parseUsedCPU(s, 1); // cpu_total used
for (i = 0; i < MainActivity.coreNum; ++i) {
offset = (i + 1) * 12;
tmp += " " + s[4 + offset] // cpu_i idle
+ " " + parseUsedCPU(s, offset) // cpu_i used
+ " " + s[offset + 11]; // cpu_i frequency
}
tmp += "\n";
/*
* convert to parsed format (each line):
* [
* timestamp, cpu_total idle, cpu_total used,
* cpu_0 idle, cpu_0 used, cpu_0 frequency,
* ...
* ]
*/
os_cpu.write(tmp.getBytes());
// format for Ana's script:
// time
// cpuTotal idle
// cpuTotal used
// cpu0 idle
// cpu0 used
// cpu0 freq
// cpu1 freq
// cpuTotal normal process user mode
// cpuTotal niced process in user mode
// cpuTotal kernal mode
// cpuTotal IO
// cpuTotal hardware interrupts
// cpuTotal software interrupts
// cpu0 normal process user mode
// cpu0 niced process in user mode
// cpu0 kernal mode
// cpu0 IO
// cpu0 hardware interrupts
// cpu0 software interrupts
// os_cpu.write((toks[0] + " " // time
// // cpuTotal toks[1-11]
// + toks[5] + " " // cpuTotal idle
// // cpuTotal used
// + (Long.parseLong(toks[2]) + Long.parseLong(toks[3])
// + Long.parseLong(toks[4]) + Long.parseLong(toks[6])
// + Long.parseLong(toks[7]) + Long.parseLong(toks[8])) + " "
// // cpu 0 toks[12-22]
// + toks[16] + " " // cpu0 idle
// // cpu0 used
// + (Long.parseLong(toks[13]) + Long.parseLong(toks[14])
// + Long.parseLong(toks[15]) + Long.parseLong(toks[17])
// + Long.parseLong(toks[18]) + Long.parseLong(toks[19])) + " "
// // cpu 0 freq toks[23]
// + toks[23] + " "
// // cpu 1 freq toks[35]
// + toks[35] + " "
// // cpuTotal details
// + toks[2] + " " + toks[3] + " " + toks[4] + " "
// + toks[6] + " " + toks[7] + " " + toks[8] + " "
// // cpu0 details
// + toks[13] + " " + toks[14] + " " + toks[15] + " "
// + toks[17] + " " + toks[18] + " " + toks[19]).getBytes());
// // cpu 1 toks[24-34]
// os_cpu.write("\n".getBytes());
}
br.close();
os_cpu.close();
}
} catch (IOException e) {
// e.printStackTrace();
return false;
} catch (InterruptedException e) {
// e.printStackTrace();
stdout_buf.close();
} catch (IOException | InterruptedException ignore) {
return false;
}
return true;
}
/**
* parse the cpu usage (used)
* @param tmp: cpu usage
* @return long: used cpu usage
*/
static Long parseUsedCPU(String[] tmp, int offset) {
return (Long.parseLong(tmp[1 + offset])
+ Long.parseLong(tmp[2 + offset])
+ Long.parseLong(tmp[3 + offset])
+ Long.parseLong(tmp[5 + offset])
+ Long.parseLong(tmp[6 + offset])
+ Long.parseLong(tmp[7 + offset]));
}
/**
* Translate the selection index into throughput setup
* @param myI
* @return
* @param myI:
* @return integer
*/
protected static int findCorrespondingThrpt(int myI) {
static int findCorrespondingThrpt(int myI) {
if (myI < 19) {
return (800 - (myI * 40)) * 1000000;
} else if (myI < 37) {
@ -390,8 +449,18 @@ public class Utilities {
}
}
protected static void estimateTime(int numRepeats, int numSelectedItems, int totalBytes, ArrayList<Integer> selectedItemsThrpt) {
/**
* Estimate how much time left
* @param numRepeats:
* @param numSelectedItems:
* @param totalBytes:
* @param selectedItemsThrpt:
*/
static void estimateTime(
int numRepeats, int numSelectedItems, int totalBytes,
ArrayList<Integer> selectedItemsThrpt) {
int time = 0;
if (MainActivity.isLocal) {
for (int k = 0; k < selectedItemsThrpt.size(); ++k)
time += (Math.max(totalBytes / findCorrespondingThrpt(selectedItemsThrpt.get(k)) + 20, 20));
@ -399,8 +468,13 @@ public class Utilities {
for (int k = 0; k < selectedItemsThrpt.size(); ++k)
time += (Math.max(totalBytes / findCorrespondingThrpt(selectedItemsThrpt.get(k)) + 20, 60));
}
time = (time + 15) * numSelectedItems * numRepeats * 1000;
final String estimatedTime = new SimpleDateFormat("MM/dd HH:mm:ss").format(new Date(System.currentTimeMillis() + time));
final String estimatedTime =
new SimpleDateFormat("MM/dd HH:mm:ss", Locale.US).format(
new Date(System.currentTimeMillis() + time));
MainActivity.myHandler.post(new Runnable() {
@Override
public void run() {