summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSzuWei Lin <szuweilin@google.com>2017-01-24 16:11:32 +0800
committerSzuWei Lin <szuweilin@google.com>2017-03-07 18:09:26 +0800
commit2dcb17e2252b17f56e1793bcf6ac479dc6e48319 (patch)
treef09e4b4034e6d85d38771bf18e6cc3a863cdce3d
parent169cf6923d84170c383b0e8e720690bd75908a9f (diff)
downloadplatform_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-xtests/apply_overlay.sh43
-rwxr-xr-xtests/run_performance_test.sh117
-rw-r--r--tests/src/Android.mk36
-rw-r--r--tests/src/ufdt_gen_test_dts.c194
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(&params, 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, &params);
+
+ if (fp) {
+ fclose(fp);
+ }
+
+ return 0;
+}