This test program increase the frequency for each cpu and launch the cpucycle 
program.

A computation is made to check the deviation of the ratio (counter / frequency) 
is
consistent between the frequencies.

More informations can be found at:

https://wiki.linaro.org/WorkingGroups/PowerManagement/Doc/QA/Scripts#test_06

Signed-off-by: Daniel Lezcano <daniel.lezc...@linaro.org>
---
 cpufreq/test_06.sh |  236 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 utils/Makefile     |   14 +---
 utils/cpucycle.c   |  102 ++++++++++++++++++++++
 3 files changed, 341 insertions(+), 11 deletions(-)
 create mode 100644 cpufreq/test_06.sh
 create mode 100644 utils/cpucycle.c

diff --git a/cpufreq/test_06.sh b/cpufreq/test_06.sh
new file mode 100644
index 0000000..e12487f
--- /dev/null
+++ b/cpufreq/test_06.sh
@@ -0,0 +1,236 @@
+#!/bin/bash
+#/*******************************************************************************
+# Copyright (C) 2011, Linaro Limited.
+#
+# This file is part of PM QA.
+#
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#
+# Contributors:
+#     Daniel Lezcano <daniel.lezc...@linaro.org> (IBM Corporation)
+#       - initial API and implementation
+#******************************************************************************/
+
+# URL : 
https://wiki.linaro.org/WorkingGroups/PowerManagement/Doc/QA/Scripts#test_06
+CPU_PATH="/sys/devices/system/cpu"
+CPUCYCLE=../utils/cpucycle
+oldfreqs=
+oldgovs=
+
+save_frequencies() {
+    index=0
+    for i in $(ls $CPU_PATH | grep "cpu[0-9].*"); do
+       printf "%-70s" "saving frequency for $i ... "
+       oldfreqs[$index]=$(cat $CPU_PATH/$i/cpufreq/scaling_cur_speed)
+       printf "DONE\n"
+       index=$((index + 1))
+    done
+}
+
+restore_frequencies() {
+    index=0
+    for i in $(ls $CPU_PATH | grep "cpu[0-9].*"); do
+       oldfreq=${oldfreqs[$index]}
+       printf "%-70s" "restoring frequency '$oldfreq' for $i ... "
+       echo $oldfreq > $CPU_PATH/$i/cpufreq/scaling_setspeed
+       printf "DONE\n"
+       index=$((index + 1))
+    done
+}
+
+save_governors() {
+    index=0
+    for i in $(ls $CPU_PATH | grep "cpu[0-9].*"); do
+       printf "%-70s" "saving governor for $i ... "
+       oldgovs[$index]=$(cat $CPU_PATH/$i/cpufreq/scaling_governor)
+       printf "DONE\n"
+       index=$((index + 1))
+    done
+}
+
+restore_governors() {
+    index=0
+    for i in $(ls $CPU_PATH | grep "cpu[0-9].*"); do
+       oldgov=${oldgovs[$index]}
+       printf "%-70s" "restoring governor '$oldgov' for $i ... "
+       echo $oldgov > $CPU_PATH/$i/cpufreq/scaling_governor
+       printf "DONE\n"
+       index=$((index + 1))
+    done
+}
+
+switch_governor() {
+
+    newgov=$2
+    oldgov=$(cat $1/scaling_governor)
+
+    printf "%-70s" "setting governor to '$newgov' ... "
+    echo $newgov > $1/scaling_governor
+    curgov=$(cat $1/scaling_governor)
+    if [ "$curgov" != "$newgov" ]; then
+       printf "FAIL\n"
+       echo $oldgov >  $1/scaling_governor
+       return 1
+    fi
+
+    printf "PASS\n"
+
+    return 0
+}
+
+check_frequency_perf() {
+
+    frequencies=$(cat $1/scaling_available_frequencies)
+    index=0
+    cpu=$2
+
+    # for each frequency check a change of performances
+    for i in $frequencies; do
+
+       switch_frequency $1 $i || return 1
+
+       printf "%-70s" "running 'cpucycle' on $cpu at '$i' KHz ... "
+
+       result=$($CPUCYCLE $cpu)
+       if [ $? != 0 ]; then
+           printf "FAIL\n"
+           return 1
+       fi
+
+       printf "PASS\n"
+
+       results[$index]=$(echo "scale=3;($result / $i)" | bc -l)
+       index=$((index + 1))
+
+    done
+
+    index=0
+    sum=0
+
+    for i in $frequencies; do
+       res=${results[$index]}
+       sum=$(echo "($sum + $res)" | bc -l)
+       index=$((index + 1))
+    done
+
+    avg=$(echo "scale=3;($sum / $index)" | bc -l)
+
+    index=0
+
+    for i in $frequencies; do
+
+       res=${results[$index]}
+
+       # compute deviation
+       dev=$(echo "scale=3;((( $res - $avg ) / $avg) * 100 )" | bc -l)
+
+       # change to absolute
+       dev=$(echo $dev | awk '{ print ($1 >= 0) ? $1 : 0 - $1}')
+
+       index=$((index + 1))
+
+       printf "%-70s" "deviation $dev % for $i is ... "
+
+       res=$(echo "($dev <= 0.5)" | bc -l)
+       if [ "$res" = "1" ]; then
+           printf "VERY GOOD\n"
+           continue
+       fi
+
+       res=$(echo "($dev <= 1.0)" | bc -l)
+       if [ "$res" = "1" ]; then
+           printf "GOOD\n"
+           continue
+       fi
+
+       res=$(echo "($dev <= 2.0)" | bc -l)
+       if [ "$res" = "1" ]; then
+           printf "BAD\n"
+           continue
+       fi
+
+       res=$(echo "($dev <= 5.0)" | bc -l)
+       if [ "$res" = "1" ]; then
+           printf "VERY BAD\n"
+           continue
+       fi
+
+       res=$(echo "($dev <= 6.0)" | bc -l)
+       if [ "$res" = "1" ]; then
+           printf "SUSPECT\n"
+           continue
+       fi
+
+       res=$(echo "($dev > 6.0)" | bc -l)
+       if [ "$res" = "1" ]; then
+           printf "BOGUS\n"
+           return 1
+       fi
+    done
+
+    return 0
+}
+
+switch_frequency() {
+
+    oldfreq=$(cat $1/scaling_cur_freq)
+    newfreq=$2
+
+    nrfreqs=$(cat $1/scaling_available_frequencies | wc -w)
+    latency=$(cat $1/cpuinfo_transition_latency)
+
+    printf "%-70s" "setting frequency to $2 KHz ... "
+    echo $2 > $1/scaling_setspeed
+
+    # wait the latency period
+    ../utils/nanosleep $((nrfreqs * latency))
+
+    curfreq=$(cat $1/scaling_cur_freq)
+    if [ "$curfreq" != "$2" ]; then
+       printf "FAIL\n"
+       echo $oldfreq > $1/scaling_setspeed
+       return 1
+    fi
+
+    printf "PASS\n"
+
+    return 0
+}
+
+exit_fail() {
+    restore_governors
+    exit 1
+}
+
+check_root() {
+
+    printf "%-70s" "checking if we are root ... "
+
+    if [ "$(id -u)" != "0" ]; then
+       printf "FAIL\n"
+       return 1
+    fi
+
+    printf "PASS\n"
+
+    return 0
+}
+
+check_root || exit 1
+
+save_governors || exit 1
+
+trap exit_fail SIGHUP SIGINT SIGTERM
+
+for i in $(ls $CPU_PATH | grep "cpu[0-9].*"); do
+
+    printf "for '$i':\n"
+    switch_governor $CPU_PATH/$i/cpufreq userspace || exit_fail
+    check_frequency_perf $CPU_PATH/$i/cpufreq $i || exit_fail
+
+done
+
+restore_governors || exit 1
diff --git a/utils/Makefile b/utils/Makefile
index ebe9856..b3e206c 100644
--- a/utils/Makefile
+++ b/utils/Makefile
@@ -1,19 +1,11 @@
 CFLAGS?=-g -Wall
 CC?=gcc
