aboutsummaryrefslogtreecommitdiffstats
path: root/tools/power/cpupower/bench
diff options
context:
space:
mode:
Diffstat (limited to 'tools/power/cpupower/bench')
-rw-r--r--tools/power/cpupower/bench/Makefile30
-rw-r--r--tools/power/cpupower/bench/README-BENCH124
-rw-r--r--tools/power/cpupower/bench/benchmark.c184
-rw-r--r--tools/power/cpupower/bench/benchmark.h27
-rw-r--r--tools/power/cpupower/bench/config.h36
-rw-r--r--tools/power/cpupower/bench/cpufreq-bench_plot.sh104
-rw-r--r--tools/power/cpupower/bench/cpufreq-bench_script.sh101
-rw-r--r--tools/power/cpupower/bench/example.cfg11
-rw-r--r--tools/power/cpupower/bench/main.c203
-rw-r--r--tools/power/cpupower/bench/parse.c224
-rw-r--r--tools/power/cpupower/bench/parse.h50
-rw-r--r--tools/power/cpupower/bench/system.c188
-rw-r--r--tools/power/cpupower/bench/system.h29
13 files changed, 1311 insertions, 0 deletions
diff --git a/tools/power/cpupower/bench/Makefile b/tools/power/cpupower/bench/Makefile
new file mode 100644
index 00000000000..3d8fa21855f
--- /dev/null
+++ b/tools/power/cpupower/bench/Makefile
@@ -0,0 +1,30 @@
1LIBS = -L../ -lm -lcpufreq
2
3OBJS = main.o parse.o system.o benchmark.o
4CFLAGS += -D_GNU_SOURCE -I../lib -DDEFAULT_CONFIG_FILE=\"$(confdir)/cpufreq-bench.conf\"
5
6ifeq ($(strip $(V)),false)
7 CC=@../build/ccdv gcc
8else
9 CC=gcc
10endif
11
12cpufreq-bench: $(OBJS)
13 $(CC) -o $@ $(CFLAGS) $(OBJS) $(LIBS)
14
15all: cpufreq-bench
16
17install:
18 mkdir -p $(DESTDIR)/$(sbindir)
19 mkdir -p $(DESTDIR)/$(bindir)
20 mkdir -p $(DESTDIR)/$(docdir)
21 mkdir -p $(DESTDIR)/$(confdir)
22 install -m 755 cpufreq-bench $(DESTDIR)/$(sbindir)/cpufreq-bench
23 install -m 755 cpufreq-bench_plot.sh $(DESTDIR)/$(bindir)/cpufreq-bench_plot.sh
24 install -m 644 README-BENCH $(DESTDIR)/$(docdir)/README-BENCH
25 install -m 755 cpufreq-bench_script.sh $(DESTDIR)/$(docdir)/cpufreq-bench_script.sh
26 install -m 644 example.cfg $(DESTDIR)/$(confdir)/cpufreq-bench.conf
27
28clean:
29 rm -f *.o
30 rm -f cpufreq-bench
diff --git a/tools/power/cpupower/bench/README-BENCH b/tools/power/cpupower/bench/README-BENCH
new file mode 100644
index 00000000000..8093ec73817
--- /dev/null
+++ b/tools/power/cpupower/bench/README-BENCH
@@ -0,0 +1,124 @@
1This is cpufreq-bench, a microbenchmark for the cpufreq framework.
2
3Purpose
4=======
5
6What is this benchmark for:
7 - Identify worst case performance loss when doing dynamic frequency
8 scaling using Linux kernel governors
9 - Identify average reaction time of a governor to CPU load changes
10 - (Stress) Testing whether a cpufreq low level driver or governor works
11 as expected
12 - Identify cpufreq related performance regressions between kernels
13 - Possibly Real time priority testing? -> what happens if there are
14 processes with a higher prio than the governor's kernel thread
15 - ...
16
17What this benchmark does *not* cover:
18 - Power saving related regressions (In fact as better the performance
19 throughput is, the worse the power savings will be, but the first should
20 mostly count more...)
21 - Real world (workloads)
22
23
24Description
25===========
26
27cpufreq-bench helps to test the condition of a given cpufreq governor.
28For that purpose, it compares the performance governor to a configured
29powersave module.
30
31
32How it works
33============
34You can specify load (100% CPU load) and sleep (0% CPU load) times in us which
35will be run X time in a row (cycles):
36
37 sleep=25000
38 load=25000
39 cycles=20
40
41This part of the configuration file will create 25ms load/sleep turns,
42repeated 20 times.
43
44Adding this:
45 sleep_step=25000
46 load_step=25000
47 rounds=5
48Will increase load and sleep time by 25ms 5 times.
49Together you get following test:
5025ms load/sleep time repeated 20 times (cycles).
5150ms load/sleep time repeated 20 times (cycles).
52..
53100ms load/sleep time repeated 20 times (cycles).
54
55First it is calibrated how long a specific CPU intensive calculation
56takes on this machine and needs to be run in a loop using the performance
57governor.
58Then the above test runs are processed using the performance governor
59and the governor to test. The time the calculation really needed
60with the dynamic freq scaling governor is compared with the time needed
61on full performance and you get the overall performance loss.
62
63
64Example of expected results with ondemand governor:
65
66This shows expected results of the first two test run rounds from
67above config, you there have:
68
69100% CPU load (load) | 0 % CPU load (sleep) | round
70 25 ms | 25 ms | 1
71 50 ms | 50 ms | 2
72
73For example if ondemand governor is configured to have a 50ms
74sampling rate you get:
75
76In round 1, ondemand should have rather static 50% load and probably
77won't ever switch up (as long as up_threshold is above).
78
79In round 2, if the ondemand sampling times exactly match the load/sleep
80trigger of the cpufreq-bench, you will see no performance loss (compare with
81below possible ondemand sample kick ins (1)):
82
83But if ondemand always kicks in in the middle of the load sleep cycles, it
84will always see 50% loads and you get worst performance impact never
85switching up (compare with below possible ondemand sample kick ins (2))::
86
87 50 50 50 50ms ->time
88load -----| |-----| |-----| |-----|
89 | | | | | | |
90sleep |-----| |-----| |-----| |----
91 |-----|-----|-----|-----|-----|-----|-----|---- ondemand sampling (1)
92 100 0 100 0 100 0 100 load seen by ondemand(%)
93 |-----|-----|-----|-----|-----|-----|-----|-- ondemand sampling (2)
94 50 50 50 50 50 50 50 load seen by ondemand(%)
95
96You can easily test all kind of load/sleep times and check whether your
97governor in average behaves as expected.
98
99
100ToDo
101====
102
103Provide a gnuplot utility script for easy generation of plots to present
104the outcome nicely.
105
106
107cpufreq-bench Command Usage
108===========================
109-l, --load=<long int> initial load time in us
110-s, --sleep=<long int> initial sleep time in us
111-x, --load-step=<long int> time to be added to load time, in us
112-y, --sleep-step=<long int> time to be added to sleep time, in us
113-c, --cpu=<unsigned int> CPU Number to use, starting at 0
114-p, --prio=<priority> scheduler priority, HIGH, LOW or DEFAULT
115-g, --governor=<governor> cpufreq governor to test
116-n, --cycles=<int> load/sleep cycles to get an avarage value to compare
117-r, --rounds<int> load/sleep rounds
118-f, --file=<configfile> config file to use
119-o, --output=<dir> output dir, must exist
120-v, --verbose verbose output on/off
121
122Due to the high priority, the application may not be responsible for some time.
123After the benchmark, the logfile is saved in OUTPUTDIR/benchmark_TIMESTAMP.log
124
diff --git a/tools/power/cpupower/bench/benchmark.c b/tools/power/cpupower/bench/benchmark.c
new file mode 100644
index 00000000000..f538633b8b4
--- /dev/null
+++ b/tools/power/cpupower/bench/benchmark.c
@@ -0,0 +1,184 @@
1/* cpufreq-bench CPUFreq microbenchmark
2 *
3 * Copyright (C) 2008 Christian Kornacker <ckornacker@suse.de>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18 */
19
20#include <stdio.h>
21#include <unistd.h>
22#include <math.h>
23
24#include "config.h"
25#include "system.h"
26#include "benchmark.h"
27
28/* Print out progress if we log into a file */
29#define show_progress(total_time, progress_time) \
30if (config->output != stdout) { \
31 fprintf(stdout, "Progress: %02lu %%\r", \
32 (progress_time * 100) / total_time); \
33 fflush(stdout); \
34}
35
36/**
37 * compute how many rounds of calculation we should do
38 * to get the given load time
39 *
40 * @param load aimed load time in µs
41 *
42 * @retval rounds of calculation
43 **/
44
45unsigned int calculate_timespace(long load, struct config *config)
46{
47 int i;
48 long long now, then;
49 unsigned int estimated = GAUGECOUNT;
50 unsigned int rounds = 0;
51 unsigned int timed = 0;
52
53 if (config->verbose)
54 printf("calibrating load of %lius, please wait...\n", load);
55
56 /* get the initial calculation time for a specific number of rounds */
57 now = get_time();
58 ROUNDS(estimated);
59 then = get_time();
60
61 timed = (unsigned int)(then - now);
62
63 /* approximation of the wanted load time by comparing with the
64 * initial calculation time */
65 for (i= 0; i < 4; i++)
66 {
67 rounds = (unsigned int)(load * estimated / timed);
68 dprintf("calibrating with %u rounds\n", rounds);
69 now = get_time();
70 ROUNDS(rounds);
71 then = get_time();
72
73 timed = (unsigned int)(then - now);
74 estimated = rounds;
75 }
76 if (config->verbose)
77 printf("calibration done\n");
78
79 return estimated;
80}
81
82/**
83 * benchmark
84 * generates a specific sleep an load time with the performance
85 * governor and compares the used time for same calculations done
86 * with the configured powersave governor
87 *
88 * @param config config values for the benchmark
89 *
90 **/
91
92void start_benchmark(struct config *config)
93{
94 unsigned int _round, cycle;
95 long long now, then;
96 long sleep_time = 0, load_time = 0;
97 long performance_time = 0, powersave_time = 0;
98 unsigned int calculations;
99 unsigned long total_time = 0, progress_time = 0;
100
101 sleep_time = config->sleep;
102 load_time = config->load;
103
104 /* For the progress bar */
105 for (_round=1; _round <= config->rounds; _round++)
106 total_time += _round * (config->sleep + config->load);
107 total_time *= 2; /* powersave and performance cycles */
108
109 for (_round=0; _round < config->rounds; _round++) {
110 performance_time = 0LL;
111 powersave_time = 0LL;
112
113 show_progress(total_time, progress_time);
114
115 /* set the cpufreq governor to "performance" which disables
116 * P-State switching. */
117 if (set_cpufreq_governor("performance", config->cpu) != 0)
118 return;
119
120 /* calibrate the calculation time. the resulting calculation
121 * _rounds should produce a load which matches the configured
122 * load time */
123 calculations = calculate_timespace(load_time, config);
124
125 if (config->verbose)
126 printf("_round %i: doing %u cycles with %u calculations"
127 " for %lius\n", _round + 1, config->cycles,
128 calculations, load_time);
129
130 fprintf(config->output, "%u %li %li ",
131 _round, load_time, sleep_time);
132
133 if (config->verbose) {
134 printf("avarage: %lius, rps:%li\n", load_time / calculations, 1000000 * calculations / load_time);
135 }
136
137 /* do some sleep/load cycles with the performance governor */
138 for (cycle = 0; cycle < config->cycles; cycle++) {
139 now = get_time();
140 usleep(sleep_time);
141 ROUNDS(calculations);
142 then = get_time();
143 performance_time += then - now - sleep_time;
144 if (config->verbose)
145 printf("performance cycle took %lius, sleep: %lius, load: %lius, rounds: %u\n",
146 (long)(then - now), sleep_time, load_time, calculations);
147 }
148 fprintf(config->output, "%li ", performance_time / config->cycles);
149
150 progress_time += sleep_time + load_time;
151 show_progress(total_time, progress_time);
152
153 /* set the powersave governor which activates P-State switching
154 * again */
155 if (set_cpufreq_governor(config->governor, config->cpu) != 0)
156 return;
157
158 /* again, do some sleep/load cycles with the powersave governor */
159 for (cycle = 0; cycle < config->cycles; cycle++) {
160 now = get_time();
161 usleep(sleep_time);
162 ROUNDS(calculations);
163 then = get_time();
164 powersave_time += then - now - sleep_time;
165 if (config->verbose)
166 printf("powersave cycle took %lius, sleep: %lius, load: %lius, rounds: %u\n",
167 (long)(then - now), sleep_time, load_time, calculations);
168 }
169
170 progress_time += sleep_time + load_time;
171
172 /* compare the avarage sleep/load cycles */
173 fprintf(config->output, "%li ", powersave_time / config->cycles);
174 fprintf(config->output, "%.3f\n", performance_time * 100.0 / powersave_time);
175 fflush(config->output);
176
177 if (config->verbose)
178 printf("performance is at %.2f%%\n", performance_time * 100.0 / powersave_time);
179
180 sleep_time += config->sleep_step;
181 load_time += config->load_step;
182 }
183}
184
diff --git a/tools/power/cpupower/bench/benchmark.h b/tools/power/cpupower/bench/benchmark.h
new file mode 100644
index 00000000000..0691f91b720
--- /dev/null
+++ b/tools/power/cpupower/bench/benchmark.h
@@ -0,0 +1,27 @@
1/* cpufreq-bench CPUFreq microbenchmark
2 *
3 * Copyright (C) 2008 Christian Kornacker <ckornacker@suse.de>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18 */
19
20/* load loop, this schould take about 1 to 2ms to complete */
21#define ROUNDS(x) {unsigned int rcnt; \
22 for (rcnt = 0; rcnt< x*1000; rcnt++) { \
23 (void)(((int)(pow(rcnt, rcnt) * sqrt(rcnt*7230970)) ^ 7230716) ^ (int)atan2(rcnt, rcnt)); \
24 }} \
25
26
27void start_benchmark(struct config *config);
diff --git a/tools/power/cpupower/bench/config.h b/tools/power/cpupower/bench/config.h
new file mode 100644
index 00000000000..9690f1be32f
--- /dev/null
+++ b/tools/power/cpupower/bench/config.h
@@ -0,0 +1,36 @@
1/* cpufreq-bench CPUFreq microbenchmark
2 *
3 * Copyright (C) 2008 Christian Kornacker <ckornacker@suse.de>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18 */
19
20/* initial loop count for the load calibration */
21#define GAUGECOUNT 1500
22
23/* default scheduling policy SCHED_OTHER */
24#define SCHEDULER SCHED_OTHER
25
26#define PRIORITY_DEFAULT 0
27#define PRIORITY_HIGH sched_get_priority_max(SCHEDULER)
28#define PRIORITY_LOW sched_get_priority_min(SCHEDULER)
29
30/* enable further debug messages */
31#ifdef DEBUG
32#define dprintf printf
33#else
34#define dprintf( ... ) while(0) { }
35#endif
36
diff --git a/tools/power/cpupower/bench/cpufreq-bench_plot.sh b/tools/power/cpupower/bench/cpufreq-bench_plot.sh
new file mode 100644
index 00000000000..410021a12f4
--- /dev/null
+++ b/tools/power/cpupower/bench/cpufreq-bench_plot.sh
@@ -0,0 +1,104 @@
1#!/bin/bash
2
3# This program is free software: you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by
5# the Free Software Foundation; either version 2, or (at your option)
6# any later version.
7
8# This program is distributed in the hope that it will be useful,
9# but WITHOUT ANY WARRANTY; without even the implied warranty of
10# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11# GNU General Public License for more details.
12
13# You should have received a copy of the GNU General Public License
14# along with this program; if not, write to the Free Software
15# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
16# 02110-1301, USA.
17
18# Author/Copyright(c): 2009, Thomas Renninger <trenn@suse.de>, Novell Inc.
19
20# Helper script to easily create nice plots of your cpufreq-bench results
21
22dir=`mktemp -d`
23output_file="cpufreq-bench.png"
24global_title="cpufreq-bench plot"
25picture_type="jpeg"
26file[0]=""
27
28function usage()
29{
30 echo "cpufreq-bench_plot.sh [OPTIONS] logfile [measure_title] [logfile [measure_title]] ...]"
31 echo
32 echo "Options"
33 echo " -o output_file"
34 echo " -t global_title"
35 echo " -p picture_type [jpeg|gif|png|postscript|...]"
36 exit 1
37}
38
39if [ $# -eq 0 ];then
40 echo "No benchmark results file provided"
41 echo
42 usage
43fi
44
45while getopts o:t:p: name ; do
46 case $name in
47 o)
48 output_file="$OPTARG".$picture_type
49 ;;
50 t)
51 global_title="$OPTARG"
52 ;;
53 p)
54 picture_type="$OPTARG"
55 ;;
56 ?)
57 usage
58 ;;
59 esac
60done
61shift $(($OPTIND -1))
62
63plots=0
64while [ "$1" ];do
65 if [ ! -f "$1" ];then
66 echo "File $1 does not exist"
67 usage
68 fi
69 file[$plots]="$1"
70 title[$plots]="$2"
71 # echo "File: ${file[$plots]} - ${title[plots]}"
72 shift;shift
73 plots=$((plots + 1))
74done
75
76echo "set terminal $picture_type" >> $dir/plot_script.gpl
77echo "set output \"$output_file\"" >> $dir/plot_script.gpl
78echo "set title \"$global_title\"" >> $dir/plot_script.gpl
79echo "set xlabel \"sleep/load time\"" >> $dir/plot_script.gpl
80echo "set ylabel \"Performance (%)\"" >> $dir/plot_script.gpl
81
82for((plot=0;plot<$plots;plot++));do
83
84 # Sanity check
85 ###### I am to dump to get this redirected to stderr/stdout in one awk call... #####
86 cat ${file[$plot]} |grep -v "^#" |awk '{if ($2 != $3) printf("Error in measure %d:Load time %s does not equal sleep time %s, plot will not be correct\n", $1, $2, $3); ERR=1}'
87 ###### I am to dump to get this redirected in one awk call... #####
88
89 # Parse out load time (which must be equal to sleep time for a plot), divide it by 1000
90 # to get ms and parse out the performance in percentage and write it to a temp file for plotting
91 cat ${file[$plot]} |grep -v "^#" |awk '{printf "%lu %.1f\n",$2/1000, $6}' >$dir/data_$plot
92
93 if [ $plot -eq 0 ];then
94 echo -n "plot " >> $dir/plot_script.gpl
95 fi
96 echo -n "\"$dir/data_$plot\" title \"${title[$plot]}\" with lines" >> $dir/plot_script.gpl
97 if [ $(($plot + 1)) -ne $plots ];then
98 echo -n ", " >> $dir/plot_script.gpl
99 fi
100done
101echo >> $dir/plot_script.gpl
102
103gnuplot $dir/plot_script.gpl
104rm -r $dir \ No newline at end of file
diff --git a/tools/power/cpupower/bench/cpufreq-bench_script.sh b/tools/power/cpupower/bench/cpufreq-bench_script.sh
new file mode 100644
index 00000000000..de20d2a0687
--- /dev/null
+++ b/tools/power/cpupower/bench/cpufreq-bench_script.sh
@@ -0,0 +1,101 @@
1#!/bin/bash
2
3# This program is free software: you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by
5# the Free Software Foundation; either version 2, or (at your option)
6# any later version.
7
8# This program is distributed in the hope that it will be useful,
9# but WITHOUT ANY WARRANTY; without even the implied warranty of
10# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11# GNU General Public License for more details.
12
13# You should have received a copy of the GNU General Public License
14# along with this program; if not, write to the Free Software
15# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
16# 02110-1301, USA.
17
18# Author/Copyright(c): 2009, Thomas Renninger <trenn@suse.de>, Novell Inc.
19
20# Ondemand up_threshold and sampling rate test script for cpufreq-bench
21# mircobenchmark.
22# Modify the general variables at the top or extend or copy out parts
23# if you want to test other things
24#
25
26# Default with latest kernels is 95, before micro account patches
27# it was 80, cmp. with git commit 808009131046b62ac434dbc796
28UP_THRESHOLD="60 80 95"
29# Depending on the kernel and the HW sampling rate could be restricted
30# and cannot be set that low...
31# E.g. before git commit cef9615a853ebc4972084f7 one could only set
32# min sampling rate of 80000 if CONFIG_HZ=250
33SAMPLING_RATE="20000 80000"
34
35function measure()
36{
37 local -i up_threshold_set
38 local -i sampling_rate_set
39
40 for up_threshold in $UP_THRESHOLD;do
41 for sampling_rate in $SAMPLING_RATE;do
42 # Set values in sysfs
43 echo $up_threshold >/sys/devices/system/cpu/cpu0/cpufreq/ondemand/up_threshold
44 echo $sampling_rate >/sys/devices/system/cpu/cpu0/cpufreq/ondemand/sampling_rate
45 up_threshold_set=$(cat /sys/devices/system/cpu/cpu0/cpufreq/ondemand/up_threshold)
46 sampling_rate_set=$(cat /sys/devices/system/cpu/cpu0/cpufreq/ondemand/sampling_rate)
47
48 # Verify set values in sysfs
49 if [ ${up_threshold_set} -eq ${up_threshold} ];then
50 echo "up_threshold: $up_threshold, set in sysfs: ${up_threshold_set}"
51 else
52 echo "WARNING: Tried to set up_threshold: $up_threshold, set in sysfs: ${up_threshold_set}"
53 fi
54 if [ ${sampling_rate_set} -eq ${sampling_rate} ];then
55 echo "sampling_rate: $sampling_rate, set in sysfs: ${sampling_rate_set}"
56 else
57 echo "WARNING: Tried to set sampling_rate: $sampling_rate, set in sysfs: ${sampling_rate_set}"
58 fi
59
60 # Benchmark
61 cpufreq-bench -o /var/log/cpufreq-bench/up_threshold_${up_threshold}_sampling_rate_${sampling_rate}
62 done
63 done
64}
65
66function create_plots()
67{
68 local command
69
70 for up_threshold in $UP_THRESHOLD;do
71 command="cpufreq-bench_plot.sh -o \"sampling_rate_${SAMPLING_RATE}_up_threshold_${up_threshold}\" -t \"Ondemand sampling_rate: ${SAMPLING_RATE} comparison - Up_threshold: $up_threshold %\""
72 for sampling_rate in $SAMPLING_RATE;do
73 command="${command} /var/log/cpufreq-bench/up_threshold_${up_threshold}_sampling_rate_${sampling_rate}/* \"sampling_rate = $sampling_rate\""
74 done
75 echo $command
76 eval "$command"
77 echo
78 done
79
80 for sampling_rate in $SAMPLING_RATE;do
81 command="cpufreq-bench_plot.sh -o \"up_threshold_${UP_THRESHOLD}_sampling_rate_${sampling_rate}\" -t \"Ondemand up_threshold: ${UP_THRESHOLD} % comparison - sampling_rate: $sampling_rate\""
82 for up_threshold in $UP_THRESHOLD;do
83 command="${command} /var/log/cpufreq-bench/up_threshold_${up_threshold}_sampling_rate_${sampling_rate}/* \"up_threshold = $up_threshold\""
84 done
85 echo $command
86 eval "$command"
87 echo
88 done
89
90 command="cpufreq-bench_plot.sh -o \"up_threshold_${UP_THRESHOLD}_sampling_rate_${SAMPLING_RATE}\" -t \"Ondemand up_threshold: ${UP_THRESHOLD} and sampling_rate ${SAMPLING_RATE} comparison\""
91 for sampling_rate in $SAMPLING_RATE;do
92 for up_threshold in $UP_THRESHOLD;do
93 command="${command} /var/log/cpufreq-bench/up_threshold_${up_threshold}_sampling_rate_${sampling_rate}/* \"up_threshold = $up_threshold - sampling_rate = $sampling_rate\""
94 done
95 done
96 echo "$command"
97 eval "$command"
98}
99
100measure
101create_plots \ No newline at end of file
diff --git a/tools/power/cpupower/bench/example.cfg b/tools/power/cpupower/bench/example.cfg
new file mode 100644
index 00000000000..f91f6436068
--- /dev/null
+++ b/tools/power/cpupower/bench/example.cfg
@@ -0,0 +1,11 @@
1sleep = 50000
2load = 50000
3cpu = 0
4priority = LOW
5output = /var/log/cpufreq-bench
6sleep_step = 50000
7load_step = 50000
8cycles = 20
9rounds = 40
10verbose = 0
11governor = ondemand
diff --git a/tools/power/cpupower/bench/main.c b/tools/power/cpupower/bench/main.c
new file mode 100644
index 00000000000..60953fc9343
--- /dev/null
+++ b/tools/power/cpupower/bench/main.c
@@ -0,0 +1,203 @@
1/* cpufreq-bench CPUFreq microbenchmark
2 *
3 * Copyright (C) 2008 Christian Kornacker <ckornacker@suse.de>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18 */
19
20#include <stdio.h>
21#include <stdlib.h>
22#include <string.h>
23#include <unistd.h>
24#include <getopt.h>
25#include <errno.h>
26
27#include "config.h"
28#include "system.h"
29#include "benchmark.h"
30
31static struct option long_options[] =
32{
33 {"output", 1, 0, 'o'},
34 {"sleep", 1, 0, 's'},
35 {"load", 1, 0, 'l'},
36 {"verbose", 0, 0, 'v'},
37 {"cpu", 1, 0, 'c'},
38 {"governor", 1, 0, 'g'},
39 {"prio", 1, 0, 'p'},
40 {"file", 1, 0, 'f'},
41 {"cycles", 1, 0, 'n'},
42 {"rounds", 1, 0, 'r'},
43 {"load-step", 1, 0, 'x'},
44 {"sleep-step", 1, 0, 'y'},
45 {"help", 0, 0, 'h'},
46 {0, 0, 0, 0}
47};
48
49/*******************************************************************
50 usage
51*******************************************************************/
52
53void usage()
54{
55 printf("usage: ./bench\n");
56 printf("Options:\n");
57 printf(" -l, --load=<long int>\t\tinitial load time in us\n");
58 printf(" -s, --sleep=<long int>\t\tinitial sleep time in us\n");
59 printf(" -x, --load-step=<long int>\ttime to be added to load time, in us\n");
60 printf(" -y, --sleep-step=<long int>\ttime to be added to sleep time, in us\n");
61 printf(" -c, --cpu=<cpu #>\t\t\tCPU Nr. to use, starting at 0\n");
62 printf(" -p, --prio=<priority>\t\t\tscheduler priority, HIGH, LOW or DEFAULT\n");
63 printf(" -g, --governor=<governor>\t\tcpufreq governor to test\n");
64 printf(" -n, --cycles=<int>\t\t\tload/sleep cycles\n");
65 printf(" -r, --rounds<int>\t\t\tload/sleep rounds\n");
66 printf(" -f, --file=<configfile>\t\tconfig file to use\n");
67 printf(" -o, --output=<dir>\t\t\toutput path. Filename will be OUTPUTPATH/benchmark_TIMESTAMP.log\n");
68 printf(" -v, --verbose\t\t\t\tverbose output on/off\n");
69 printf(" -h, --help\t\t\t\tPrint this help screen\n");
70 exit (1);
71}
72
73/*******************************************************************
74 main
75*******************************************************************/
76
77int main(int argc, char **argv)
78{
79 int c;
80 int option_index = 0;
81 struct config *config = NULL;
82
83 config = prepare_default_config();
84
85 if (config == NULL)
86 return EXIT_FAILURE;
87
88 while (1) {
89 c = getopt_long (argc, argv, "hg:o:s:l:vc:p:f:n:r:x:y:",
90 long_options, &option_index);
91 if (c == -1)
92 break;
93
94 switch (c) {
95 case 'o':
96 if (config->output != NULL)
97 fclose(config->output);
98
99 config->output = prepare_output(optarg);
100
101 if (config->output == NULL)
102 return EXIT_FAILURE;
103
104 dprintf("user output path -> %s\n", optarg);
105 break;
106 case 's':
107 sscanf(optarg, "%li", &config->sleep);
108 dprintf("user sleep time -> %s\n", optarg);
109 break;
110 case 'l':
111 sscanf(optarg, "%li", &config->load);
112 dprintf("user load time -> %s\n", optarg);
113 break;
114 case 'c':
115 sscanf(optarg, "%u", &config->cpu);
116 dprintf("user cpu -> %s\n", optarg);
117 break;
118 case 'g':
119 strncpy(config->governor, optarg, 14);
120 dprintf("user governor -> %s\n", optarg);
121 break;
122 case 'p':
123 if (string_to_prio(optarg) != SCHED_ERR) {
124 config->prio = string_to_prio(optarg);
125 dprintf("user prio -> %s\n", optarg);
126 } else {
127 if (config != NULL) {
128 if (config->output != NULL)
129 fclose(config->output);
130 free(config);
131 }
132 usage();
133 }
134 break;
135 case 'n':
136 sscanf(optarg, "%u", &config->cycles);
137 dprintf("user cycles -> %s\n", optarg);
138 break;
139 case 'r':
140 sscanf(optarg, "%u", &config->rounds);
141 dprintf("user rounds -> %s\n", optarg);
142 break;
143 case 'x':
144 sscanf(optarg, "%li", &config->load_step);
145 dprintf("user load_step -> %s\n", optarg);
146 break;
147 case 'y':
148 sscanf(optarg, "%li", &config->sleep_step);
149 dprintf("user sleep_step -> %s\n", optarg);
150 break;
151 case 'f':
152 if (prepare_config(optarg, config))
153 return EXIT_FAILURE;
154 break;
155 case 'v':
156 config->verbose = 1;
157 dprintf("verbose output enabled\n");
158 break;
159 case 'h':
160 case '?':
161 default:
162 if (config != NULL) {
163 if (config->output != NULL)
164 fclose(config->output);
165 free(config);
166 }
167 usage();
168 }
169 }
170
171 if (config->verbose) {
172 printf("starting benchmark with parameters:\n");
173 printf("config:\n\t"
174 "sleep=%li\n\t"
175 "load=%li\n\t"
176 "sleep_step=%li\n\t"
177 "load_step=%li\n\t"
178 "cpu=%u\n\t"
179 "cycles=%u\n\t"
180 "rounds=%u\n\t"
181 "governor=%s\n\n",
182 config->sleep,
183 config->load,
184 config->sleep_step,
185 config->load_step,
186 config->cpu,
187 config->cycles,
188 config->rounds,
189 config->governor);
190 }
191
192 prepare_user(config);
193 prepare_system(config);
194 start_benchmark(config);
195
196 if (config->output != stdout)
197 fclose(config->output);
198
199 free(config);
200
201 return EXIT_SUCCESS;
202}
203
diff --git a/tools/power/cpupower/bench/parse.c b/tools/power/cpupower/bench/parse.c
new file mode 100644
index 00000000000..3b270ac92c4
--- /dev/null
+++ b/tools/power/cpupower/bench/parse.c
@@ -0,0 +1,224 @@
1/* cpufreq-bench CPUFreq microbenchmark
2 *
3 * Copyright (C) 2008 Christian Kornacker <ckornacker@suse.de>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18 */
19
20#include <stdio.h>
21#include <stdlib.h>
22#include <stdarg.h>
23#include <string.h>
24#include <time.h>
25#include <dirent.h>
26
27#include <sys/utsname.h>
28#include <sys/types.h>
29#include <sys/stat.h>
30
31#include "parse.h"
32#include "config.h"
33
34/**
35 * converts priority string to priority
36 *
37 * @param str string that represents a scheduler priority
38 *
39 * @retval priority
40 * @retval SCHED_ERR when the priority doesn't exit
41 **/
42
43enum sched_prio string_to_prio(const char *str)
44{
45 if (strncasecmp("high", str, strlen(str)) == 0)
46 return SCHED_HIGH;
47 else if (strncasecmp("default", str, strlen(str)) == 0)
48 return SCHED_DEFAULT;
49 else if (strncasecmp("low", str, strlen(str)) == 0)
50 return SCHED_LOW;
51 else
52 return SCHED_ERR;
53}
54
55/**
56 * create and open logfile
57 *
58 * @param dir directory in which the logfile should be created
59 *
60 * @retval logfile on success
61 * @retval NULL when the file can't be created
62 **/
63
64FILE *prepare_output(const char *dirname)
65{
66 FILE *output = NULL;
67 int len;
68 char *filename;
69 struct utsname sysdata;
70 DIR *dir;
71
72 dir = opendir(dirname);
73 if (dir == NULL) {
74 if (mkdir(dirname, 0755)) {
75 perror("mkdir");
76 fprintf(stderr, "error: Cannot create dir %s\n",
77 dirname);
78 return NULL;
79 }
80 }
81
82 len = strlen(dirname) + 30;
83 filename = malloc(sizeof(char) * len);
84
85 if (uname(&sysdata) == 0) {
86 len += strlen(sysdata.nodename) + strlen(sysdata.release);
87 filename = realloc(filename, sizeof(char) * len);
88
89 if(filename == NULL) {
90 perror("realloc");
91 return NULL;
92 }
93
94 snprintf(filename, len - 1, "%s/benchmark_%s_%s_%li.log",
95 dirname, sysdata.nodename, sysdata.release, time(NULL));
96 } else {
97 snprintf(filename, len -1, "%s/benchmark_%li.log", dirname, time(NULL));
98 }
99
100 dprintf("logilename: %s\n", filename);
101
102 if ((output = fopen(filename, "w+")) == NULL) {
103 perror("fopen");
104 fprintf(stderr, "error: unable to open logfile\n");
105 }
106
107 fprintf(stdout, "Logfile: %s\n", filename);
108
109 free(filename);
110 fprintf(output, "#round load sleep performance powersave percentage\n");
111 return output;
112}
113
114/**
115 * returns the default config
116 *
117 * @retval default config on success
118 * @retval NULL when the output file can't be created
119 **/
120
121struct config *prepare_default_config()
122{
123 struct config *config = malloc(sizeof(struct config));
124
125 dprintf("loading defaults\n");
126
127 config->sleep = 500000;
128 config->load = 500000;
129 config->sleep_step = 500000;
130 config->load_step = 500000;
131 config->cycles = 5;
132 config->rounds = 50;
133 config->cpu = 0;
134 config->prio = SCHED_HIGH;
135 config->verbose = 0;
136 strncpy(config->governor, "ondemand", 8);
137
138 config->output = stdout;
139
140#ifdef DEFAULT_CONFIG_FILE
141 if (prepare_config(DEFAULT_CONFIG_FILE, config))
142 return NULL;
143#endif
144 return config;
145}
146
147/**
148 * parses config file and returns the config to the caller
149 *
150 * @param path config file name
151 *
152 * @retval 1 on error
153 * @retval 0 on success
154 **/
155
156int prepare_config(const char *path, struct config *config)
157{
158 size_t len = 0;
159 char *opt, *val, *line = NULL;
160 FILE *configfile = fopen(path, "r");
161
162 if (config == NULL) {
163 fprintf(stderr, "error: config is NULL\n");
164 return 1;
165 }
166
167 if (configfile == NULL) {
168 perror("fopen");
169 fprintf(stderr, "error: unable to read configfile\n");
170 free(config);
171 return 1;
172 }
173
174 while (getline(&line, &len, configfile) != -1)
175 {
176 if (line[0] == '#' || line[0] == ' ')
177 continue;
178
179 sscanf(line, "%as = %as", &opt, &val);
180
181 dprintf("parsing: %s -> %s\n", opt, val);
182
183 if (strncmp("sleep", opt, strlen(opt)) == 0)
184 sscanf(val, "%li", &config->sleep);
185
186 else if (strncmp("load", opt, strlen(opt)) == 0)
187 sscanf(val, "%li", &config->load);
188
189 else if (strncmp("load_step", opt, strlen(opt)) == 0)
190 sscanf(val, "%li", &config->load_step);
191
192 else if (strncmp("sleep_step", opt, strlen(opt)) == 0)
193 sscanf(val, "%li", &config->sleep_step);
194
195 else if (strncmp("cycles", opt, strlen(opt)) == 0)
196 sscanf(val, "%u", &config->cycles);
197
198 else if (strncmp("rounds", opt, strlen(opt)) == 0)
199 sscanf(val, "%u", &config->rounds);
200
201 else if (strncmp("verbose", opt, strlen(opt)) == 0)
202 sscanf(val, "%u", &config->verbose);
203
204 else if (strncmp("output", opt, strlen(opt)) == 0)
205 config->output = prepare_output(val);
206
207 else if (strncmp("cpu", opt, strlen(opt)) == 0)
208 sscanf(val, "%u", &config->cpu);
209
210 else if (strncmp("governor", opt, 14) == 0)
211 strncpy(config->governor, val, 14);
212
213 else if (strncmp("priority", opt, strlen(opt)) == 0) {
214 if (string_to_prio(val) != SCHED_ERR)
215 config->prio = string_to_prio(val);
216 }
217 }
218
219 free(line);
220 free(opt);
221 free(val);
222
223 return 0;
224}
diff --git a/tools/power/cpupower/bench/parse.h b/tools/power/cpupower/bench/parse.h
new file mode 100644
index 00000000000..9fcdfa23dd9
--- /dev/null
+++ b/tools/power/cpupower/bench/parse.h
@@ -0,0 +1,50 @@
1/* cpufreq-bench CPUFreq microbenchmark
2 *
3 * Copyright (C) 2008 Christian Kornacker <ckornacker@suse.de>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18 */
19
20/* struct that holds the required config parameters */
21struct config
22{
23 long sleep; /* sleep time in µs */
24 long load; /* load time in µs */
25 long sleep_step; /* time value which changes the
26 * sleep time after every round in µs */
27 long load_step; /* time value which changes the
28 * load time after every round in µs */
29 unsigned int cycles; /* calculation cycles with the same sleep/load time */
30 unsigned int rounds; /* calculation rounds with iterated sleep/load time */
31 unsigned int cpu; /* cpu for which the affinity is set */
32 char governor[15]; /* cpufreq governor */
33 enum sched_prio /* possible scheduler priorities */
34 {
35 SCHED_ERR=-1,SCHED_HIGH, SCHED_DEFAULT, SCHED_LOW
36 } prio;
37
38 unsigned int verbose; /* verbose output */
39 FILE *output; /* logfile */
40 char *output_filename; /* logfile name, must be freed at the end
41 if output != NULL and output != stdout*/
42};
43
44enum sched_prio string_to_prio(const char *str);
45
46FILE *prepare_output(const char *dir);
47
48int prepare_config(const char *path, struct config *config);
49struct config *prepare_default_config();
50
diff --git a/tools/power/cpupower/bench/system.c b/tools/power/cpupower/bench/system.c
new file mode 100644
index 00000000000..3e3a82e8bdd
--- /dev/null
+++ b/tools/power/cpupower/bench/system.c
@@ -0,0 +1,188 @@
1/* cpufreq-bench CPUFreq microbenchmark
2 *
3 * Copyright (C) 2008 Christian Kornacker <ckornacker@suse.de>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18 */
19
20#include <stdio.h>
21#include <time.h>
22#include <sys/time.h>
23#include <sys/types.h>
24#include <unistd.h>
25
26#include <sched.h>
27
28#include <cpufreq.h>
29
30#include "config.h"
31#include "system.h"
32
33/**
34 * returns time since epoch in µs
35 *
36 * @retval time
37 **/
38
39long long int get_time()
40{
41 struct timeval now;
42
43 gettimeofday(&now, NULL);
44
45 return (long long int)(now.tv_sec * 1000000LL + now.tv_usec);
46}
47
48/**
49 * sets the cpufreq governor
50 *
51 * @param governor cpufreq governor name
52 * @param cpu cpu for which the governor should be set
53 *
54 * @retval 0 on success
55 * @retval -1 when failed
56 **/
57
58int set_cpufreq_governor(char *governor, unsigned int cpu)
59{
60
61 dprintf("set %s as cpufreq governor\n", governor);
62
63 if (cpufreq_cpu_exists(cpu) != 0) {
64 perror("cpufreq_cpu_exists");
65 fprintf(stderr, "error: cpu %u does not exist\n", cpu);
66 return -1;
67 }
68
69 if (cpufreq_modify_policy_governor(cpu, governor) != 0) {
70 perror("cpufreq_modify_policy_governor");
71 fprintf(stderr, "error: unable to set %s governor\n", governor);
72 return -1;
73 }
74
75 return 0;
76}
77
78/**
79 * sets cpu affinity for the process
80 *
81 * @param cpu cpu# to which the affinity should be set
82 *
83 * @retval 0 on success
84 * @retval -1 when setting the affinity failed
85 **/
86
87int set_cpu_affinity(unsigned int cpu)
88{
89 cpu_set_t cpuset;
90
91 CPU_ZERO(&cpuset);
92 CPU_SET(cpu, &cpuset);
93
94 dprintf("set affinity to cpu #%u\n", cpu);
95
96 if (sched_setaffinity(getpid(), sizeof(cpu_set_t), &cpuset) < 0) {
97 perror("sched_setaffinity");
98 fprintf(stderr, "warning: unable to set cpu affinity\n");
99 return -1;
100 }
101
102 return 0;
103}
104
105/**
106 * sets the process priority parameter
107 *
108 * @param priority priority value
109 *
110 * @retval 0 on success
111 * @retval -1 when setting the priority failed
112 **/
113
114int set_process_priority(int priority)
115{
116 struct sched_param param;
117
118 dprintf("set scheduler priority to %i\n", priority);
119
120 param.sched_priority = priority;
121
122 if (sched_setscheduler(0, SCHEDULER, &param) < 0) {
123 perror("sched_setscheduler");
124 fprintf(stderr, "warning: unable to set scheduler priority\n");
125 return -1;
126 }
127
128 return 0;
129}
130
131/**
132 * notifys the user that the benchmark may run some time
133 *
134 * @param config benchmark config values
135 *
136 **/
137
138void prepare_user(const struct config *config)
139{
140 unsigned long sleep_time = 0;
141 unsigned long load_time = 0;
142 unsigned int round;
143
144 for (round = 0; round < config->rounds; round++) {
145 sleep_time += 2 * config->cycles * (config->sleep + config->sleep_step * round);
146 load_time += 2 * config->cycles * (config->load + config->load_step * round) + (config->load + config->load_step * round * 4);
147 }
148
149 if (config->verbose || config->output != stdout)
150 printf("approx. test duration: %im\n",
151 (int)((sleep_time + load_time) / 60000000));
152}
153
154/**
155 * sets up the cpu affinity and scheduler priority
156 *
157 * @param config benchmark config values
158 *
159 **/
160
161void prepare_system(const struct config *config)
162{
163 if (config->verbose)
164 printf("set cpu affinity to cpu #%u\n", config->cpu);
165
166 set_cpu_affinity(config->cpu);
167
168 switch (config->prio) {
169 case SCHED_HIGH:
170 if (config->verbose)
171 printf("high priority condition requested\n");
172
173 set_process_priority(PRIORITY_HIGH);
174 break;
175 case SCHED_LOW:
176 if (config->verbose)
177 printf("low priority condition requested\n");
178
179 set_process_priority(PRIORITY_LOW);
180 break;
181 default:
182 if (config->verbose)
183 printf("default priority condition requested\n");
184
185 set_process_priority(PRIORITY_DEFAULT);
186 }
187}
188
diff --git a/tools/power/cpupower/bench/system.h b/tools/power/cpupower/bench/system.h
new file mode 100644
index 00000000000..3a8c858b78f
--- /dev/null
+++ b/tools/power/cpupower/bench/system.h
@@ -0,0 +1,29 @@
1/* cpufreq-bench CPUFreq microbenchmark
2 *
3 * Copyright (C) 2008 Christian Kornacker <ckornacker@suse.de>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18 */
19
20#include "parse.h"
21
22long long get_time();
23
24int set_cpufreq_governor(char *governor, unsigned int cpu);
25int set_cpu_affinity(unsigned int cpu);
26int set_process_priority(int priority);
27
28void prepare_user(const struct config *config);
29void prepare_system(const struct config *config);