diff options
| author | SzuWei Lin <szuweilin@google.com> | 2017-01-24 16:11:32 +0800 |
|---|---|---|
| committer | SzuWei Lin <szuweilin@google.com> | 2017-03-07 18:09:26 +0800 |
| commit | 2dcb17e2252b17f56e1793bcf6ac479dc6e48319 (patch) | |
| tree | f09e4b4034e6d85d38771bf18e6cc3a863cdce3d | |
| parent | 169cf6923d84170c383b0e8e720690bd75908a9f (diff) | |
| download | platform_system_libufdt-2dcb17e2252b17f56e1793bcf6ac479dc6e48319.tar.gz platform_system_libufdt-2dcb17e2252b17f56e1793bcf6ac479dc6e48319.tar.bz2 platform_system_libufdt-2dcb17e2252b17f56e1793bcf6ac479dc6e48319.zip | |
Add a performance testing script
To test the DTO performance in different platform. Add a DTS test case
generator and a script to test different cases. Also modify the test
script that's able to upload executable and test cases to devices with
adb, and run the performance test cases on devices.
Bug: 33825009
Test: tests/run_performance_test.sh
Change-Id: I660b613237a86cb17f571ffc488c29e0e8b95ed6
| -rwxr-xr-x | tests/apply_overlay.sh | 43 | ||||
| -rwxr-xr-x | tests/run_performance_test.sh | 117 | ||||
| -rw-r--r-- | tests/src/Android.mk | 36 | ||||
| -rw-r--r-- | tests/src/ufdt_gen_test_dts.c | 194 |
4 files changed, 385 insertions, 5 deletions
diff --git a/tests/apply_overlay.sh b/tests/apply_overlay.sh index 943613f..8f23a41 100755 --- a/tests/apply_overlay.sh +++ b/tests/apply_overlay.sh @@ -4,7 +4,7 @@ PROG_NAME=`basename $0` function usage() { echo "Usage:" - echo " $PROG_NAME (--fdt|--ufdt) <Base DTS> <Overlay DTS> <Output DTS>" + echo " $PROG_NAME (--fdt|--ufdt) (--remote) <Base DTS> <Overlay DTS> <Output DTS>" } function on_exit() { @@ -27,6 +27,15 @@ else exit 1 fi +# --remote: run overlay on the device with adb +if [ "$1" == "--remote" ]; then + shift + EXE_PATH="${ANDROID_PRODUCT_OUT}/obj/EXECUTABLES" + REMOTE_PATH="/data/local/tmp" + adb push "${EXE_PATH}/${OVERLAY}_intermediates/${OVERLAY}" \ + "$REMOTE_PATH" > /dev/null +fi + if [[ $# -lt 3 ]]; then usage exit 1 @@ -43,18 +52,42 @@ trap on_exit EXIT # Compile the *-base.dts to make *-base.dtb BASE_DTS_NAME=`basename "$BASE_DTS"` -BASE_DTB="$TEMP_DIR/${BASE_DTS_NAME}-base.dtb" +BASE_DTB_NAME="${BASE_DTS_NAME}-base.dtb" +BASE_DTB="${TEMP_DIR}/${BASE_DTB_NAME}" dtc -@ -qq -O dtb -o "$BASE_DTB" "$BASE_DTS" # Compile the *-overlay.dts to make *-overlay.dtb OVERLAY_DTS_NAME=`basename "$OVERLAY_DTS"` -OVERLAY_DTB="$TEMP_DIR/${OVERLAY_DTS_NAME}-overlay.dtb" +OVERLAY_DTB_NAME="${OVERLAY_DTS_NAME}-overlay.dtb" +OVERLAY_DTB="${TEMP_DIR}/${OVERLAY_DTB_NAME}" dtc -@ -qq -O dtb -o "$OVERLAY_DTB" "$OVERLAY_DTS" # Run ufdt_apply_overlay to combine *-base.dtb and *-overlay.dtb # into *-merged.dtb -MERGED_DTB="$TEMP_DIR/${BASE_DTS_NAME}-merged.dtb" -"$OVERLAY" "$BASE_DTB" "$OVERLAY_DTB" "$MERGED_DTB" +MERGED_DTB_NAME="${BASE_DTS_NAME}-merged.dtb" +MERGED_DTB="${TEMP_DIR}/${MERGED_DTB_NAME}" +if [ -z "$REMOTE_PATH" ]; then + "$OVERLAY" "$BASE_DTB" "$OVERLAY_DTB" "$MERGED_DTB" +else + adb push "$BASE_DTB" "$REMOTE_PATH" > /dev/null + adb push "$OVERLAY_DTB" "$REMOTE_PATH" > /dev/null + adb shell " + cd "$REMOTE_PATH" && + "./${OVERLAY}" "$BASE_DTB_NAME" "$OVERLAY_DTB_NAME" "$MERGED_DTB_NAME" + " + adb pull "${REMOTE_PATH}/${MERGED_DTB_NAME}" "$MERGED_DTB" > /dev/null +fi + +if [ ! -z "$REMOTE_PATH" ]; then + # clean up + adb shell " + cd "$REMOTE_PATH" && + rm -f "$OVERLAY" && + rm -f "$BASE_DTB_NAME" && + rm -f "$OVERLAY_DTB_NAME" && + rm -f "$MERGED_DTB_NAME" + " > /dev/null +fi # Dump dtc -s -O dts -o "$OUT_DTS" "$MERGED_DTB" diff --git a/tests/run_performance_test.sh b/tests/run_performance_test.sh new file mode 100755 index 0000000..3cfc1ed --- /dev/null +++ b/tests/run_performance_test.sh @@ -0,0 +1,117 @@ +#!/bin/bash + +# Include some functions from common.sh. +SCRIPT_DIR="$(dirname "$(readlink -f "$0")")" +source ${SCRIPT_DIR}/common.sh + +OUT_DATA_DIR="test_out" + +# Disable REMOTE for test on local +REMOTE="--remote" + +TEST_COUNT=10 +DEBUG=false + + +apply_overlay() { + local overaly="$1" + local base_dts="$2" + local overlay_dts="$3" + local merged_dts="$4" + + local summary=0 + for i in $(seq 1 $TEST_COUNT); do + TIME=$(./apply_overlay.sh "--$overaly" $REMOTE \ + "$base_dts" "$overlay_dts" "$merged_dts" \ + | sed -E "s/.*took ([0-9]+\\.[0-9]+) secs/\\1/") + if $DEBUG; then + echo "time=$TIME" + fi + summary=$(echo "$summary + $TIME" | bc -l) + done + AVERAY=$(echo "scale=9; $summary/$TEST_COUNT" | bc -l) + printf "%10s Average time=%s\n" "($overaly)" "$AVERAY" +} + +run_performance_test() { + # see ufdt_gen_test_dts.c for detail + local node_depth="$1" + local node_unused="$2" + local node_count="$3" + local append_count="$4" + local override_count="$5" + + mkdir -p "$OUT_DATA_DIR" >& /dev/null + + # + # Prepare dtb and dtbo files + # + local base_dts="${OUT_DATA_DIR}/base.dts" + echo " Base DT: depth=$node_depth unused=$node_unused nodes=$node_count" + ufdt_gen_test_dts -n $node_count -d $node_depth -u $node_unused \ + -o "$base_dts" + if $DEBUG; then + cat "$base_dts" + fi + + local overlay_dts="${OUT_DATA_DIR}/overlay.dts" + echo " Overlay DT: append=$append_count override=$override_count" + ufdt_gen_test_dts -p -a $append_count -w $override_count \ + -o "$overlay_dts" + if $DEBUG; then + cat "$overlay_dts" + fi + + local merged_dts="${OUT_DATA_DIR}/overlay_merged.dts" + apply_overlay fdt $base_dts $overlay_dts $merged_dts + apply_overlay ufdt $base_dts $overlay_dts $merged_dts + + rm -rf "$OUT_DATA_DIR" +} + +main() { + alert "========== Running Performance Tests ==========" + + if [ -z "$ANDROID_BUILD_TOP" ]; then + die "Run envsetup.sh / lunch yet?" + fi + + if ! command_exists ufdt_gen_test_dts || + ! command_exists dtc; then + die "Run mmma $(dirname $SCRIPT_DIR) yet?" + fi + + if [ "$REMOTE" == "--remote" ]; then + adb get-state > /dev/null + if [ "$?" -ne "0" ]; then + die "adb can not connect to device." + fi + fi + + # cd to ${SCRIPT_DIR} in a subshell because gen_test.sh uses relative + # paths for dependent files. + cd "${SCRIPT_DIR}" + + # + # run_performance_test + # <node_depth> <node_unused> <node_count> <append_count> <override_count> + + # Test case #1: node=x append=100 override=100 + for t in $(seq 200 50 1000); do + run_performance_test 2 0 $t 100 100 + done + # Test case #2: node=x append=100 override=100 + for t in $(seq 200 50 1000); do + run_performance_test 2 $t $t 100 100 + done + # Test case #3: node=2000 append=X + for t in $(seq 50 50 1000); do + run_performance_test 2 0 2000 $t 0 + done + # Test case #4: node=2000 override=X + for t in $(seq 50 50 1000); do + run_performance_test 2 0 2000 0 $t + done +} + +main "$@" diff --git a/tests/src/Android.mk b/tests/src/Android.mk index adac198..bfd5c52 100644 --- a/tests/src/Android.mk +++ b/tests/src/Android.mk @@ -6,6 +6,15 @@ LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) +LOCAL_MODULE := ufdt_gen_test_dts +LOCAL_SRC_FILES := ufdt_gen_test_dts.c + +include $(BUILD_HOST_EXECUTABLE) + +################################################### + +include $(CLEAR_VARS) + LOCAL_MODULE := ufdt_apply_overlay LOCAL_SRC_FILES := ufdt_overlay_test_app.c util.c LOCAL_STATIC_LIBRARIES := \ @@ -20,6 +29,20 @@ include $(BUILD_HOST_EXECUTABLE) include $(CLEAR_VARS) +LOCAL_MODULE := ufdt_apply_overlay +LOCAL_SRC_FILES := ufdt_overlay_test_app.c util.c +LOCAL_STATIC_LIBRARIES := \ + libufdt \ + libfdt \ + libufdt_sysdeps +LOCAL_REQUIRED_MODULES := dtc + +include $(BUILD_EXECUTABLE) + +################################################### + +include $(CLEAR_VARS) + LOCAL_MODULE := fdt_apply_overlay LOCAL_SRC_FILES := fdt_overlay_test_app.c util.c LOCAL_STATIC_LIBRARIES := \ @@ -43,3 +66,16 @@ LOCAL_REQUIRED_MODULES := dtc include $(BUILD_HOST_EXECUTABLE) ################################################### + +include $(CLEAR_VARS) + +LOCAL_MODULE := fdt_apply_overlay +LOCAL_SRC_FILES := fdt_overlay_test_app.c util.c +LOCAL_STATIC_LIBRARIES := \ + libfdt \ + libufdt_sysdeps +LOCAL_REQUIRED_MODULES := dtc + +include $(BUILD_EXECUTABLE) + +################################################### diff --git a/tests/src/ufdt_gen_test_dts.c b/tests/src/ufdt_gen_test_dts.c new file mode 100644 index 0000000..8f0a27f --- /dev/null +++ b/tests/src/ufdt_gen_test_dts.c @@ -0,0 +1,194 @@ +#include <getopt.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +/* + * The parameters to generate testing DTS + * /dts-v1/ /plugin/; <- header and plugin + * /{ + * level0 { <- depth + * level1 { + * ... + * node0: node0 { <- node + * unused0 {} <- unused + * unused1 {} + * ... + * status="disabled"; + * } + * ... + * }; + * }; + * }; + * + * &node0 { <- append + * new_prop="foo"; + * } + * ... + * + * &node0 { <- override + * status="okay"; + * } + * ... + */ + +static const char short_options[] = "Hpd:u:n:a:w:o:"; +static struct option long_options[] = { + { "no-header", no_argument, NULL, 'H' }, + { "plugin", no_argument, NULL, 'p' }, + { "depth", required_argument, NULL, 'd' }, + { "unused", required_argument, NULL, 'u' }, + { "node", required_argument, NULL, 'n' }, + { "append", required_argument, NULL, 'a' }, + { "override", required_argument, NULL, 'w' }, + { "output", required_argument, NULL, 'o' }, + { 0, 0, NULL, 0 } +}; + +struct gen_params { + int no_header; /* Doesn't add header */ + int plugin; /* Add /plugin/ in header */ + int depth; /* the depth of a node, 0 means generate on root node */ + int unused_num; /* unused child nodes per node */ + int node_num; /* the number to generate nodes */ + int append_num; /* the number to generate appending references */ + int override_num; /* the number to generate overriding references */ +}; + + +static void output_header(FILE *fp, int is_plugin) { + fprintf(fp, "/dts-v1/;\n"); + if (is_plugin) { + fprintf(fp, "/plugin/;\n"); + } + fprintf(fp, "\n"); +} + +static void output_root_begin(FILE *fp, int depth) { + fprintf(fp, "/ {\n"); + + int i; + for (i = 0; i < depth; i++) { + fprintf(fp, "level%d {\n", i); + } +} + +static void output_root_end(FILE *fp, int depth) { + int i; + for (i = 0; i < depth; i++) { + fprintf(fp, "};\n"); + } + + fprintf(fp, "};\n\n"); +} + +static void output_unused_nodes(FILE *fp, int count) { + int i; + for (i = 0; i < count; i++) { + fprintf(fp, "unused%d {};\n", i); + } +} + +static void output_prop_str(FILE *fp, const char *prop, const char *value) { + /* TODO: should escape value */ + fprintf(fp, "%s=\"%s\";\n", prop, value); +} + +static void output_nodes(FILE *fp, int count, const char *prop, const char *value) { + int i; + for (i = 0; i < count; i++) { + fprintf(fp, "node%d: node%d {\n", i, i); + output_prop_str(fp, prop, value); + fprintf(fp, "};\n\n"); + } +} + +static void output_ref_nodes(FILE *fp, int start_id, int count, + const char *prop, const char *value) { + int i; + for (i = start_id; i < start_id + count; i++) { + fprintf(fp, "&node%d {\n", i); + output_prop_str(fp, prop, value); + fprintf(fp, "};\n\n"); + } +} + +static int gen_dts(FILE *fp, const struct gen_params *params) { + if (!params->no_header) { + output_header(fp, params->plugin); + } + + if (params->node_num > 0) { + output_root_begin(fp, params->depth); + output_unused_nodes(fp, params->unused_num); + output_nodes(fp, params->node_num, "status", "disabled"); + output_root_end(fp, params->depth); + } + + int start_id = 0; + output_ref_nodes(fp, start_id, params->append_num, "new_prop", "bar"); + start_id += params->append_num; + output_ref_nodes(fp, start_id, params->override_num, "status", "okay"); + + return 0; +} + +int main(int argc, char *argv[]) { + const char *filename = NULL; + struct gen_params params; + memset(¶ms, 0, sizeof(struct gen_params)); + + while (1) { + int option_index = 0; + int c = getopt_long(argc, argv, short_options, long_options, &option_index); + if (c == -1) { + break; + } + switch (c) { + case 'H': + params.no_header = 1; + break; + case 'p': + params.plugin = 1; + break; + case 'd': + params.depth = atoi(optarg); + break; + case 'u': + params.unused_num = atoi(optarg); + break; + case 'n': + params.node_num = atoi(optarg); + break; + case 'a': + params.append_num = atoi(optarg); + break; + case 'w': + params.override_num = atoi(optarg); + break; + case 'o': + filename = optarg; + break; + case '?': + break; + } + } + + FILE *fp = NULL; + if (filename) { + fp = fopen(filename, "wt"); + if (fp == NULL) { + fprintf(stderr, "Can not create file: ", filename); + return -1; + } + } + + gen_dts(fp ? fp : stdout, ¶ms); + + if (fp) { + fclose(fp); + } + + return 0; +} |