-EXEC=nanosleep
 SRC=$(wildcard *.c)
-OBJ= $(SRC:.c=.o)
+EXEC=$(SRC:%.c=%)
 
 check: $(EXEC)
 
-nanosleep: $(OBJ)
-       @$(CC) -o $@ $^ $(LDFLAGS)
-
-%.o: %.c
-       $(CC) -o $@ -c $< $(CFLAGS)
+all: $(EXEC)
 
 clean:
-       rm *.o
-
-mrproper: clean
-       rm $(EXEC)
+       rm -f *.o $(EXEC)
diff --git a/utils/cpucycle.c b/utils/cpucycle.c
new file mode 100644
index 0000000..e092c0a
--- /dev/null
+++ b/utils/cpucycle.c
@@ -0,0 +1,102 @@
+/*******************************************************************************
+ * Copyright (C) 2011, Linaro Limited.
+ *
+ * This file is part of PM QA
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Daniel Lezcano <daniel.lezc...@linaro.org> (IBM Corporation)
+ *       - initial API and implementation
+ 
*******************************************************************************/
+#define _GNU_SOURCE
+#include <sched.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdbool.h>
+#include <signal.h>
+#include <unistd.h>
+#include <regex.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/resource.h>
+
+static bool intr;
+
+void sigalarm(int sig)
+{
+       intr = true;
+}
+
+int main(int argc, char *argv[])
+{
+       regex_t reg;
+       const char *regex = "cpu[0-9].*";
+       char **aargv = NULL;
+       regmatch_t m[1];
+       cpu_set_t cpuset;
+       long counter = 0;
+       int i;
+
+       if (argc == 1) {
+               fprintf(stderr, "%s <cpuN> [cpuM] ... \n", argv[0]);
+               return 1;
+       }
+
+       aargv = &argv[1];
+
+       if (regcomp(&reg, regex, 0)) {
+               fprintf(stderr, "failed to compile the regex\n");
+               return 1;
+       }
+
+       CPU_ZERO(&cpuset);
+
+       for (i = 0; i < (argc - 1); i++) {
+
+               char *aux;
+               int cpu;
+
+               if (regexec(&reg, aargv[i], 1, m, 0)) {
+                       fprintf(stderr, "'%s' parameter not recognized, " \
+                               "should be cpu[0-9]\n", aargv[i]);
+                       return 1;
+               }
+
+               aux = aargv[i] + 3;
+               cpu = atoi(aux);
+
+               CPU_SET(cpu, &cpuset);
+       }
+
+       if (sched_setaffinity(0, sizeof(cpuset), &cpuset)) {
+               perror("sched_setaffinity");
+               return 1;
+       }
+
+       if (setpriority(PRIO_PROCESS, 0, -20) < 0) {
+               perror("setpriority");
+               return 1;
+       }
+
+       signal(SIGALRM, sigalarm);
+
+       alarm(1);
+       /* warmup */
+       for (; !intr ;)
+               counter++;
+
+       counter = 0;
+       intr = false;
+
+       alarm(1);
+       for (; !intr ;)
+               counter++;
+
+       printf("%ld\n", counter);
+
+       return 0;
+}
-- 
1.7.4.1


_______________________________________________
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev

Reply via email to