summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--app-launcher/Android.mk24
-rw-r--r--app-launcher/README76
-rwxr-xr-xapp-launcher/app-launcher461
-rw-r--r--app-launcher/computestats.c118
-rw-r--r--app-launcher/computestatsf.c118
5 files changed, 797 insertions, 0 deletions
diff --git a/app-launcher/Android.mk b/app-launcher/Android.mk
new file mode 100644
index 00000000..755b1d3f
--- /dev/null
+++ b/app-launcher/Android.mk
@@ -0,0 +1,24 @@
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+#LOCAL_32_BIT_ONLY = true
+LOCAL_MODULE_HOST_OS := linux
+LOCAL_SRC_FILES := computestatsf.c
+LOCAL_MODULE := computestatsf
+LOCAL_MODULE_TAGS := debug
+include $(BUILD_HOST_EXECUTABLE)
+
+include $(CLEAR_VARS)
+#LOCAL_32_BIT_ONLY = true
+LOCAL_MODULE_HOST_OS := linux
+LOCAL_SRC_FILES := computestats.c
+LOCAL_MODULE := computestats
+LOCAL_MODULE_TAGS := debug
+include $(BUILD_HOST_EXECUTABLE)
+
+include $(CLEAR_VARS)
+LOCAL_PREBUILT_EXECUTABLES := app-launcher
+LOCAL_MODULE_HOST_OS := linux
+LOCAL_MODULE_TAGS := debug
+LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES)
+include $(BUILD_HOST_PREBUILT)
diff --git a/app-launcher/README b/app-launcher/README
new file mode 100644
index 00000000..cca58aa5
--- /dev/null
+++ b/app-launcher/README
@@ -0,0 +1,76 @@
+ Instructions to Run (and modify) app-launcher script
+ ----------------------------------------------------
+
+Introduction: app-launcher is a script that launches apps many times,
+measures various system metrics, computes basic stats for the metrics
+and reports that stats.
+
+Launching app-launcher :
+app-launcher -a|-b|-u [-v] num-iterations
+-a:Run on all cores
+-b:Run only big cores
+-c:pagecached. Don't drop pagecache before each launch (not default)
+-h:Dump help menu'
+-u:user experience, no change to cpu/gpu frequencies or governors'
+-v : Optional, Verbose mode, prints stats on a lot of metrics.
+num-iterations : Must be >= 100 to get statistically valid data.
+
+Note, under -a|-b, we lock the CPU and GPU frequencies.
+
+Apps Supported :
+On phone, these 4 apps are launched
+Chrome
+Camera
+Maps
+Youtube
+
+On Fugu (Google TV), these 3 apps are launched
+YouTube
+Games
+Music
+
+To add new apps, launch app manually and grep for package name +
+activity name in logcat and add these to the launch_phone_apps()
+function.
+
+Adding support for new Devices to app-launcher :
+There are a few bits of code needed to do this.
+1) Add a new cpufreq_<device> routine to fix the CPU/GPU frequencies
+as desired.
+2) Add logic that checks the $model obtained and check against your device.
+ (a) Then add code to call your cpufreq_<device> routine there
+ (b) (Optional) Add code to get the /system block device pathname. This is
+ only needed if you wan to get storage block device (/system) data.
+
+Adding new Metrics to app-launcher :
+You can modify the way simpleperf is used in the script to collect
+different metrics, but that will require a change to getstats() to
+parse the output as necessary. Adding new storage stats or other stats
+collected from /proc (or /sys) is definitely possible, but code needs
+to be written for that - modeled after the disk_stats_before/after
+functions.
+
+Notes :
+
+Here are the commands to launch/stop the various Apps of interest. The
+way to find the package and activity for the app of interest is to
+launch the app and then grep for it in logcat to find the
+package+activity and use that in am start.
+
+Chrome :
+adb shell 'simpleperf stat -a am start -W -n com.android.chrome/com.google.android.apps.chrome.Main'
+adb shell 'am force-stop com.android.chrome'
+
+Camera :
+adb shell 'simpleperf stat -a am start -W -n com.google.android.GoogleCamera/com.android.camera.CameraActivity'
+adb shell 'am force-stop com.google.android.GoogleCamera'
+
+Maps :
+adb shell 'simpleperf stat -a am start -W -n com.google.android.apps.maps/com.google.android.maps.MapsActivity'
+adb shell 'am force-stop com.google.android.apps.maps'
+
+Youtube :
+adb shell 'am start -W -n com.google.android.youtube/com.google.android.apps.youtube.app.WatchWhileActivity'
+adb shell 'am force-stop com.google.android.youtube'
+
+
diff --git a/app-launcher/app-launcher b/app-launcher/app-launcher
new file mode 100755
index 00000000..44e62f8d
--- /dev/null
+++ b/app-launcher/app-launcher
@@ -0,0 +1,461 @@
+#!/bin/sh
+
+parseoptions() {
+ verbose=false
+ user_experience=false
+ little_cores_off=false
+ iterations=0
+ pagecached=false
+
+ while [ $# -gt 1 ]
+ do
+ case $1 in
+ -a)
+ ;;
+ -b)
+ little_cores_off=true
+ ;;
+ -c)
+ pagecached=true
+ ;;
+ -h)
+ usage
+ ;;
+ -u)
+ user_experience=true
+ ;;
+ -v)
+ verbose=true
+ ;;
+ *)
+ usage
+ ;;
+ esac
+ shift
+ done
+
+ iterations=$1
+ if [ $iterations -lt 100 ]; then
+ usage
+ fi
+}
+
+getstats () {
+ infile=$1
+ app=$2
+ echo "Data for $app :"
+
+ # Chrome related Hack alert :
+ # For Chrome launches, "TotalTime" is the right metric to measure. That is closer
+ # to what the user seems Chrome launch time as. So special case Chrome here.
+
+ if [ $app == Chrome ]; then
+ launch_time_string="TotalTime"
+ else
+ launch_time_string="ThisTime"
+ fi
+
+ # From Activity Manager
+ echo "Launch Time :"
+ fgrep $launch_time_string $infile | awk '{print $2}' | computestats
+
+ # Data from simpleperf
+ echo "cpu-cycles :"
+ fgrep cpu-cycles $infile | awk '{print $1}' | sed s/,//g | computestats
+
+ # CPU util% Data from /proc/stat
+ echo "cpu-util% :"
+ fgrep 'Total CPU util' $infile | awk '{print $5}' | computestatsf
+ echo "user-cpu-util% :"
+ fgrep 'User CPU util' $infile | awk '{print $5}' | computestatsf
+ echo "sys-cpu-util% (incl hardirq/softirq) :"
+ fgrep 'Sys CPU util' $infile | awk '{print $5}' | computestatsf
+
+ if [ $verbose == true ]; then
+ echo "instructions : "
+ fgrep instructions $infile | awk '{print $1}' | sed s/,//g | computestats
+
+ echo "cycles per instruction : "
+ fgrep instructions $infile | awk '{print $4}' | sed s/,//g | computestatsf
+
+ echo "branch-misses : "
+ fgrep branch-misses $infile | awk '{print $1}' | sed s/,//g | computestats
+
+ echo "context-switches : "
+ fgrep context-switches $infile | awk '{print $1}' | sed s/,//g | computestats
+
+ echo "page-faults : "
+ fgrep page-faults $infile | awk '{print $1}' | sed s/,//g | computestats
+ fi
+
+ if [ $system_bdev_set == true ]; then
+ # (Storage) Data from /proc we've collected
+ echo "KB read for $system_block_device blkdev :"
+ fgrep KB $infile | grep system | awk '{print $5}' | computestats
+
+ echo "iowait% :"
+ fgrep IOwait $infile | awk '{print $3}' | computestatsf
+
+ echo "Device util% for $system_block_device blkdev :"
+ fgrep 'Device util' $infile | awk '{print $4}' | computestatsf
+ fi
+}
+
+cpufreq_volantis() {
+ echo "Setting Governor to performance"
+ if [ $little_cores_off == true ]; then
+ echo "Cannot turn off Little cores on $model"
+ exit 1
+ fi
+ i=0
+ num_cores=2
+ while [ $i -lt $num_cores ]
+ do
+ adb shell "echo performance > /sys/devices/system/cpu/cpu$i/cpufreq/scaling_g\
+overnor"
+ adb shell "echo 2499000 > /sys/devices/system/cpu/cpu$i/cpufreq/scaling_max_fr\
+eq"
+ i=`expr $i + 1`
+ done
+ # Lock the GPU frequencies
+ echo -n 852000000 > /d/clock/override.gbus/rate
+ echo -n 1 > /d/clock/override.gbus/state
+}
+
+cpufreq_fugu() {
+ echo "Setting Governor to performance"
+ if [ $little_cores_off == true ]; then
+ echo "Cannot turn off Little cores on $model"
+ exit 1
+ fi
+ i=0
+ num_cores=4
+ while [ $i -lt $num_cores ]
+ do
+ adb shell "echo performance > /sys/devices/system/cpu/cpu$i/cpufreq/scaling_governor"
+ adb shell "echo 1833000 > /sys/devices/system/cpu/cpu$i/cpufreq/scaling_max_freq"
+ i=`expr $i + 1`
+ done
+}
+
+cpufreq_marlin_sailfish () {
+ echo "Setting Governor to performance"
+ # GPU Governor and Frequency
+ adb shell 'echo performance > /sys/class/kgsl/kgsl-3d0/devfreq/governor'
+ adb shell 'echo 624000000 > /sys/class/kgsl/kgsl-3d0/devfreq/max_freq'
+ if [ $little_cores_off == true ]; then
+ # Disable Little Cores, force app to run on big cores
+ echo "Disabling Little Cores"
+ adb shell 'echo 0 > /sys/devices/system/cpu/cpu0/online'
+ adb shell 'echo 0 > /sys/devices/system/cpu/cpu1/online'
+ else
+ echo "Enabling All Cores"
+ adb shell 'echo 1 > /sys/devices/system/cpu/cpu0/online'
+ adb shell 'echo 1 > /sys/devices/system/cpu/cpu1/online'
+ adb shell 'echo performance > /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor'
+ adb shell 'echo 1996800 > /sys/devices/system/cpu/cpu0/cpufreq/scaling_max_freq'
+ # cpu1 needed ?
+ adb shell 'echo performance > /sys/devices/system/cpu/cpu1/cpufreq/scaling_governor'
+ adb shell 'echo 1996800 > /sys/devices/system/cpu/cpu1/cpufreq/scaling_max_freq'
+ fi
+ # Set Governor to performance, up scaling_max_frequency to highest
+ adb shell 'echo performance > /sys/devices/system/cpu/cpu2/cpufreq/scaling_governor'
+ # Only necessary to set max_freq on cpu2, cpu3 is in same cluster and will
+ # automatically get the same settings
+ adb shell 'echo 2150400 > /sys/devices/system/cpu/cpu2/cpufreq/scaling_max_freq'
+}
+
+cpufreq_angler () {
+ echo "Setting Governor and Frequency"
+ # GPU Governor and Frequency
+ adb shell "echo performance > /sys/class/kgsl/kgsl-3d0/devfreq/governor"
+ adb shell "echo 0 > /sys/class/kgsl/kgsl-3d0/bus_split"
+ adb shell "echo 1 > /sys/class/kgsl/kgsl-3d0/force_clk_on"
+ adb shell "echo 10000 > /sys/class/kgsl/kgsl-3d0/idle_timer"
+ if [ $little_cores_off == true ]; then
+ # Disable Little Cores, force app to run on big cores
+ echo "Disabling Little Cores"
+ i=0
+ num_cores=4
+ while [ $i -lt $num_cores ]
+ do
+ adb shell "echo 0 > /sys/devices/system/cpu/cpu$i/online"
+ i=`expr $i + 1`
+ done
+ else
+ echo "Enabling All Cores"
+ # Enable Little cores here, set governor to performance
+ # Lock frequency of little cores
+ i=0
+ num_cores=4
+ while [ $i -lt $num_cores ]
+ do
+ adb shell "echo 1 > /sys/devices/system/cpu/cpu$i/online"
+ adb shell "echo performance > /sys/devices/system/cpu/cpu$i/cpufreq/scaling_governor"
+ # Lock frequency of little cores
+ adb shell "echo 1555200 > /sys/devices/system/cpu/cpu$i/cpufreq/scaling_max_freq"
+ i=`expr $i + 1`
+ done
+ fi
+ i=4
+ num_cores=8
+ while [ $i -lt $num_cores ]
+ do
+ adb shell "echo performance > /sys/devices/system/cpu/cpu$i/cpufreq/scaling_governor"
+ # Lock frequency of big cores
+ adb shell "echo 1958400 > /sys/devices/system/cpu/cpu$i/cpufreq/scaling_max_freq"
+ i=`expr $i + 1`
+ done
+}
+
+#
+# This strange bit of logic is needed to get the underlying block devices for /system
+# for Marlin/Sailfish
+#
+get_marlin_sailfish_devnames () {
+ # This bit of code required to get the block dev for /system and /vendor
+ # Suffix can be _a or _b, depending on what the active /system partition is
+# suffix=`adb shell getprop ro.boot.slot_suffix`
+ # Get the blockdevice using the suffix we got above
+# system_block_device=`adb shell ls -l /dev/block/platform/soc/*ufs*/by-name/system$suffix | awk '{ print $10 }' `
+ # Vendor is more straightforward, but we don't use it right now
+# vendor_block_device=`adb shell df /vendor | grep -v Filesystem | awk '{print $1}' `
+ # finally extract the last component of the absolute device pathname we got above
+# system_block_device=`echo $system_block_device | awk 'BEGIN { FS ="/" } ; { print $4 }' `
+# vendor_block_device=`echo $vendor_block_device | awk 'BEGIN { FS ="/" } ; { print $4 }' `
+ system_bdev_set=true
+# For now, hardcode sda for Marlin/Sailfish block device
+# XXX - We'll get stats for entire device
+ system_block_device=sda
+ echo Block Device $system_block_device
+}
+
+get_angler_devnames () {
+ # Get the underlying bdev from the "by-name" mapping
+ system_block_device=`adb shell 'find /dev/block/platform -name by-name | xargs ls -l' | grep system | awk '{ print $10 }' `
+ # extract the last component of the absolute device pathname we got above
+ system_block_device=`echo $system_block_device | awk 'BEGIN { FS ="/" } ; { print $4 }' `
+ # vendor is unused right now, but get the bdev anyway in case we decide to use it
+ # Get the underlying bdev from the "by-name" mapping
+ vendor_block_device=`adb shell 'find /dev/block/platform -name by-name | xargs ls -l' | grep vendor | awk '{ print $10 }' `
+ # extract the last component of the absolute device pathname we got above
+ vendor_block_device=`echo $vendor_block_device | awk 'BEGIN { FS ="/" } ; { print $4 }' `
+ system_bdev_set=true
+}
+
+get_fugu_devnames () {
+ system_block_device=`adb shell ls -l /dev/block/by-name/system | awk '{ print $10 }' `
+ system_block_device=`echo $system_block_device | awk 'BEGIN { FS ="/" } ; { print $4 }' `
+ system_bdev_set=true
+}
+
+get_volantis_devnames () {
+ # Hardcoding all of the mmcblk0 device for now
+ system_block_device=mmcblk0
+ system_bdev_set=true
+}
+
+system_stats_before() {
+ if [ $system_bdev_set == true ]; then
+ # Get BEFORE read stats for /system
+ adb shell 'cat /proc/diskstats' | grep -w $system_block_device > /tmp/$model-system
+ BEFORE_RD_IOS_SYSTEM=`awk '{ print $4 }' /tmp/$model-system`
+ BEFORE_RD_SECTORS_SYSTEM=`awk '{ print $6 }' /tmp/$model-system`
+ # iowait% computation
+ adb shell 'cat /proc/stat' | grep -w cpu > /tmp/procstat
+ user_ticks_before=`awk '{ print ($2 + $3) }' /tmp/procstat`
+ sys_ticks_before=`awk '{ print ($4 + $7 + $8) }' /tmp/procstat`
+ cpubusy_ticks_before=`awk '{ print ($2 + $3 + $4 + $7 + $8) }' /tmp/procstat`
+ iowait_ticks_before=`awk '{ print $6 }' /tmp/procstat`
+ total_ticks_before=`awk '{ print ($2 + $3 + $4 + $5 + $7 + $8) }' /tmp/procstat`
+ # Device util% computation
+ # Note hz=100, so multiplying uptime (in seconds) by 100, gives us
+ # the uptime in hz.
+ adb shell 'cat /proc/uptime' > /tmp/uptime
+ uptime_before_hz=`awk '{ print ($1 * 100) }' /tmp/uptime`
+ # Note that the device (busy) ticks is in ms. Since hz=100, dividing
+ # device (busy) ticks by 10, gives us this in the correct ticks units
+ device_util_before_hz=`awk '{ print ($13 / 10) }' /tmp/$model-system`
+ fi
+}
+
+system_stats_after() {
+ if [ $system_bdev_set == true ]; then
+ # Get AFTER read stats for /system
+ adb shell 'cat /proc/diskstats' | grep -w $system_block_device > /tmp/$model-system
+ AFTER_RD_IOS_SYSTEM=`awk '{ print $4 }' /tmp/$model-system`
+ AFTER_RD_SECTORS_SYSTEM=`awk '{ print $6 }' /tmp/$model-system`
+ # iowait% computation
+ adb shell 'cat /proc/stat' | grep -w cpu > /tmp/procstat
+ user_ticks_after=`awk '{ print ($2 + $3) }' /tmp/procstat`
+ sys_ticks_after=`awk '{ print ($4 + $7 + $8) }' /tmp/procstat`
+ cpubusy_ticks_after=`awk '{ print ($2 + $3 + $4 + $7 + $8) }' /tmp/procstat`
+ iowait_ticks_after=`awk '{ print $6 }' /tmp/procstat`
+ total_ticks_after=`awk '{ print ($2 + $3 + $4 + $5 + $7 + $8) }' /tmp/procstat`
+ # Device util% computation
+ # Note hz=100, so multiplying uptime (in seconds) by 100, gives us
+ # the uptime in hz.
+ adb shell 'cat /proc/uptime' > /tmp/uptime
+ uptime_after_hz=`awk '{ print ($1 * 100) }' /tmp/uptime`
+ # Note that the device (busy) ticks is in ms. Since hz=100, dividing
+ # device (busy) ticks by 10, gives us this in the correct ticks units
+ device_util_after_hz=`awk '{ print ($13 / 10) }' /tmp/$model-system`
+ fi
+}
+
+system_stats_delta() {
+ if [ $system_bdev_set == true ]; then
+ # Sectors to KB
+ READ_KB_SYSTEM=`expr $AFTER_RD_SECTORS_SYSTEM - $BEFORE_RD_SECTORS_SYSTEM`
+ READ_KB_SYSTEM=`expr $READ_KB_SYSTEM / 2`
+ echo Read IOs /system = `expr $AFTER_RD_IOS_SYSTEM - $BEFORE_RD_IOS_SYSTEM`
+ echo Read KB /system = $READ_KB_SYSTEM
+ echo $iowait_ticks_before $iowait_ticks_after $total_ticks_before $total_ticks_after | awk '{ printf "IOwait = %.2f\n", (($2 - $1) * 100.0) / ($4 - $3) }'
+ echo $device_util_before_hz $device_util_after_hz $uptime_before_hz $uptime_after_hz | awk '{ printf "Device util% = %.2f\n", (($2 - $1) * 100.0) / ($4 - $3) }'
+ echo $user_ticks_after $user_ticks_before $total_ticks_after $total_ticks_before | awk '{ printf "User CPU util% = %.2f\n", (($1 - $2) * 100.0) / ($3 - $4) }'
+ echo $sys_ticks_after $sys_ticks_before $total_ticks_after $total_ticks_before | awk '{ printf "Sys CPU util% = %.2f\n", (($1 - $2) * 100.0) / ($3 - $4) }'
+ echo $cpubusy_ticks_after $cpubusy_ticks_before $total_ticks_after $total_ticks_before | awk '{ printf "Total CPU util% = %.2f\n", (($1 - $2) * 100.0) / ($3 - $4) }'
+ fi
+}
+
+launch_app() {
+ package=$1
+ activity=$2
+ adb shell "am force-stop $package"
+ sleep 1
+
+ i=0
+ while [ $i -lt $iterations ]
+ do
+ if [ $pagecached == false ]; then
+ adb shell 'echo 3 > /proc/sys/vm/drop_caches'
+ fi
+ # The -W argument to am start forces am start to wait till the launch completes.
+ # The -S argument forces it to kill any existing app that is running first
+ # eg. adb shell 'am start -W -S -n com.android.chrome/com.google.android.apps.chrome.Main'
+ system_stats_before
+ adb shell "simpleperf stat -a am start -W -n $package/$activity"
+ system_stats_after
+ system_stats_delta
+ sleep 1
+ adb shell "am force-stop $package"
+ sleep 1
+ i=`expr $i + 1`
+ done
+}
+
+launch_fugu_apps() {
+ launch_app com.google.android.youtube.tv com.google.android.apps.youtube.tv.activity.TvGuideActivity > youtube-$model
+ getstats youtube-$model YouTube
+ launch_app com.google.android.play.games com.google.android.gms.games.pano.activity.PanoGamesOnboardHostActivity > games-$model
+ getstats games-$model Games
+ launch_app com.google.android.music com.android.music.activitymanagement.TopLevelActivity > music-$model
+ getstats music-$model Music
+}
+
+launch_phone_apps() {
+ launch_app com.android.chrome com.google.android.apps.chrome.Main > chrome-$model
+ getstats chrome-$model Chrome
+ launch_app com.google.android.GoogleCamera com.android.camera.CameraActivity > camera-$model
+ getstats camera-$model Camera
+ launch_app com.google.android.apps.maps com.google.android.maps.MapsActivity > maps-$model
+ getstats maps-$model Maps
+# launch_app com.google.android.youtube com.google.android.apps.youtube.app.WatchWhileActivity > youtube-$model
+# getstats youtube-$model YouTube
+}
+
+usage() {
+ echo 'Usage: app-launcher [-c|-v] -a|-b|-u num-iterations'
+ echo 'where num-iterations >= 100'
+ echo '-v (optional) for verbose stats dump'
+ echo '-a|-b|-u required:'
+ echo ' -a:all cores'
+ echo ' -b:only big cores'
+ echo ' -c:pagecached. Do not drop pagecache before each launch (not default)'
+ echo ' -h:Dump this help menu'
+ echo ' -u:user experience, no change to cpu/gpu frequencies or governors'
+ echo ' -a/-b locks CPU/GPU freqs to max, performance governor, thermal/perfd off'
+ echo ' -u runs with default device configs, as users would see it'
+ exit 1
+}
+
+#
+# The main() part of the script follows :
+#
+
+if [ $# -lt 2 ]; then
+ usage
+fi
+
+which computestats > /dev/null
+if [ $? != 0 ]; then
+ echo "ERROR: Please add computestats utiliy to your PATH"
+ exit 1
+fi
+
+which computestatsf > /dev/null
+if [ $? != 0 ]; then
+ echo "Error: Please add computestatsf utility to your PATH"
+ exit 1
+fi
+
+parseoptions $@
+
+adb root && sleep 2
+
+if [ $user_experience == false ]; then
+ # Important to stop the thermal-engine to prevent throttling while test is running
+ # and stop perfd
+ adb shell 'stop thermal-engine'
+ adb shell 'stop perfd'
+else
+ echo "User Experience: Default Configs. No changes to cpufreq settings"
+fi
+
+model=`adb shell getprop ro.product.name`
+# Releases are inconsistent with various trailing characters, remove them all
+model=`echo $model | sed 's/[ \t\r\n]*$//' `
+
+echo Found $model Device
+
+system_bdev_set=false
+case $model in
+ marlin | sailfish)
+ if [ $user_experience == false ]; then
+ cpufreq_marlin_sailfish
+ fi
+ get_marlin_sailfish_devnames
+ ;;
+ angler)
+ if [ $user_experience == false ]; then
+ cpufreq_angler
+ fi
+ get_angler_devnames
+ ;;
+ fugu)
+ if [ $user_experience == false ]; then
+ cpufreq_fugu
+ fi
+ get_fugu_devnames
+ ;;
+ volantis | volantisg)
+ if [ $user_experience == false ]; then
+ cpufreq_volantis
+ fi
+ get_volantis_devnames
+ ;;
+ *)
+ echo Unknown Device $model
+ exit 1
+ ;;
+esac
+
+
+#
+# launch each app in turn
+#
+if [ $model == "fugu" ]; then
+ launch_fugu_apps
+else # Phone Apps
+ launch_phone_apps
+fi
diff --git a/app-launcher/computestats.c b/app-launcher/computestats.c
new file mode 100644
index 00000000..e081e06f
--- /dev/null
+++ b/app-launcher/computestats.c
@@ -0,0 +1,118 @@
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <stdio.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/mman.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <math.h>
+
+char *pname;
+char *in_file;
+
+#define DATA_COUNT (1024*1024)
+u_int64_t data_items[DATA_COUNT];
+
+int num_data_items = 0;
+
+#define BUFSIZE 1024
+char in_buf[BUFSIZE];
+
+static int
+compare_long(const void *p1, const void *p2)
+{
+ u_int64_t val1 = *(u_int64_t *)p1;
+ u_int64_t val2 = *(u_int64_t *)p2;
+
+ if (val1 == val2)
+ return 0;
+ if (val1 < val2)
+ return -1;
+ return 1;
+}
+
+int
+main(int argc, char **argv)
+{
+ FILE *in_fp;
+ u_int64_t sum_x = 0;
+ u_int64_t sum_sq_x = 0;
+ u_int64_t mean;
+ double std_dev;
+ int i;
+ int one_sd = 0;
+ int two_sd = 0;
+ int three_sd = 0;
+ double one_sd_low, one_sd_high;
+ double two_sd_low, two_sd_high;
+ double three_sd_low, three_sd_high;
+
+ pname = argv[0];
+ if (argc == 1)
+ in_fp = stdin;
+ else {
+ in_file = argv[1];
+ in_fp = fopen(in_file, "r");
+ }
+ while (fgets(in_buf, BUFSIZE, in_fp)) {
+ if (num_data_items == DATA_COUNT) {
+ fprintf(stderr,
+ "DATA overflow, increase size of data_items array\n");
+ exit(1);
+ }
+ sscanf(in_buf, "%ju", &data_items[num_data_items]);
+#if 0
+ printf("%lu\n", data_items[num_data_items++]);
+#endif
+ num_data_items++;
+ }
+ if (num_data_items == 0) {
+ fprintf(stderr, "Empty input file ?\n");
+ exit(1);
+ }
+#if 0
+ printf("Total items %lu\n", num_data_items);
+#endif
+ for (i = 0 ; i < num_data_items ; i++) {
+ sum_x += data_items[i];
+ sum_sq_x += data_items[i] * data_items[i];
+ }
+ mean = sum_x / num_data_items;
+ printf("\tMean %lu\n", mean);
+ std_dev = sqrt((sum_sq_x / num_data_items) - (mean * mean));
+ printf("\tStd Dev %.2f (%.2f%% of mean)\n",
+ std_dev, (std_dev * 100.0) / mean);
+ one_sd_low = mean - std_dev;
+ one_sd_high = mean + std_dev;
+ two_sd_low = mean - (2 * std_dev);
+ two_sd_high = mean + (2 * std_dev);
+ three_sd_low = mean - (3 * std_dev);
+ three_sd_high = mean + (3 * std_dev);
+ for (i = 0 ; i < num_data_items ; i++) {
+ if (data_items[i] >= one_sd_low &&
+ data_items[i] <= one_sd_high)
+ one_sd++;
+ if (data_items[i] >= two_sd_low &&
+ data_items[i] <= two_sd_high)
+ two_sd++;
+ if (data_items[i] >= three_sd_low &&
+ data_items[i] <= three_sd_high)
+ three_sd++;
+ }
+ printf("\tWithin 1 SD %.2f%%\n",
+ ((double)one_sd * 100) / num_data_items);
+ printf("\tWithin 2 SD %.2f%%\n",
+ ((double)two_sd * 100) / num_data_items);
+ printf("\tWithin 3 SD %.2f%%\n",
+ ((double)three_sd* 100) / num_data_items);
+ printf("\tOutside 3 SD %.2f%%\n",
+ ((double)(num_data_items - three_sd) * 100) / num_data_items);
+ /* Sort the data to get percentiles */
+ qsort(data_items, num_data_items, sizeof(u_int64_t), compare_long);
+ printf("\t50th percentile %lu\n", data_items[num_data_items / 2]);
+ printf("\t75th percentile %lu\n", data_items[(3 * num_data_items) / 4]);
+ printf("\t90th percentile %lu\n", data_items[(9 * num_data_items) / 10]);
+ printf("\t99th percentile %lu\n", data_items[(99 * num_data_items) / 100]);
+}
+
diff --git a/app-launcher/computestatsf.c b/app-launcher/computestatsf.c
new file mode 100644
index 00000000..2ec0b9dd
--- /dev/null
+++ b/app-launcher/computestatsf.c
@@ -0,0 +1,118 @@
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <stdio.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/mman.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <math.h>
+
+char *pname;
+char *in_file;
+
+#define DATA_COUNT (1024*1024)
+double data_items[DATA_COUNT];
+
+int num_data_items = 0;
+
+#define BUFSIZE 1024
+char in_buf[BUFSIZE];
+
+static int
+compare_double(const void *p1, const void *p2)
+{
+ double val1 = *(u_int64_t *)p1;
+ double val2 = *(u_int64_t *)p2;
+
+ if (val1 == val2)
+ return 0;
+ if (val1 < val2)
+ return -1;
+ return 1;
+}
+
+int
+main(int argc, char **argv)
+{
+ FILE *in_fp;
+ double sum_x = 0;
+ double sum_sq_x = 0;
+ double mean;
+ double std_dev;
+ int i;
+ int one_sd = 0;
+ int two_sd = 0;
+ int three_sd = 0;
+ double one_sd_low, one_sd_high;
+ double two_sd_low, two_sd_high;
+ double three_sd_low, three_sd_high;
+
+ pname = argv[0];
+ if (argc == 1)
+ in_fp = stdin;
+ else {
+ in_file = argv[1];
+ in_fp = fopen(in_file, "r");
+ }
+ while (fgets(in_buf, BUFSIZE, in_fp)) {
+ if (num_data_items == DATA_COUNT) {
+ fprintf(stderr,
+ "DATA overflow, increase size of data_items array\n");
+ exit(1);
+ }
+ sscanf(in_buf, "%lf", &data_items[num_data_items]);
+#if 0
+ printf("%lf\n", data_items[num_data_items]);
+#endif
+ num_data_items++;
+ }
+ if (num_data_items == 0) {
+ fprintf(stderr, "Empty input file ?\n");
+ exit(1);
+ }
+#if 0
+ printf("Total items %lu\n", num_data_items);
+#endif
+ for (i = 0 ; i < num_data_items ; i++) {
+ sum_x += data_items[i];
+ sum_sq_x += data_items[i] * data_items[i];
+ }
+ mean = sum_x / num_data_items;
+ printf("\tMean %.4f\n", mean);
+ std_dev = sqrt((sum_sq_x / num_data_items) - (mean * mean));
+ printf("\tStd Dev %.4f (%.4f%% of mean)\n",
+ std_dev, (std_dev * 100.0) / mean);
+ one_sd_low = mean - std_dev;
+ one_sd_high = mean + std_dev;
+ two_sd_low = mean - (2 * std_dev);
+ two_sd_high = mean + (2 * std_dev);
+ three_sd_low = mean - (3 * std_dev);
+ three_sd_high = mean + (3 * std_dev);
+ for (i = 0 ; i < num_data_items ; i++) {
+ if (data_items[i] >= one_sd_low &&
+ data_items[i] <= one_sd_high)
+ one_sd++;
+ if (data_items[i] >= two_sd_low &&
+ data_items[i] <= two_sd_high)
+ two_sd++;
+ if (data_items[i] >= three_sd_low &&
+ data_items[i] <= three_sd_high)
+ three_sd++;
+ }
+ printf("\tWithin 1 SD %.2f%%\n",
+ ((double)one_sd * 100) / num_data_items);
+ printf("\tWithin 2 SD %.2f%%\n",
+ ((double)two_sd * 100) / num_data_items);
+ printf("\tWithin 3 SD %.2f%%\n",
+ ((double)three_sd* 100) / num_data_items);
+ printf("\tOutside 3 SD %.2f%%\n",
+ ((double)(num_data_items - three_sd) * 100) / num_data_items);
+ /* Sort the data to get percentiles */
+ qsort(data_items, num_data_items, sizeof(u_int64_t), compare_double);
+ printf("\t50th percentile %lf\n", data_items[num_data_items / 2]);
+ printf("\t75th percentile %lf\n", data_items[(3 * num_data_items) / 4]);
+ printf("\t90th percentile %lf\n", data_items[(9 * num_data_items) / 10]);
+ printf("\t99th percentile %lf\n", data_items[(99 * num_data_items) / 100]);
+}
+