From: Carl E. L. <ce...@li...> - 2013-08-15 23:26:40
|
Maynard: I believe I have fixed all of the issues you noted. I also found a few additional typos and space/tab issues that needed fixing. See what you think of this version. Carl Love ----------------------------------------------------------------------------- Add tests for the ocount tool The patch adds support for two additional testuites for testing the ocount tool. The first testsuite runs a series of tests on the ocount tool. The tests include: - each event generates non-zero counts - counting for each event for an interval of n seconds, 2*n and 4*n scale as expected - the sum of the counts for each event in user mode only, kernel mode only match counting in user and kernel mode - the output using the brief output format is verified The above tests are run when the tool "oprofile" or "oprofile-ocount" are run. The second testsuite includes the additional test: - counting cycles for an interval of n seconds matches n*proc_frequency The testsuite is only run when the tool "cycle-check-ocount" is specified. The testsuite checks the event count against the reported CPU frequency which may or may not be the actual operating CPU frequency. The reported frequency and the actual frequency may differ if the CPU is running in the Intel "turbo" mode or at a lower frequency for thermal management. The user may need to manually verify any test failures based on the actual operating CPU frequency not the reported CPU frequency. Signed-off-by: Carl Love <ce...@us...> --- testsuite/README | 111 +++++++++---- .../cycle-check-ocount/ocount-cycle-check-run.exp | 89 ++++++++++ testsuite/lib/ocount_util.exp | 185 +++++++++++++++++++++ testsuite/oprofile-ocount/ocount-run.exp | 184 ++++++++++++++++++++ testsuite/workload_ocount/load.c | 81 +++++++++ 5 files changed, 619 insertions(+), 31 deletions(-) create mode 100644 testsuite/cycle-check-ocount/ocount-cycle-check-run.exp create mode 100644 testsuite/lib/ocount_util.exp create mode 100644 testsuite/oprofile-ocount/ocount-run.exp create mode 100644 testsuite/workload_ocount/load.c diff --git a/testsuite/README b/testsuite/README index 1218fc2..b2f8692 100644 --- a/testsuite/README +++ b/testsuite/README @@ -1,6 +1,7 @@ This testsuite directory contains a simple testsuite to check the functionality of OProfile on the machine. The testsuite supports testing the previous user interface using opcontrol and the new operf interface. +The testsuite also includes tests for the ocount tool. The testsuite consists of several workloads. Each workload is run using an architecture specific list of event sets. The OProfile report for @@ -8,49 +9,99 @@ each workload run is then checked to make sure the expected symbols that are specific to that workload are found in the profile report. -Running the opcontrol OProfile testsuite requires the following: +Profiling Tool tests --Superuser privileges --The dejagnu and expect packages are installed --The OProfile commands to be on the PATH + Running the opcontrol OProfile testsuite requires the following: -The opcontrol tests are run by being in this directory and running the -following command: + -Superuser privileges + -The dejagnu and expect packages are installed + -The OProfile commands to be on the PATH -runtest --tool oprofile-opcontrol + The opcontrol tests are run by being in this directory and running the + following command: + runtest --tool oprofile-opcontrol -The system-wide operf OProfile testsuite requires the following: --Superuser privileges --The dejagnu and expect packages are installed --The OProfile commands to be on the PATH + The system-wide operf OProfile testsuite requires the following: -The system-wide operf tests are run by being in this directory and running -the following command: + -Superuser privileges + -The dejagnu and expect packages are installed + -The OProfile commands to be on the PATH -runtest --tool oprofile-operf + The system-wide operf tests are run by being in this directory and running + the following command: -The single process operf testsuite requires the following: + runtest --tool oprofile-operf --The dejagnu and expect packages are installed --The OProfile commands to be on the PATH --Note, you should run the command "opcontrol --reset" as root to make sure - there are no opcontrol data samples around that opreport might accidentally - pickup on. The testsuite is setup so it can run as a regular user. Regular - users can't delete the opcontrol data. --In order to run oprofile--single_process as an normal user, the testsuite - directories need to be writable by normal user running the test. + The single process operf testsuite requires the following: -The single process operf tests are run by being in this directory and running -the following command as either root or a normal user: + -The dejagnu and expect packages are installed + -The OProfile commands to be on the PATH + -Note, you should run the command "opcontrol --reset" as root to make sure + there are no opcontrol data samples around that opreport might accidentally + pickup on. The testsuite is setup so it can run as a regular user. Regular + users can't delete the opcontrol data. + -In order to run oprofile-single_process as an normal user, the testsuite + directories need to be writable by normal user running the test. -runtest --tool oprofile-single_process + The single process operf tests are run by being in this directory and running + the following command as either root or a normal user: -To run all three testsuites (provided the requirements for all of them are -met), use the command + runtest --tool oprofile-single_process -runtest --tool oprofile + +Event Counting tool tests + + The testsuite oprofile-ocount tests the event counting tool ocount. The + testsuite runs a series of tests using the ocount tool. + + The tests include: + + - each sample generates non-zero counts + - counting cycles for an interval of n seconds, 2*n and 4*n scale as + expected + - the sum of the counts cycles in user mode only, kernel mode + only match counting cycles in user and kernel mode + + The ocount tests are run by being in this directory and running the following + command as either root or a normal user: + + runtest --tool oprofile-ocount + + + The testsuite cycle-check-ocount tests tool ocount counting of cycles versus + the reported CPU frequency. The reported frequency is not correct for all + platforms. Some of the Intel processors can be running in Turbo mode. In + Turbo mode the CPU frequency is higher then the reported frequency. The + CPU frequency may be lowered by automatic thermal regulation circuits for + heat management. This is true for the Power processors. In this case, the + actual CPU frequency may be lower then the reported frequency. These tests + were put into a separate tool as they should only be run when the user + has a good understanding of what the actual rather then reported frequency + for the CPU is. + + The tests include: + + - each sample generates non-zero counts + - counting cycles for an interval of n seconds matches n*proc_frequency + + The tests will pass or fail based on the reported frequency. The user will + need to manually verify if the reported count makes sense for the actual + CPU frequency. + + The cycle check tests are run by being in this directory and running the + following command as either root or a normal user: + + runtest --tool cycle-check-ocount + + +Combined profiling and counting tests + + To run all of the testsuites, with the exception of the cycle check tests, + (provided the requirements for all of them are met), use the command + + runtest --tool oprofile The tests will run and at the end should print out the number of tests @@ -68,5 +119,3 @@ wrong" and that the basic functionality works. Comments about and additions to the testsuite infrastructure are appreciated. - --Will diff --git a/testsuite/cycle-check-ocount/ocount-cycle-check-run.exp b/testsuite/cycle-check-ocount/ocount-cycle-check-run.exp new file mode 100644 index 0000000..999bf8b --- /dev/null +++ b/testsuite/cycle-check-ocount/ocount-cycle-check-run.exp @@ -0,0 +1,89 @@ +# ocount-cycle-check-run.exp +# Copyright (C) 2013 IBM +# +# author: Carl Love <ca...@us...> +# +# This file is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# + +load_lib "ocount_util.exp" + +proc do_test_ocount_cycle_test {workload_exec output_format} { + + # Get processor frequency in Hz + set freq [get_cpu_frequency] + + # Check that counting cycles for "interval" seconds is equal to the + # processor frequency. Note, we run this with a workload so we don't have + # issues with partitioned machines ceeding the processor because it is + # idle. + + set event [get_cycles_event] + set interval 1 + + set pid [exec $workload_exec > /tmp/junky.xwyesu.xse &] + + # allow workload to reach steady state + local_exec "sleep 1" "" "" 10 + + set result [local_exec "ocount $output_format -e $event --time-interval $interval:1 -p $pid " "" "" 60] + + test_kill_workload $pid + + if {[string match $output_format "--brief-format"]} { + set count [get_event_count_brief $result $event] + } else { + set count [get_event_count $result $event] + } + + local_exec "rm /tmp/junky.xwyesu.xse" "" "" 10 + set test "Count cycles matches CPU frequency" + + # check the count is not zero + if {[check_nonzero_count $count $workload_exec $event] == 0} { + return + } + + # The frequency is specified in units of Hz + set expt_count [expr $interval * $freq] + + # Count of cycles and frequency should be within the following percentage + set percent 5 + + if {[check_expected_value $count $expt_count $percent] == 1} { + pass $test + } else { + fail $test + send "CPU freq $freq Hz, collection interval $interval. \n" + send "Expected count $expt_count, actual count $count. \n" + send "See the README for an explanation about why the \n" + send "ocount-cycle-check test may have failed. \n\n" + } +} + +proc cycle_run_tests {} { + + set workload_exec [compile_ocount_workload "workload_ocount/load.c"] + + # Check the brief format counting cycles versus CPU frequency + do_test_ocount_cycle_test $workload_exec "--brief-format" + + # Check the cycles count versus CPU frequency + do_test_ocount_cycle_test $workload_exec "" +} + + +#main +cycle_run_tests diff --git a/testsuite/lib/ocount_util.exp b/testsuite/lib/ocount_util.exp new file mode 100644 index 0000000..bbf53a7 --- /dev/null +++ b/testsuite/lib/ocount_util.exp @@ -0,0 +1,185 @@ +# ocount_util.exp +# Copyright (C) 2013 IBM +# +# Author: Carl Love <ca...@us...> +# +# This file is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# + +proc get_cycles_event {} { + # local exec output of ophelp output is of the form: + # "0 {CYCLES:100000:0:1:1}". Extract the cycles event + set string [local_exec "ophelp -d" "" "" 10] + set line [regexp -all -inline {\S+} $string] + set word [split [string trimleft [lindex $line 1 ] "\{" ] ":"] + set event [lindex $word 0] + return $event +} + +proc compile_ocount_workload {workload_src } { + + set compiler "cc" + set compile_options " " + set extension [lindex [split $workload_src "."] 1] + set workload_exec [ lindex [split $workload_src "."] 0]_bin + + set result [local_exec "$compiler -o $workload_exec $workload_src $compile_options" "" "" 10 ] + if { [lindex $result 0] == 1 } { + print "\nERROR compiling workload: $workload_src" + print "Compiler error message: $result\n" + } + return $workload_exec +} + +# proc check that the result was with in the expected percent of the +# expected value +proc check_expected_value {actual_value expected_value percent} { + + set min_val [expr ($expected_value * (100 - $percent))/100] + set max_val [expr ($expected_value * (100 + $percent))/100] + + if {$actual_value >= $min_val && $actual_value <= $max_val} { + return 1 + } else { + return 0 + } +} + +proc check_nonzero_count {count workload event} { + set test "Non-zero count for workload $workload and event $event" + if {$count == 0} { + fail $test + return 0 + } else { + pass $test + return 1 + } +} + +proc get_event_count { result symbol} { + + set words [regexp -all -inline {\S+} $result] + + set count 0 + set index 0 + foreach entry $words { + if {[string match $entry $symbol ] == 1} { + set count [lindex $words $index+1 ] + } + set index [expr $index + 1] + } + + # remove all commas in the count value + return [regsub -all {,} $count ""] +} + +proc get_event_count_brief { result symbol} { + # Output is assumed to be in the brief format which + # consists of a string of fields separated by commas + + set words [regexp -all -inline {\S+} $result] + set count 0 + set index 0 + foreach entry $words { + set sub_field [split $entry ","] + set index 0 + foreach sub_entry $sub_field { + if {[string match $sub_entry $symbol ] == 1} { + set count [lindex $sub_field $index+1 ] + break + } + set index [expr $index + 1] + } + } + return $count +} + +proc test_kill_workload {pid} { + set test "Kill the running workload. Note, if this fails it could be the reason the some non-zero tests failing.\n" + set result [local_exec "kill $pid" "" "" 10] + + set words [regexp -all -inline {\S+} $result] + if {[ lindex $words 0] == 0 } { + pass $test + } else { + fail $test + } +} + +proc get_cpu_frequency {} { + set file_exists [file exists "/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq" ] + set freq 0 + + if { $file_exists } { + # The frequency specified in this file seem to be in units of KHz, + # return the frequency in units of Hz. + set fp [open "/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq" r] + set result [read $fp] + if {[ string is integer -strict $result ]} { + set freq [ expr $result * 1000 ] + } + } + + # if the frequency was not found in cpuinfo_max_freq, try /proc/cpuinfo + if { $freq == 0 } { + # The frequency specified in this file may be in MHz, Hz or bogomips. + # Return the frequency in units of Hz. + set fp [open "/proc/cpuinfo" r] + set result [read $fp] + set words [regexp -all -inline {\S+} $result] + set index 0 + + foreach entry $words { + # look for x86/parisc/ia64/x86_64 entry "cpu MHz : %lf" + if {([string match $entry "cpu" ] == 1) && + ([string match [lindex $words $index+1] "MHz"] == 1)} { + set freq_str [lindex $words $index+3 ] + set freq [ expr $freq_str * 1000000 ] + break + } + + # look for ppc/ppc64 entry, "clock : %lfMHz" + if {[string match $entry "clock" ] == 1} { + set freq_str [lindex $words $index+2 ] + set freq_str_trim [string trimright $freq_str "MHz"]0001-Add-test-for-the-ocount-tool.patch + set freq [ expr $freq_str_trim * 1000000 ] + break + } + + # look for alpha, "cycle frequency [Hz] : %lu" + if {([string match $entry "cycle" ] == 1) && + ([string match [lindex $words $index+1] "frequency"] == 1)} { + set freq [lindex $words $index+4 ] + break + } + + # look for sparc64, "Cpu0ClkTck : %lx" + if {[string match $entry "Cpu0ClkTck" ] == 1} { + set freq [lindex $words $index+2 ] + break + } + + # look for mips including loongson2, "BogoMIPS : %lu" + if {[string match $entry "BogoMIPS" ] == 1} { + set freq_str [lindex $words $index+2 ] + set freq [ expr ($freq_str * 2) / 3 ] + break + } + + set index [expr $index + 1] + } + } + return $freq +} diff --git a/testsuite/oprofile-ocount/ocount-run.exp b/testsuite/oprofile-ocount/ocount-run.exp new file mode 100644 index 0000000..964aa1c --- /dev/null +++ b/testsuite/oprofile-ocount/ocount-run.exp @@ -0,0 +1,184 @@ +# ocount-run.exp +# Copyright (C) 2013 IBM +# +# Author: Carl Love <ca...@us...> +# +# This file is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# + +load_lib "ocount_util.exp" + + +proc do_test_ocount_cycle_test {workload_exec output_format} { + + # Check that counting cycles for "interval" seconds is non-zero + set event [get_cycles_event] + set interval 1 + + set pid [exec $workload_exec > /tmp/junky.xwyesu.xse &] + + # allow workload to reach steady state + local_exec "sleep 1" "" "" 10 + + set result [local_exec "ocount $output_format -e $event --time-interval $interval:1 -p $pid " "" "" 60] + + test_kill_workload $pid + + if {[string match $output_format "--brief-format"]} { + set count [get_event_count_brief $result $event] + } else { + set count [get_event_count $result $event] + } + + local_exec "rm /tmp/junky.xwyesu.xse" "" "" 10 + + set test "Count cycles matches CPU frequency" + + # check the count is not zero + if {[check_nonzero_count $count $workload_exec $event] == 0} { + return + } + +} + +proc do_test_ocount_scaling {workload_exec} { + + # The actual result is expected to be within the following percent of the + # actual count + set percent 5 + set interval1 1 + set interval2 2 + set interval4 4 + + set event [get_cycles_event] + + set pid [exec $workload_exec > /tmp/junky.xwyesu.xse &] + + # allow workload to reach steady state + local_exec "sleep 1" "" "" 10 + + set result1 [local_exec "taskset -c 0 ocount -e ${event} --time-interval $interval1:1 -p $pid" "" "" 60] + set result2 [local_exec "taskset -c 0 ocount -e ${event} --time-interval $interval2:1 -p $pid" "" "" 60] + set result4 [local_exec "taskset -c 0 ocount -e ${event} --time-interval $interval4:1 -p $pid" "" "" 60] + + test_kill_workload $pid + + set count1 [get_event_count $result1 $event] + set count2 [get_event_count $result2 $event] + set count4 [get_event_count $result4 $event] + + # Check the results are not zero + check_nonzero_count $count1 $workload_exec $event + check_nonzero_count $count2 $workload_exec $event + check_nonzero_count $count4 $workload_exec $event + + # Check the scaling of the results + set test "Event $event count scales by 2, workload $workload_exec" + + set expt_count [expr $count1 * 2] + if {[check_expected_value $count2 $expt_count $percent] == 1} { + pass $test + } else { + fail $test + send "Initial count $count1, expected count $expt_count, actual $count2\n\n" + } + + local_exec "rm /tmp/junky.xwyesu.xse" "" "" 10 + + set test "Event $event count scales by 4, workload $workload_exec" + set expt_count [expr $count1 * 4] + + if {[check_expected_value $count4 $expt_count $percent] == 1} { + pass $test + } else { + fail $test + send "Initial count $count1, expected count $expt_count, actual $count4\n\n" + } +} + +proc do_test_ocount_modes {workload_exec} { + + # The actual result is expected to be within the following percent of the + # actual count + set percent 5 + set interval 1 + + set event [get_cycles_event] + + # Run the workloads in user only, kernel only, then user and kernel + # modes. + set pid [exec $workload_exec > /tmp/junky.xwyesu.xse &] + + # allow workload to reach steady state + local_exec "sleep 1" "" "" 10 + + set user_result [local_exec "taskset -c 0 ocount -e ${event}:0:0:1 --time-interval $interval:1 -p $pid" "" "" 60] + + set kernel_result [local_exec "taskset -c 0 ocount -e ${event}:0:1:0 --time-interval $interval:1 -p $pid" "" "" 60] + + set user_kernel_result [local_exec "taskset -c 0 ocount -e ${event}:0:1:1 --time-interval $interval:1 -p $pid" "" "" 60] + + test_kill_workload $pid + + local_exec "rm /tmp/junky.xwyesu.xse" "" "" 10 + + # get the counts from the results + set u_count [get_event_count $user_result $event] + set k_count [get_event_count $kernel_result $event] + set u_k_count [get_event_count $user_kernel_result $event] + + # Check the counts are not zero + check_nonzero_count $u_count $workload_exec $event + check_nonzero_count $k_count $workload_exec $event] + check_nonzero_count $u_k_count $workload_exec $event + + # Check the scaling of the results + set test "Event $event, user mode count plus kernel mode count matches user and kernel mode count, workload $workload_exec" + + set expt_count [expr $u_count + $k_count] + + if {[check_expected_value $u_k_count $expt_count $percent] == 1} { + pass $test + } else { + fail $test + send "User count $u_count, kernel count $k_count, sum $expt_count\n" + send "User and kernel count, $u_k_count\n" + } +} + + +proc ocount_run_tests {} { + + set workload_exec [compile_ocount_workload "workload_ocount/load.c"] + +send "ocount_run_tests\n" + + # Check the brief format counting cycles gives non-zero count + do_test_ocount_cycle_test $workload_exec "--brief-format" + + # Check the cycles count gives non-zero count + do_test_ocount_cycle_test $workload_exec "" + + # Check counts for workload scale as expected + do_test_ocount_scaling $workload_exec + + # Check counts for workload for user, kernel, user and kernel modes + do_test_ocount_modes $workload_exec + +} + + +#main +ocount_run_tests diff --git a/testsuite/workload_ocount/load.c b/testsuite/workload_ocount/load.c new file mode 100644 index 0000000..d4fafcb --- /dev/null +++ b/testsuite/workload_ocount/load.c @@ -0,0 +1,81 @@ +/* load.c + * Copyright (C) 2013 IBM + * + * Author: Carl Love <ca...@us...> + * + * This file is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include <errno.h> +#include <stdio.h> +#include <stdlib.h> +#include <sys/time.h> +#include <sched.h> +#include <link.h> + +#define ARRAY_SIZE 7000 +#define ARRAY_STEP 128/sizeof(int) + +#define REPORT_FREQ 100 +#define NUM_ITER 20000000 +#define UPPER_LIMIT 10000 +#define LOWER_LIMIT 10 + +main(int argc, char *argv[]) +{ + + int array[ARRAY_SIZE]; + int i, j; + int sum=0; + int direction=1; + + int sum_add(int sum, int value); + int sum_sub(int sum, int value); + + for (i=0; i<ARRAY_SIZE; i++) { + array[i] = i; + } + + for (i=1; i<=NUM_ITER; i++) { + for (j=0; j<ARRAY_SIZE; j=j+ARRAY_STEP) { + + if (sum > UPPER_LIMIT) { + direction = 0; + } + + if (sum < LOWER_LIMIT) { + direction = 1; + } + + if (direction == 1) { + sum=sum_add(sum, array[j]); + } + + if (direction == 0) { + sum=sum_sub(sum, array[j]); + } + } + } +} + +int sum_add(int sum, int value) +{ + return(sum+value); +} + +int sum_sub(int sum, int value) +{ + return(sum-value); +} -- 1.7.12.rc1.22.gbfbf4d4 |
From: Carl E. L. <ce...@li...> - 2013-08-16 16:14:25
|
Maynard: The previous attempt at sending the patch had the string "0001-Add-test-for-the-ocount-tool.patch" importantly pasted into the patch during the final patch review. I have cleaned up the patch. Sorry about the screw up. Carl Love ------------------------------------------------------------ Add test for the ocount tool The patch adds support for two additional testuites for testing the ocount tool. The first testsuite runs a series of tests on the ocount tool. The tests include: - each event generates non-zero counts - counting for each event for an interval of n seconds, 2*n and 4*n scale as expected - the sum of the counts for each event in user mode only, kernel mode only match counting in user and kernel mode - the output using the brief output format is verified The above tests are run when the tool "oprofile" or "oprofile-ocount" are run. The second testsuite includes the additional test: - counting cycles for an interval of n seconds matches n*proc_frequency The testsuite is only run when the tool "cycle-check-ocount" is specified. The testsuite checks the event count against the reported CPU frequency which may or may not be the actual operating CPU frequency. The reported frequency and the actual frequency may differ if the CPU is running in the Intel "turbo" mode or at a lower frequency for thermal management. The user may need to manually verify any test failures based on the actual operating CPU frequency not the reported CPU frequency. Signed-off-by: Carl Love <ce...@us...> --- testsuite/README | 111 +++++++++---- .../cycle-check-ocount/ocount-cycle-check-run.exp | 89 ++++++++++ testsuite/lib/ocount_util.exp | 185 +++++++++++++++++++++ testsuite/oprofile-ocount/ocount-run.exp | 184 ++++++++++++++++++++ testsuite/workload_ocount/load.c | 81 +++++++++ 5 files changed, 619 insertions(+), 31 deletions(-) create mode 100644 testsuite/cycle-check-ocount/ocount-cycle-check-run.exp create mode 100644 testsuite/lib/ocount_util.exp create mode 100644 testsuite/oprofile-ocount/ocount-run.exp create mode 100644 testsuite/workload_ocount/load.c diff --git a/testsuite/README b/testsuite/README index 1218fc2..b2f8692 100644 --- a/testsuite/README +++ b/testsuite/README @@ -1,6 +1,7 @@ This testsuite directory contains a simple testsuite to check the functionality of OProfile on the machine. The testsuite supports testing the previous user interface using opcontrol and the new operf interface. +The testsuite also includes tests for the ocount tool. The testsuite consists of several workloads. Each workload is run using an architecture specific list of event sets. The OProfile report for @@ -8,49 +9,99 @@ each workload run is then checked to make sure the expected symbols that are specific to that workload are found in the profile report. -Running the opcontrol OProfile testsuite requires the following: +Profiling Tool tests --Superuser privileges --The dejagnu and expect packages are installed --The OProfile commands to be on the PATH + Running the opcontrol OProfile testsuite requires the following: -The opcontrol tests are run by being in this directory and running the -following command: + -Superuser privileges + -The dejagnu and expect packages are installed + -The OProfile commands to be on the PATH -runtest --tool oprofile-opcontrol + The opcontrol tests are run by being in this directory and running the + following command: + runtest --tool oprofile-opcontrol -The system-wide operf OProfile testsuite requires the following: --Superuser privileges --The dejagnu and expect packages are installed --The OProfile commands to be on the PATH + The system-wide operf OProfile testsuite requires the following: -The system-wide operf tests are run by being in this directory and running -the following command: + -Superuser privileges + -The dejagnu and expect packages are installed + -The OProfile commands to be on the PATH -runtest --tool oprofile-operf + The system-wide operf tests are run by being in this directory and running + the following command: -The single process operf testsuite requires the following: + runtest --tool oprofile-operf --The dejagnu and expect packages are installed --The OProfile commands to be on the PATH --Note, you should run the command "opcontrol --reset" as root to make sure - there are no opcontrol data samples around that opreport might accidentally - pickup on. The testsuite is setup so it can run as a regular user. Regular - users can't delete the opcontrol data. --In order to run oprofile--single_process as an normal user, the testsuite - directories need to be writable by normal user running the test. + The single process operf testsuite requires the following: -The single process operf tests are run by being in this directory and running -the following command as either root or a normal user: + -The dejagnu and expect packages are installed + -The OProfile commands to be on the PATH + -Note, you should run the command "opcontrol --reset" as root to make sure + there are no opcontrol data samples around that opreport might accidentally + pickup on. The testsuite is setup so it can run as a regular user. Regular + users can't delete the opcontrol data. + -In order to run oprofile-single_process as an normal user, the testsuite + directories need to be writable by normal user running the test. -runtest --tool oprofile-single_process + The single process operf tests are run by being in this directory and running + the following command as either root or a normal user: -To run all three testsuites (provided the requirements for all of them are -met), use the command + runtest --tool oprofile-single_process -runtest --tool oprofile + +Event Counting tool tests + + The testsuite oprofile-ocount tests the event counting tool ocount. The + testsuite runs a series of tests using the ocount tool. + + The tests include: + + - each sample generates non-zero counts + - counting cycles for an interval of n seconds, 2*n and 4*n scale as + expected + - the sum of the counts cycles in user mode only, kernel mode + only match counting cycles in user and kernel mode + + The ocount tests are run by being in this directory and running the following + command as either root or a normal user: + + runtest --tool oprofile-ocount + + + The testsuite cycle-check-ocount tests tool ocount counting of cycles versus + the reported CPU frequency. The reported frequency is not correct for all + platforms. Some of the Intel processors can be running in Turbo mode. In + Turbo mode the CPU frequency is higher then the reported frequency. The + CPU frequency may be lowered by automatic thermal regulation circuits for + heat management. This is true for the Power processors. In this case, the + actual CPU frequency may be lower then the reported frequency. These tests + were put into a separate tool as they should only be run when the user + has a good understanding of what the actual rather then reported frequency + for the CPU is. + + The tests include: + + - each sample generates non-zero counts + - counting cycles for an interval of n seconds matches n*proc_frequency + + The tests will pass or fail based on the reported frequency. The user will + need to manually verify if the reported count makes sense for the actual + CPU frequency. + + The cycle check tests are run by being in this directory and running the + following command as either root or a normal user: + + runtest --tool cycle-check-ocount + + +Combined profiling and counting tests + + To run all of the testsuites, with the exception of the cycle check tests, + (provided the requirements for all of them are met), use the command + + runtest --tool oprofile The tests will run and at the end should print out the number of tests @@ -68,5 +119,3 @@ wrong" and that the basic functionality works. Comments about and additions to the testsuite infrastructure are appreciated. - --Will diff --git a/testsuite/cycle-check-ocount/ocount-cycle-check-run.exp b/testsuite/cycle-check-ocount/ocount-cycle-check-run.exp new file mode 100644 index 0000000..999bf8b --- /dev/null +++ b/testsuite/cycle-check-ocount/ocount-cycle-check-run.exp @@ -0,0 +1,89 @@ +# ocount-cycle-check-run.exp +# Copyright (C) 2013 IBM +# +# author: Carl Love <ca...@us...> +# +# This file is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# + +load_lib "ocount_util.exp" + +proc do_test_ocount_cycle_test {workload_exec output_format} { + + # Get processor frequency in Hz + set freq [get_cpu_frequency] + + # Check that counting cycles for "interval" seconds is equal to the + # processor frequency. Note, we run this with a workload so we don't have + # issues with partitioned machines ceeding the processor because it is + # idle. + + set event [get_cycles_event] + set interval 1 + + set pid [exec $workload_exec > /tmp/junky.xwyesu.xse &] + + # allow workload to reach steady state + local_exec "sleep 1" "" "" 10 + + set result [local_exec "ocount $output_format -e $event --time-interval $interval:1 -p $pid " "" "" 60] + + test_kill_workload $pid + + if {[string match $output_format "--brief-format"]} { + set count [get_event_count_brief $result $event] + } else { + set count [get_event_count $result $event] + } + + local_exec "rm /tmp/junky.xwyesu.xse" "" "" 10 + set test "Count cycles matches CPU frequency" + + # check the count is not zero + if {[check_nonzero_count $count $workload_exec $event] == 0} { + return + } + + # The frequency is specified in units of Hz + set expt_count [expr $interval * $freq] + + # Count of cycles and frequency should be within the following percentage + set percent 5 + + if {[check_expected_value $count $expt_count $percent] == 1} { + pass $test + } else { + fail $test + send "CPU freq $freq Hz, collection interval $interval. \n" + send "Expected count $expt_count, actual count $count. \n" + send "See the README for an explanation about why the \n" + send "ocount-cycle-check test may have failed. \n\n" + } +} + +proc cycle_run_tests {} { + + set workload_exec [compile_ocount_workload "workload_ocount/load.c"] + + # Check the brief format counting cycles versus CPU frequency + do_test_ocount_cycle_test $workload_exec "--brief-format" + + # Check the cycles count versus CPU frequency + do_test_ocount_cycle_test $workload_exec "" +} + + +#main +cycle_run_tests diff --git a/testsuite/lib/ocount_util.exp b/testsuite/lib/ocount_util.exp new file mode 100644 index 0000000..bbf53a7 --- /dev/null +++ b/testsuite/lib/ocount_util.exp @@ -0,0 +1,185 @@ +# ocount_util.exp +# Copyright (C) 2013 IBM +# +# Author: Carl Love <ca...@us...> +# +# This file is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# + +proc get_cycles_event {} { + # local exec output of ophelp output is of the form: + # "0 {CYCLES:100000:0:1:1}". Extract the cycles event + set string [local_exec "ophelp -d" "" "" 10] + set line [regexp -all -inline {\S+} $string] + set word [split [string trimleft [lindex $line 1 ] "\{" ] ":"] + set event [lindex $word 0] + return $event +} + +proc compile_ocount_workload {workload_src } { + + set compiler "cc" + set compile_options " " + set extension [lindex [split $workload_src "."] 1] + set workload_exec [ lindex [split $workload_src "."] 0]_bin + + set result [local_exec "$compiler -o $workload_exec $workload_src $compile_options" "" "" 10 ] + if { [lindex $result 0] == 1 } { + print "\nERROR compiling workload: $workload_src" + print "Compiler error message: $result\n" + } + return $workload_exec +} + +# proc check that the result was with in the expected percent of the +# expected value +proc check_expected_value {actual_value expected_value percent} { + + set min_val [expr ($expected_value * (100 - $percent))/100] + set max_val [expr ($expected_value * (100 + $percent))/100] + + if {$actual_value >= $min_val && $actual_value <= $max_val} { + return 1 + } else { + return 0 + } +} + +proc check_nonzero_count {count workload event} { + set test "Non-zero count for workload $workload and event $event" + if {$count == 0} { + fail $test + return 0 + } else { + pass $test + return 1 + } +} + +proc get_event_count { result symbol} { + + set words [regexp -all -inline {\S+} $result] + + set count 0 + set index 0 + foreach entry $words { + if {[string match $entry $symbol ] == 1} { + set count [lindex $words $index+1 ] + } + set index [expr $index + 1] + } + + # remove all commas in the count value + return [regsub -all {,} $count ""] +} + +proc get_event_count_brief { result symbol} { + # Output is assumed to be in the brief format which + # consists of a string of fields separated by commas + + set words [regexp -all -inline {\S+} $result] + set count 0 + set index 0 + foreach entry $words { + set sub_field [split $entry ","] + set index 0 + foreach sub_entry $sub_field { + if {[string match $sub_entry $symbol ] == 1} { + set count [lindex $sub_field $index+1 ] + break + } + set index [expr $index + 1] + } + } + return $count +} + +proc test_kill_workload {pid} { + set test "Kill the running workload. Note, if this fails it could be the reason the some non-zero tests failing.\n" + set result [local_exec "kill $pid" "" "" 10] + + set words [regexp -all -inline {\S+} $result] + if {[ lindex $words 0] == 0 } { + pass $test + } else { + fail $test + } +} + +proc get_cpu_frequency {} { + set file_exists [file exists "/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq" ] + set freq 0 + + if { $file_exists } { + # The frequency specified in this file seem to be in units of KHz, + # return the frequency in units of Hz. + set fp [open "/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq" r] + set result [read $fp] + if {[ string is integer -strict $result ]} { + set freq [ expr $result * 1000 ] + } + } + + # if the frequency was not found in cpuinfo_max_freq, try /proc/cpuinfo + if { $freq == 0 } { + # The frequency specified in this file may be in MHz, Hz or bogomips. + # Return the frequency in units of Hz. + set fp [open "/proc/cpuinfo" r] + set result [read $fp] + set words [regexp -all -inline {\S+} $result] + set index 0 + + foreach entry $words { + # look for x86/parisc/ia64/x86_64 entry "cpu MHz : %lf" + if {([string match $entry "cpu" ] == 1) && + ([string match [lindex $words $index+1] "MHz"] == 1)} { + set freq_str [lindex $words $index+3 ] + set freq [ expr $freq_str * 1000000 ] + break + } + + # look for ppc/ppc64 entry, "clock : %lfMHz" + if {[string match $entry "clock" ] == 1} { + set freq_str [lindex $words $index+2 ] + set freq_str_trim [string trimright $freq_str "MHz"] + set freq [ expr $freq_str_trim * 1000000 ] + break + } + + # look for alpha, "cycle frequency [Hz] : %lu" + if {([string match $entry "cycle" ] == 1) && + ([string match [lindex $words $index+1] "frequency"] == 1)} { + set freq [lindex $words $index+4 ] + break + } + + # look for sparc64, "Cpu0ClkTck : %lx" + if {[string match $entry "Cpu0ClkTck" ] == 1} { + set freq [lindex $words $index+2 ] + break + } + + # look for mips including loongson2, "BogoMIPS : %lu" + if {[string match $entry "BogoMIPS" ] == 1} { + set freq_str [lindex $words $index+2 ] + set freq [ expr ($freq_str * 2) / 3 ] + break + } + + set index [expr $index + 1] + } + } + return $freq +} diff --git a/testsuite/oprofile-ocount/ocount-run.exp b/testsuite/oprofile-ocount/ocount-run.exp new file mode 100644 index 0000000..964aa1c --- /dev/null +++ b/testsuite/oprofile-ocount/ocount-run.exp @@ -0,0 +1,184 @@ +# ocount-run.exp +# Copyright (C) 2013 IBM +# +# Author: Carl Love <ca...@us...> +# +# This file is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# + +load_lib "ocount_util.exp" + + +proc do_test_ocount_cycle_test {workload_exec output_format} { + + # Check that counting cycles for "interval" seconds is non-zero + set event [get_cycles_event] + set interval 1 + + set pid [exec $workload_exec > /tmp/junky.xwyesu.xse &] + + # allow workload to reach steady state + local_exec "sleep 1" "" "" 10 + + set result [local_exec "ocount $output_format -e $event --time-interval $interval:1 -p $pid " "" "" 60] + + test_kill_workload $pid + + if {[string match $output_format "--brief-format"]} { + set count [get_event_count_brief $result $event] + } else { + set count [get_event_count $result $event] + } + + local_exec "rm /tmp/junky.xwyesu.xse" "" "" 10 + + set test "Count cycles matches CPU frequency" + + # check the count is not zero + if {[check_nonzero_count $count $workload_exec $event] == 0} { + return + } + +} + +proc do_test_ocount_scaling {workload_exec} { + + # The actual result is expected to be within the following percent of the + # actual count + set percent 5 + set interval1 1 + set interval2 2 + set interval4 4 + + set event [get_cycles_event] + + set pid [exec $workload_exec > /tmp/junky.xwyesu.xse &] + + # allow workload to reach steady state + local_exec "sleep 1" "" "" 10 + + set result1 [local_exec "taskset -c 0 ocount -e ${event} --time-interval $interval1:1 -p $pid" "" "" 60] + set result2 [local_exec "taskset -c 0 ocount -e ${event} --time-interval $interval2:1 -p $pid" "" "" 60] + set result4 [local_exec "taskset -c 0 ocount -e ${event} --time-interval $interval4:1 -p $pid" "" "" 60] + + test_kill_workload $pid + + set count1 [get_event_count $result1 $event] + set count2 [get_event_count $result2 $event] + set count4 [get_event_count $result4 $event] + + # Check the results are not zero + check_nonzero_count $count1 $workload_exec $event + check_nonzero_count $count2 $workload_exec $event + check_nonzero_count $count4 $workload_exec $event + + # Check the scaling of the results + set test "Event $event count scales by 2, workload $workload_exec" + + set expt_count [expr $count1 * 2] + if {[check_expected_value $count2 $expt_count $percent] == 1} { + pass $test + } else { + fail $test + send "Initial count $count1, expected count $expt_count, actual $count2\n\n" + } + + local_exec "rm /tmp/junky.xwyesu.xse" "" "" 10 + + set test "Event $event count scales by 4, workload $workload_exec" + set expt_count [expr $count1 * 4] + + if {[check_expected_value $count4 $expt_count $percent] == 1} { + pass $test + } else { + fail $test + send "Initial count $count1, expected count $expt_count, actual $count4\n\n" + } +} + +proc do_test_ocount_modes {workload_exec} { + + # The actual result is expected to be within the following percent of the + # actual count + set percent 5 + set interval 1 + + set event [get_cycles_event] + + # Run the workloads in user only, kernel only, then user and kernel + # modes. + set pid [exec $workload_exec > /tmp/junky.xwyesu.xse &] + + # allow workload to reach steady state + local_exec "sleep 1" "" "" 10 + + set user_result [local_exec "taskset -c 0 ocount -e ${event}:0:0:1 --time-interval $interval:1 -p $pid" "" "" 60] + + set kernel_result [local_exec "taskset -c 0 ocount -e ${event}:0:1:0 --time-interval $interval:1 -p $pid" "" "" 60] + + set user_kernel_result [local_exec "taskset -c 0 ocount -e ${event}:0:1:1 --time-interval $interval:1 -p $pid" "" "" 60] + + test_kill_workload $pid + + local_exec "rm /tmp/junky.xwyesu.xse" "" "" 10 + + # get the counts from the results + set u_count [get_event_count $user_result $event] + set k_count [get_event_count $kernel_result $event] + set u_k_count [get_event_count $user_kernel_result $event] + + # Check the counts are not zero + check_nonzero_count $u_count $workload_exec $event + check_nonzero_count $k_count $workload_exec $event] + check_nonzero_count $u_k_count $workload_exec $event + + # Check the scaling of the results + set test "Event $event, user mode count plus kernel mode count matches user and kernel mode count, workload $workload_exec" + + set expt_count [expr $u_count + $k_count] + + if {[check_expected_value $u_k_count $expt_count $percent] == 1} { + pass $test + } else { + fail $test + send "User count $u_count, kernel count $k_count, sum $expt_count\n" + send "User and kernel count, $u_k_count\n" + } +} + + +proc ocount_run_tests {} { + + set workload_exec [compile_ocount_workload "workload_ocount/load.c"] + +send "ocount_run_tests\n" + + # Check the brief format counting cycles gives non-zero count + do_test_ocount_cycle_test $workload_exec "--brief-format" + + # Check the cycles count gives non-zero count + do_test_ocount_cycle_test $workload_exec "" + + # Check counts for workload scale as expected + do_test_ocount_scaling $workload_exec + + # Check counts for workload for user, kernel, user and kernel modes + do_test_ocount_modes $workload_exec + +} + + +#main +ocount_run_tests diff --git a/testsuite/workload_ocount/load.c b/testsuite/workload_ocount/load.c new file mode 100644 index 0000000..d4fafcb --- /dev/null +++ b/testsuite/workload_ocount/load.c @@ -0,0 +1,81 @@ +/* load.c + * Copyright (C) 2013 IBM + * + * Author: Carl Love <ca...@us...> + * + * This file is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include <errno.h> +#include <stdio.h> +#include <stdlib.h> +#include <sys/time.h> +#include <sched.h> +#include <link.h> + +#define ARRAY_SIZE 7000 +#define ARRAY_STEP 128/sizeof(int) + +#define REPORT_FREQ 100 +#define NUM_ITER 20000000 +#define UPPER_LIMIT 10000 +#define LOWER_LIMIT 10 + +main(int argc, char *argv[]) +{ + + int array[ARRAY_SIZE]; + int i, j; + int sum=0; + int direction=1; + + int sum_add(int sum, int value); + int sum_sub(int sum, int value); + + for (i=0; i<ARRAY_SIZE; i++) { + array[i] = i; + } + + for (i=1; i<=NUM_ITER; i++) { + for (j=0; j<ARRAY_SIZE; j=j+ARRAY_STEP) { + + if (sum > UPPER_LIMIT) { + direction = 0; + } + + if (sum < LOWER_LIMIT) { + direction = 1; + } + + if (direction == 1) { + sum=sum_add(sum, array[j]); + } + + if (direction == 0) { + sum=sum_sub(sum, array[j]); + } + } + } +} + +int sum_add(int sum, int value) +{ + return(sum+value); +} + +int sum_sub(int sum, int value) +{ + return(sum-value); +} -- 1.7.12.rc1.22.gbfbf4d4 |
From: Maynard J. <may...@us...> - 2013-08-16 16:49:03
|
On 08/16/2013 11:14 AM, Carl E. Love wrote: > Maynard: > > The previous attempt at sending the patch had the string > "0001-Add-test-for-the-ocount-tool.patch" importantly pasted into the > patch during the final patch review. I have cleaned up the patch. > Sorry about the screw up. > > Carl Love > > ------------------------------------------------------------ > Add test for the ocount tool > > The patch adds support for two additional testuites for testing the ocount > tool. The first testsuite runs a series of tests on the ocount tool. The > tests include: > > - each event generates non-zero counts > - counting for each event for an interval of n seconds, 2*n and 4*n scale as > expected > - the sum of the counts for each event in user mode only, kernel mode > only match counting in user and kernel mode > - the output using the brief output format is verified Carl, When I first tried running the new tests, I was getting the following error message: FAIL: Non-zero count for workload workload_ocount/load_bin and event spawn I realized I didn't have oprofile installed on my test system, and when I installed it, the tests ran fine. Can you add some up-front check for oprofile support so that the failure message is helpful? Thanks. -Maynard > > The above tests are run when the tool "oprofile" or "oprofile-ocount" are run. > > The second testsuite includes the additional test: > > - counting cycles for an interval of n seconds matches n*proc_frequency > > The testsuite is only run when the tool "cycle-check-ocount" is specified. > The testsuite checks the event count against the reported CPU frequency which > may or may not be the actual operating CPU frequency. The reported frequency > and the actual frequency may differ if the CPU is running in the Intel "turbo" > mode or at a lower frequency for thermal management. The user may need to > manually verify any test failures based on the actual operating CPU frequency > not the reported CPU frequency. > > Signed-off-by: Carl Love <ce...@us...> > --- > testsuite/README | 111 +++++++++---- > .../cycle-check-ocount/ocount-cycle-check-run.exp | 89 ++++++++++ > testsuite/lib/ocount_util.exp | 185 +++++++++++++++++++++ > testsuite/oprofile-ocount/ocount-run.exp | 184 ++++++++++++++++++++ > testsuite/workload_ocount/load.c | 81 +++++++++ > 5 files changed, 619 insertions(+), 31 deletions(-) > create mode 100644 testsuite/cycle-check-ocount/ocount-cycle-check-run.exp > create mode 100644 testsuite/lib/ocount_util.exp > create mode 100644 testsuite/oprofile-ocount/ocount-run.exp > create mode 100644 testsuite/workload_ocount/load.c > > diff --git a/testsuite/README b/testsuite/README > index 1218fc2..b2f8692 100644 > --- a/testsuite/README > +++ b/testsuite/README > @@ -1,6 +1,7 @@ > This testsuite directory contains a simple testsuite to check the > functionality of OProfile on the machine. The testsuite supports testing > the previous user interface using opcontrol and the new operf interface. > +The testsuite also includes tests for the ocount tool. > > The testsuite consists of several workloads. Each workload is run using > an architecture specific list of event sets. The OProfile report for > @@ -8,49 +9,99 @@ each workload run is then checked to make sure the expected symbols that > are specific to that workload are found in the profile report. > > > -Running the opcontrol OProfile testsuite requires the following: > +Profiling Tool tests > > --Superuser privileges > --The dejagnu and expect packages are installed > --The OProfile commands to be on the PATH > + Running the opcontrol OProfile testsuite requires the following: > > -The opcontrol tests are run by being in this directory and running the > -following command: > + -Superuser privileges > + -The dejagnu and expect packages are installed > + -The OProfile commands to be on the PATH > > -runtest --tool oprofile-opcontrol > + The opcontrol tests are run by being in this directory and running the > + following command: > > + runtest --tool oprofile-opcontrol > > -The system-wide operf OProfile testsuite requires the following: > > --Superuser privileges > --The dejagnu and expect packages are installed > --The OProfile commands to be on the PATH > + The system-wide operf OProfile testsuite requires the following: > > -The system-wide operf tests are run by being in this directory and running > -the following command: > + -Superuser privileges > + -The dejagnu and expect packages are installed > + -The OProfile commands to be on the PATH > > -runtest --tool oprofile-operf > + The system-wide operf tests are run by being in this directory and running > + the following command: > > -The single process operf testsuite requires the following: > + runtest --tool oprofile-operf > > --The dejagnu and expect packages are installed > --The OProfile commands to be on the PATH > --Note, you should run the command "opcontrol --reset" as root to make sure > - there are no opcontrol data samples around that opreport might accidentally > - pickup on. The testsuite is setup so it can run as a regular user. Regular > - users can't delete the opcontrol data. > --In order to run oprofile--single_process as an normal user, the testsuite > - directories need to be writable by normal user running the test. > + The single process operf testsuite requires the following: > > -The single process operf tests are run by being in this directory and running > -the following command as either root or a normal user: > + -The dejagnu and expect packages are installed > + -The OProfile commands to be on the PATH > + -Note, you should run the command "opcontrol --reset" as root to make sure > + there are no opcontrol data samples around that opreport might accidentally > + pickup on. The testsuite is setup so it can run as a regular user. Regular > + users can't delete the opcontrol data. > + -In order to run oprofile-single_process as an normal user, the testsuite > + directories need to be writable by normal user running the test. > > -runtest --tool oprofile-single_process > + The single process operf tests are run by being in this directory and running > + the following command as either root or a normal user: > > -To run all three testsuites (provided the requirements for all of them are > -met), use the command > + runtest --tool oprofile-single_process > > -runtest --tool oprofile > + > +Event Counting tool tests > + > + The testsuite oprofile-ocount tests the event counting tool ocount. The > + testsuite runs a series of tests using the ocount tool. > + > + The tests include: > + > + - each sample generates non-zero counts > + - counting cycles for an interval of n seconds, 2*n and 4*n scale as > + expected > + - the sum of the counts cycles in user mode only, kernel mode > + only match counting cycles in user and kernel mode > + > + The ocount tests are run by being in this directory and running the following > + command as either root or a normal user: > + > + runtest --tool oprofile-ocount > + > + > + The testsuite cycle-check-ocount tests tool ocount counting of cycles versus > + the reported CPU frequency. The reported frequency is not correct for all > + platforms. Some of the Intel processors can be running in Turbo mode. In > + Turbo mode the CPU frequency is higher then the reported frequency. The > + CPU frequency may be lowered by automatic thermal regulation circuits for > + heat management. This is true for the Power processors. In this case, the > + actual CPU frequency may be lower then the reported frequency. These tests > + were put into a separate tool as they should only be run when the user > + has a good understanding of what the actual rather then reported frequency > + for the CPU is. > + > + The tests include: > + > + - each sample generates non-zero counts > + - counting cycles for an interval of n seconds matches n*proc_frequency > + > + The tests will pass or fail based on the reported frequency. The user will > + need to manually verify if the reported count makes sense for the actual > + CPU frequency. > + > + The cycle check tests are run by being in this directory and running the > + following command as either root or a normal user: > + > + runtest --tool cycle-check-ocount > + > + > +Combined profiling and counting tests > + > + To run all of the testsuites, with the exception of the cycle check tests, > + (provided the requirements for all of them are met), use the command > + > + runtest --tool oprofile > > > The tests will run and at the end should print out the number of tests > @@ -68,5 +119,3 @@ wrong" and that the basic functionality works. > > Comments about and additions to the testsuite infrastructure are > appreciated. > - > --Will > diff --git a/testsuite/cycle-check-ocount/ocount-cycle-check-run.exp b/testsuite/cycle-check-ocount/ocount-cycle-check-run.exp > new file mode 100644 > index 0000000..999bf8b > --- /dev/null > +++ b/testsuite/cycle-check-ocount/ocount-cycle-check-run.exp > @@ -0,0 +1,89 @@ > +# ocount-cycle-check-run.exp > +# Copyright (C) 2013 IBM > +# > +# author: Carl Love <ca...@us...> > +# > +# This file is free software; you can redistribute it and/or modify > +# it under the terms of the GNU General Public License as published by > +# the Free Software Foundation; either version 2 of the License, or > +# (at your option) any later version. > +# > +# This program is distributed in the hope that it will be useful, > +# but WITHOUT ANY WARRANTY; without even the implied warranty of > +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > +# GNU General Public License for more details. > +# > +# You should have received a copy of the GNU General Public License > +# along with this program; if not, write to the Free Software > +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. > +# > + > +load_lib "ocount_util.exp" > + > +proc do_test_ocount_cycle_test {workload_exec output_format} { > + > + # Get processor frequency in Hz > + set freq [get_cpu_frequency] > + > + # Check that counting cycles for "interval" seconds is equal to the > + # processor frequency. Note, we run this with a workload so we don't have > + # issues with partitioned machines ceeding the processor because it is > + # idle. > + > + set event [get_cycles_event] > + set interval 1 > + > + set pid [exec $workload_exec > /tmp/junky.xwyesu.xse &] > + > + # allow workload to reach steady state > + local_exec "sleep 1" "" "" 10 > + > + set result [local_exec "ocount $output_format -e $event --time-interval $interval:1 -p $pid " "" "" 60] > + > + test_kill_workload $pid > + > + if {[string match $output_format "--brief-format"]} { > + set count [get_event_count_brief $result $event] > + } else { > + set count [get_event_count $result $event] > + } > + > + local_exec "rm /tmp/junky.xwyesu.xse" "" "" 10 > + set test "Count cycles matches CPU frequency" > + > + # check the count is not zero > + if {[check_nonzero_count $count $workload_exec $event] == 0} { > + return > + } > + > + # The frequency is specified in units of Hz > + set expt_count [expr $interval * $freq] > + > + # Count of cycles and frequency should be within the following percentage > + set percent 5 > + > + if {[check_expected_value $count $expt_count $percent] == 1} { > + pass $test > + } else { > + fail $test > + send "CPU freq $freq Hz, collection interval $interval. \n" > + send "Expected count $expt_count, actual count $count. \n" > + send "See the README for an explanation about why the \n" > + send "ocount-cycle-check test may have failed. \n\n" > + } > +} > + > +proc cycle_run_tests {} { > + > + set workload_exec [compile_ocount_workload "workload_ocount/load.c"] > + > + # Check the brief format counting cycles versus CPU frequency > + do_test_ocount_cycle_test $workload_exec "--brief-format" > + > + # Check the cycles count versus CPU frequency > + do_test_ocount_cycle_test $workload_exec "" > +} > + > + > +#main > +cycle_run_tests > diff --git a/testsuite/lib/ocount_util.exp b/testsuite/lib/ocount_util.exp > new file mode 100644 > index 0000000..bbf53a7 > --- /dev/null > +++ b/testsuite/lib/ocount_util.exp > @@ -0,0 +1,185 @@ > +# ocount_util.exp > +# Copyright (C) 2013 IBM > +# > +# Author: Carl Love <ca...@us...> > +# > +# This file is free software; you can redistribute it and/or modify > +# it under the terms of the GNU General Public License as published by > +# the Free Software Foundation; either version 2 of the License, or > +# (at your option) any later version. > +# > +# This program is distributed in the hope that it will be useful, > +# but WITHOUT ANY WARRANTY; without even the implied warranty of > +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > +# GNU General Public License for more details. > +# > +# You should have received a copy of the GNU General Public License > +# along with this program; if not, write to the Free Software > +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. > +# > + > +proc get_cycles_event {} { > + # local exec output of ophelp output is of the form: > + # "0 {CYCLES:100000:0:1:1}". Extract the cycles event > + set string [local_exec "ophelp -d" "" "" 10] > + set line [regexp -all -inline {\S+} $string] > + set word [split [string trimleft [lindex $line 1 ] "\{" ] ":"] > + set event [lindex $word 0] > + return $event > +} > + > +proc compile_ocount_workload {workload_src } { > + > + set compiler "cc" > + set compile_options " " > + set extension [lindex [split $workload_src "."] 1] > + set workload_exec [ lindex [split $workload_src "."] 0]_bin > + > + set result [local_exec "$compiler -o $workload_exec $workload_src $compile_options" "" "" 10 ] > + if { [lindex $result 0] == 1 } { > + print "\nERROR compiling workload: $workload_src" > + print "Compiler error message: $result\n" > + } > + return $workload_exec > +} > + > +# proc check that the result was with in the expected percent of the > +# expected value > +proc check_expected_value {actual_value expected_value percent} { > + > + set min_val [expr ($expected_value * (100 - $percent))/100] > + set max_val [expr ($expected_value * (100 + $percent))/100] > + > + if {$actual_value >= $min_val && $actual_value <= $max_val} { > + return 1 > + } else { > + return 0 > + } > +} > + > +proc check_nonzero_count {count workload event} { > + set test "Non-zero count for workload $workload and event $event" > + if {$count == 0} { > + fail $test > + return 0 > + } else { > + pass $test > + return 1 > + } > +} > + > +proc get_event_count { result symbol} { > + > + set words [regexp -all -inline {\S+} $result] > + > + set count 0 > + set index 0 > + foreach entry $words { > + if {[string match $entry $symbol ] == 1} { > + set count [lindex $words $index+1 ] > + } > + set index [expr $index + 1] > + } > + > + # remove all commas in the count value > + return [regsub -all {,} $count ""] > +} > + > +proc get_event_count_brief { result symbol} { > + # Output is assumed to be in the brief format which > + # consists of a string of fields separated by commas > + > + set words [regexp -all -inline {\S+} $result] > + set count 0 > + set index 0 > + foreach entry $words { > + set sub_field [split $entry ","] > + set index 0 > + foreach sub_entry $sub_field { > + if {[string match $sub_entry $symbol ] == 1} { > + set count [lindex $sub_field $index+1 ] > + break > + } > + set index [expr $index + 1] > + } > + } > + return $count > +} > + > +proc test_kill_workload {pid} { > + set test "Kill the running workload. Note, if this fails it could be the reason the some non-zero tests failing.\n" > + set result [local_exec "kill $pid" "" "" 10] > + > + set words [regexp -all -inline {\S+} $result] > + if {[ lindex $words 0] == 0 } { > + pass $test > + } else { > + fail $test > + } > +} > + > +proc get_cpu_frequency {} { > + set file_exists [file exists "/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq" ] > + set freq 0 > + > + if { $file_exists } { > + # The frequency specified in this file seem to be in units of KHz, > + # return the frequency in units of Hz. > + set fp [open "/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq" r] > + set result [read $fp] > + if {[ string is integer -strict $result ]} { > + set freq [ expr $result * 1000 ] > + } > + } > + > + # if the frequency was not found in cpuinfo_max_freq, try /proc/cpuinfo > + if { $freq == 0 } { > + # The frequency specified in this file may be in MHz, Hz or bogomips. > + # Return the frequency in units of Hz. > + set fp [open "/proc/cpuinfo" r] > + set result [read $fp] > + set words [regexp -all -inline {\S+} $result] > + set index 0 > + > + foreach entry $words { > + # look for x86/parisc/ia64/x86_64 entry "cpu MHz : %lf" > + if {([string match $entry "cpu" ] == 1) && > + ([string match [lindex $words $index+1] "MHz"] == 1)} { > + set freq_str [lindex $words $index+3 ] > + set freq [ expr $freq_str * 1000000 ] > + break > + } > + > + # look for ppc/ppc64 entry, "clock : %lfMHz" > + if {[string match $entry "clock" ] == 1} { > + set freq_str [lindex $words $index+2 ] > + set freq_str_trim [string trimright $freq_str "MHz"] > + set freq [ expr $freq_str_trim * 1000000 ] > + break > + } > + > + # look for alpha, "cycle frequency [Hz] : %lu" > + if {([string match $entry "cycle" ] == 1) && > + ([string match [lindex $words $index+1] "frequency"] == 1)} { > + set freq [lindex $words $index+4 ] > + break > + } > + > + # look for sparc64, "Cpu0ClkTck : %lx" > + if {[string match $entry "Cpu0ClkTck" ] == 1} { > + set freq [lindex $words $index+2 ] > + break > + } > + > + # look for mips including loongson2, "BogoMIPS : %lu" > + if {[string match $entry "BogoMIPS" ] == 1} { > + set freq_str [lindex $words $index+2 ] > + set freq [ expr ($freq_str * 2) / 3 ] > + break > + } > + > + set index [expr $index + 1] > + } > + } > + return $freq > +} > diff --git a/testsuite/oprofile-ocount/ocount-run.exp b/testsuite/oprofile-ocount/ocount-run.exp > new file mode 100644 > index 0000000..964aa1c > --- /dev/null > +++ b/testsuite/oprofile-ocount/ocount-run.exp > @@ -0,0 +1,184 @@ > +# ocount-run.exp > +# Copyright (C) 2013 IBM > +# > +# Author: Carl Love <ca...@us...> > +# > +# This file is free software; you can redistribute it and/or modify > +# it under the terms of the GNU General Public License as published by > +# the Free Software Foundation; either version 2 of the License, or > +# (at your option) any later version. > +# > +# This program is distributed in the hope that it will be useful, > +# but WITHOUT ANY WARRANTY; without even the implied warranty of > +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > +# GNU General Public License for more details. > +# > +# You should have received a copy of the GNU General Public License > +# along with this program; if not, write to the Free Software > +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. > +# > + > +load_lib "ocount_util.exp" > + > + > +proc do_test_ocount_cycle_test {workload_exec output_format} { > + > + # Check that counting cycles for "interval" seconds is non-zero > + set event [get_cycles_event] > + set interval 1 > + > + set pid [exec $workload_exec > /tmp/junky.xwyesu.xse &] > + > + # allow workload to reach steady state > + local_exec "sleep 1" "" "" 10 > + > + set result [local_exec "ocount $output_format -e $event --time-interval $interval:1 -p $pid " "" "" 60] > + > + test_kill_workload $pid > + > + if {[string match $output_format "--brief-format"]} { > + set count [get_event_count_brief $result $event] > + } else { > + set count [get_event_count $result $event] > + } > + > + local_exec "rm /tmp/junky.xwyesu.xse" "" "" 10 > + > + set test "Count cycles matches CPU frequency" > + > + # check the count is not zero > + if {[check_nonzero_count $count $workload_exec $event] == 0} { > + return > + } > + > +} > + > +proc do_test_ocount_scaling {workload_exec} { > + > + # The actual result is expected to be within the following percent of the > + # actual count > + set percent 5 > + set interval1 1 > + set interval2 2 > + set interval4 4 > + > + set event [get_cycles_event] > + > + set pid [exec $workload_exec > /tmp/junky.xwyesu.xse &] > + > + # allow workload to reach steady state > + local_exec "sleep 1" "" "" 10 > + > + set result1 [local_exec "taskset -c 0 ocount -e ${event} --time-interval $interval1:1 -p $pid" "" "" 60] > + set result2 [local_exec "taskset -c 0 ocount -e ${event} --time-interval $interval2:1 -p $pid" "" "" 60] > + set result4 [local_exec "taskset -c 0 ocount -e ${event} --time-interval $interval4:1 -p $pid" "" "" 60] > + > + test_kill_workload $pid > + > + set count1 [get_event_count $result1 $event] > + set count2 [get_event_count $result2 $event] > + set count4 [get_event_count $result4 $event] > + > + # Check the results are not zero > + check_nonzero_count $count1 $workload_exec $event > + check_nonzero_count $count2 $workload_exec $event > + check_nonzero_count $count4 $workload_exec $event > + > + # Check the scaling of the results > + set test "Event $event count scales by 2, workload $workload_exec" > + > + set expt_count [expr $count1 * 2] > + if {[check_expected_value $count2 $expt_count $percent] == 1} { > + pass $test > + } else { > + fail $test > + send "Initial count $count1, expected count $expt_count, actual $count2\n\n" > + } > + > + local_exec "rm /tmp/junky.xwyesu.xse" "" "" 10 > + > + set test "Event $event count scales by 4, workload $workload_exec" > + set expt_count [expr $count1 * 4] > + > + if {[check_expected_value $count4 $expt_count $percent] == 1} { > + pass $test > + } else { > + fail $test > + send "Initial count $count1, expected count $expt_count, actual $count4\n\n" > + } > +} > + > +proc do_test_ocount_modes {workload_exec} { > + > + # The actual result is expected to be within the following percent of the > + # actual count > + set percent 5 > + set interval 1 > + > + set event [get_cycles_event] > + > + # Run the workloads in user only, kernel only, then user and kernel > + # modes. > + set pid [exec $workload_exec > /tmp/junky.xwyesu.xse &] > + > + # allow workload to reach steady state > + local_exec "sleep 1" "" "" 10 > + > + set user_result [local_exec "taskset -c 0 ocount -e ${event}:0:0:1 --time-interval $interval:1 -p $pid" "" "" 60] > + > + set kernel_result [local_exec "taskset -c 0 ocount -e ${event}:0:1:0 --time-interval $interval:1 -p $pid" "" "" 60] > + > + set user_kernel_result [local_exec "taskset -c 0 ocount -e ${event}:0:1:1 --time-interval $interval:1 -p $pid" "" "" 60] > + > + test_kill_workload $pid > + > + local_exec "rm /tmp/junky.xwyesu.xse" "" "" 10 > + > + # get the counts from the results > + set u_count [get_event_count $user_result $event] > + set k_count [get_event_count $kernel_result $event] > + set u_k_count [get_event_count $user_kernel_result $event] > + > + # Check the counts are not zero > + check_nonzero_count $u_count $workload_exec $event > + check_nonzero_count $k_count $workload_exec $event] > + check_nonzero_count $u_k_count $workload_exec $event > + > + # Check the scaling of the results > + set test "Event $event, user mode count plus kernel mode count matches user and kernel mode count, workload $workload_exec" > + > + set expt_count [expr $u_count + $k_count] > + > + if {[check_expected_value $u_k_count $expt_count $percent] == 1} { > + pass $test > + } else { > + fail $test > + send "User count $u_count, kernel count $k_count, sum $expt_count\n" > + send "User and kernel count, $u_k_count\n" > + } > +} > + > + > +proc ocount_run_tests {} { > + > + set workload_exec [compile_ocount_workload "workload_ocount/load.c"] > + > +send "ocount_run_tests\n" > + > + # Check the brief format counting cycles gives non-zero count > + do_test_ocount_cycle_test $workload_exec "--brief-format" > + > + # Check the cycles count gives non-zero count > + do_test_ocount_cycle_test $workload_exec "" > + > + # Check counts for workload scale as expected > + do_test_ocount_scaling $workload_exec > + > + # Check counts for workload for user, kernel, user and kernel modes > + do_test_ocount_modes $workload_exec > + > +} > + > + > +#main > +ocount_run_tests > diff --git a/testsuite/workload_ocount/load.c b/testsuite/workload_ocount/load.c > new file mode 100644 > index 0000000..d4fafcb > --- /dev/null > +++ b/testsuite/workload_ocount/load.c > @@ -0,0 +1,81 @@ > +/* load.c > + * Copyright (C) 2013 IBM > + * > + * Author: Carl Love <ca...@us...> > + * > + * This file is free software; you can redistribute it and/or modify > + * it under the terms of the GNU General Public License as published by > + * the Free Software Foundation; either version 2 of the License, or > + * (at your option) any later version. > + * > + * This program is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > + * GNU General Public License for more details. > + * > + * You should have received a copy of the GNU General Public License > + * along with this program; if not, write to the Free Software > + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. > + */ > + > +#include <errno.h> > +#include <stdio.h> > +#include <stdlib.h> > +#include <sys/time.h> > +#include <sched.h> > +#include <link.h> > + > +#define ARRAY_SIZE 7000 > +#define ARRAY_STEP 128/sizeof(int) > + > +#define REPORT_FREQ 100 > +#define NUM_ITER 20000000 > +#define UPPER_LIMIT 10000 > +#define LOWER_LIMIT 10 > + > +main(int argc, char *argv[]) > +{ > + > + int array[ARRAY_SIZE]; > + int i, j; > + int sum=0; > + int direction=1; > + > + int sum_add(int sum, int value); > + int sum_sub(int sum, int value); > + > + for (i=0; i<ARRAY_SIZE; i++) { > + array[i] = i; > + } > + > + for (i=1; i<=NUM_ITER; i++) { > + for (j=0; j<ARRAY_SIZE; j=j+ARRAY_STEP) { > + > + if (sum > UPPER_LIMIT) { > + direction = 0; > + } > + > + if (sum < LOWER_LIMIT) { > + direction = 1; > + } > + > + if (direction == 1) { > + sum=sum_add(sum, array[j]); > + } > + > + if (direction == 0) { > + sum=sum_sub(sum, array[j]); > + } > + } > + } > +} > + > +int sum_add(int sum, int value) > +{ > + return(sum+value); > +} > + > +int sum_sub(int sum, int value) > +{ > + return(sum-value); > +} > |
From: Carl E. L. <ce...@li...> - 2013-08-16 18:31:10
|
Maynard: I added the procedure "ocount_get_version {}" to lib/ocount_util.exp. It is similar to the "operf_get_version {}" in lib/operf_util.exp. The ocount_get_version procedure is called by the cycle-check-ocount and oprofile-ocount tools to verify that the ocount tool is supported. If the ocount tool is not supported, the test prints a message to that effect and exits. I tested the changes on systems that have and do not have ocount installed. Carl Love ------------------------------------------------------------------------- Add test for the ocount tool The patch adds support for two additional testsuites for testing the ocount tool. The first testsuite runs a series of tests on the ocount tool. The tests include: - each event generates non-zero counts - counting for each event for an interval of n seconds, 2*n and 4*n scale as expected - the sum of the counts for each event in user mode only, kernel mode only match counting in user and kernel mode - the output using the brief output format is verified The above tests are run when the tool "oprofile" or "oprofile-ocount" are run. The second testsuite includes the additional test: - counting cycles for an interval of n seconds matches n*proc_frequency The testsuite is only run when the tool "cycle-check-ocount" is specified. The testsuite checks the event count against the reported CPU frequency which may or may not be the actual operating CPU frequency. The reported frequency and the actual frequency may differ if the CPU is running in the Intel "turbo" mode or at a lower frequency for thermal management. The user may need to manually verify any test failures based on the actual operating CPU frequency not the reported CPU frequency. Signed-off-by: Carl Love <ce...@us...> --- testsuite/README | 111 ++++++++--- .../cycle-check-ocount/ocount-cycle-check-run.exp | 95 ++++++++++ testsuite/lib/ocount_util.exp | 208 +++++++++++++++++++++ testsuite/oprofile-ocount/ocount-run.exp | 191 +++++++++++++++++++ testsuite/workload_ocount/load.c | 81 ++++++++ 5 files changed, 655 insertions(+), 31 deletions(-) create mode 100644 testsuite/cycle-check-ocount/ocount-cycle-check-run.exp create mode 100644 testsuite/lib/ocount_util.exp create mode 100644 testsuite/oprofile-ocount/ocount-run.exp create mode 100644 testsuite/workload_ocount/load.c diff --git a/testsuite/README b/testsuite/README index 1218fc2..24c926b 100644 --- a/testsuite/README +++ b/testsuite/README @@ -1,6 +1,7 @@ This testsuite directory contains a simple testsuite to check the functionality of OProfile on the machine. The testsuite supports testing the previous user interface using opcontrol and the new operf interface. +The testsuite also includes tests for the ocount tool. The testsuite consists of several workloads. Each workload is run using an architecture specific list of event sets. The OProfile report for @@ -8,49 +9,99 @@ each workload run is then checked to make sure the expected symbols that are specific to that workload are found in the profile report. -Running the opcontrol OProfile testsuite requires the following: +Profiling Tool tests --Superuser privileges --The dejagnu and expect packages are installed --The OProfile commands to be on the PATH + Running the opcontrol OProfile testsuite requires the following: -The opcontrol tests are run by being in this directory and running the -following command: + -Superuser privileges + -The dejagnu and expect packages are installed + -The OProfile commands to be on the PATH -runtest --tool oprofile-opcontrol + The opcontrol tests are run by being in this directory and running the + following command: + runtest --tool oprofile-opcontrol -The system-wide operf OProfile testsuite requires the following: --Superuser privileges --The dejagnu and expect packages are installed --The OProfile commands to be on the PATH + The system-wide operf OProfile testsuite requires the following: -The system-wide operf tests are run by being in this directory and running -the following command: + -Superuser privileges + -The dejagnu and expect packages are installed + -The OProfile commands to be on the PATH -runtest --tool oprofile-operf + The system-wide operf tests are run by being in this directory and running + the following command: -The single process operf testsuite requires the following: + runtest --tool oprofile-operf --The dejagnu and expect packages are installed --The OProfile commands to be on the PATH --Note, you should run the command "opcontrol --reset" as root to make sure - there are no opcontrol data samples around that opreport might accidentally - pickup on. The testsuite is setup so it can run as a regular user. Regular - users can't delete the opcontrol data. --In order to run oprofile--single_process as an normal user, the testsuite - directories need to be writable by normal user running the test. + The single process operf testsuite requires the following: -The single process operf tests are run by being in this directory and running -the following command as either root or a normal user: + -The dejagnu and expect packages are installed + -The OProfile commands to be on the PATH + -Note, you should run the command "opcontrol --reset" as root to make sure + there are no opcontrol data samples around that opreport might accidentally + pickup on. The testsuite is setup so it can run as a regular user. Regular + users can't delete the opcontrol data. + -In order to run oprofile-single_process as an normal user, the testsuite + directories need to be writable by normal user running the test. -runtest --tool oprofile-single_process + The single process operf tests are run by being in this directory and running + the following command as either root or a normal user: -To run all three testsuites (provided the requirements for all of them are -met), use the command + runtest --tool oprofile-single_process -runtest --tool oprofile + +Event Counting tool tests + + The testsuite oprofile-ocount tests the event counting tool ocount. The + testsuite runs a series of tests using the ocount tool. + + The tests include: + + - each sample generates non-zero counts + - counting cycles for an interval of n seconds, 2*n and 4*n scale as + expected + - the sum of the counts cycles in user mode only, kernel mode + only match counting cycles in user and kernel mode + + The ocount tests are run by being in this directory and running the following + command as either root or a normal user: + + runtest --tool oprofile-ocount + + + The testsuite cycle-check-ocount tests tool ocount counting of cycles versus + the reported CPU frequency. The reported frequency is not correct for all + platforms. Some of the Intel processors can be running in Turbo mode. In + Turbo mode the CPU frequency is higher then the reported frequency. The + CPU frequency may be lowered by automatic thermal regulation circuits for + heat management. This is true for the Power processors. In this case, the + actual CPU frequency may be lower then the reported frequency. These tests + were put into a separate tool as they should only be run when the user + has a good understanding of what the actual rather then reported frequency + for the CPU is. + + The tests include: + + - each sample generates non-zero counts + - counting cycles for an interval of n seconds matches n*proc_frequency + + The tests will pass or fail based on the reported frequency. The user will + need to manually verify if the reported count makes sense for the actual + CPU frequency. + + The cycle check tests are run by being in this directory and running the + following command as either root or a normal user: + + runtest --tool cycle-check-ocount + + +Combined profiling and counting tests + + To run all of the testsuites, with the exception of the cycle check tests, + (provided the requirements for all of them are met), use the command + + runtest --tool oprofile The tests will run and at the end should print out the number of tests @@ -68,5 +119,3 @@ wrong" and that the basic functionality works. Comments about and additions to the testsuite infrastructure are appreciated. - --Will diff --git a/testsuite/cycle-check-ocount/ocount-cycle-check-run.exp b/testsuite/cycle-check-ocount/ocount-cycle-check-run.exp new file mode 100644 index 0000000..a43c15e --- /dev/null +++ b/testsuite/cycle-check-ocount/ocount-cycle-check-run.exp @@ -0,0 +1,95 @@ +# ocount-cycle-check-run.exp +# Copyright (C) 2013 IBM +# +# author: Carl Love <ca...@us...> +# +# This file is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# + +load_lib "ocount_util.exp" + +proc do_test_ocount_cycle_test {workload_exec output_format} { + + # Get processor frequency in Hz + set freq [get_cpu_frequency] + + # Check that counting cycles for "interval" seconds is equal to the + # processor frequency. Note, we run this with a workload so we don't have + # issues with partitioned machines ceeding the processor because it is + # idle. + + set event [get_cycles_event] + set interval 1 + + set pid [exec $workload_exec > /tmp/junky.xwyesu.xse &] + + # allow workload to reach steady state + local_exec "sleep 1" "" "" 10 + + set result [local_exec "ocount $output_format -e $event --time-interval $interval:1 -p $pid " "" "" 60] + + test_kill_workload $pid + + if {[string match $output_format "--brief-format"]} { + set count [get_event_count_brief $result $event] + } else { + set count [get_event_count $result $event] + } + + local_exec "rm /tmp/junky.xwyesu.xse" "" "" 10 + set test "Count cycles matches CPU frequency" + + # check the count is not zero + if {[check_nonzero_count $count $workload_exec $event] == 0} { + return + } + + # The frequency is specified in units of Hz + set expt_count [expr $interval * $freq] + + # Count of cycles and frequency should be within the following percentage + set percent 5 + + if {[check_expected_value $count $expt_count $percent] == 1} { + pass $test + } else { + fail $test + send "CPU freq $freq Hz, collection interval $interval. \n" + send "Expected count $expt_count, actual count $count. \n" + send "See the README for an explanation about why the \n" + send "ocount-cycle-check test may have failed. \n\n" + } +} + +proc cycle_run_tests {} { + + set workload_exec [compile_ocount_workload "workload_ocount/load.c"] + + # Check the brief format counting cycles versus CPU frequency + do_test_ocount_cycle_test $workload_exec "--brief-format" + + # Check the cycles count versus CPU frequency + do_test_ocount_cycle_test $workload_exec "" +} + + +#main +ocount_get_version + +if { $ocount_version == 0 } { + send "\nThe OProfile ocount user tool is not supported. Will not run ocount tests.\n" +} else { + cycle_run_tests +} diff --git a/testsuite/lib/ocount_util.exp b/testsuite/lib/ocount_util.exp new file mode 100644 index 0000000..8ed528d --- /dev/null +++ b/testsuite/lib/ocount_util.exp @@ -0,0 +1,208 @@ +# ocount_util.exp +# Copyright (C) 2013 IBM +# +# Author: Carl Love <ca...@us...> +# +# This file is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# + +proc get_cycles_event {} { + # local exec output of ophelp output is of the form: + # "0 {CYCLES:100000:0:1:1}". Extract the cycles event + set string [local_exec "ophelp -d" "" "" 10] + set line [regexp -all -inline {\S+} $string] + set word [split [string trimleft [lindex $line 1 ] "\{" ] ":"] + set event [lindex $word 0] + return $event +} + +proc compile_ocount_workload {workload_src } { + + set compiler "cc" + set compile_options " " + set extension [lindex [split $workload_src "."] 1] + set workload_exec [ lindex [split $workload_src "."] 0]_bin + + set result [local_exec "$compiler -o $workload_exec $workload_src $compile_options" "" "" 10 ] + if { [lindex $result 0] == 1 } { + print "\nERROR compiling workload: $workload_src" + print "Compiler error message: $result\n" + } + return $workload_exec +} + +# proc check that the result was with in the expected percent of the +# expected value +proc check_expected_value {actual_value expected_value percent} { + + set min_val [expr ($expected_value * (100 - $percent))/100] + set max_val [expr ($expected_value * (100 + $percent))/100] + + if {$actual_value >= $min_val && $actual_value <= $max_val} { + return 1 + } else { + return 0 + } +} + +proc check_nonzero_count {count workload event} { + set test "Non-zero count for workload $workload and event $event" + if {$count == 0} { + fail $test + return 0 + } else { + pass $test + return 1 + } +} + +proc get_event_count { result symbol} { + + set words [regexp -all -inline {\S+} $result] + + set count 0 + set index 0 + foreach entry $words { + if {[string match $entry $symbol ] == 1} { + set count [lindex $words $index+1 ] + } + set index [expr $index + 1] + } + + # remove all commas in the count value + return [regsub -all {,} $count ""] +} + +proc get_event_count_brief { result symbol} { + # Output is assumed to be in the brief format which + # consists of a string of fields separated by commas + + set words [regexp -all -inline {\S+} $result] + set count 0 + set index 0 + foreach entry $words { + set sub_field [split $entry ","] + set index 0 + foreach sub_entry $sub_field { + if {[string match $sub_entry $symbol ] == 1} { + set count [lindex $sub_field $index+1 ] + break + } + set index [expr $index + 1] + } + } + return $count +} + +proc test_kill_workload {pid} { + set test "Kill the running workload. Note, if this fails it could be the reason the some non-zero tests failing.\n" + set result [local_exec "kill $pid" "" "" 10] + + set words [regexp -all -inline {\S+} $result] + if {[ lindex $words 0] == 0 } { + pass $test + } else { + fail $test + } +} + +proc get_cpu_frequency {} { + set file_exists [file exists "/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq" ] + set freq 0 + + if { $file_exists } { + # The frequency specified in this file seem to be in units of KHz, + # return the frequency in units of Hz. + set fp [open "/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq" r] + set result [read $fp] + if {[ string is integer -strict $result ]} { + set freq [ expr $result * 1000 ] + } + } + + # if the frequency was not found in cpuinfo_max_freq, try /proc/cpuinfo + if { $freq == 0 } { + # The frequency specified in this file may be in MHz, Hz or bogomips. + # Return the frequency in units of Hz. + set fp [open "/proc/cpuinfo" r] + set result [read $fp] + set words [regexp -all -inline {\S+} $result] + set index 0 + + foreach entry $words { + # look for x86/parisc/ia64/x86_64 entry "cpu MHz : %lf" + if {([string match $entry "cpu" ] == 1) && + ([string match [lindex $words $index+1] "MHz"] == 1)} { + set freq_str [lindex $words $index+3 ] + set freq [ expr $freq_str * 1000000 ] + break + } + + # look for ppc/ppc64 entry, "clock : %lfMHz" + if {[string match $entry "clock" ] == 1} { + set freq_str [lindex $words $index+2 ] + set freq_str_trim [string trimright $freq_str "MHz"] + set freq [ expr $freq_str_trim * 1000000 ] + break + } + + # look for alpha, "cycle frequency [Hz] : %lu" + if {([string match $entry "cycle" ] == 1) && + ([string match [lindex $words $index+1] "frequency"] == 1)} { + set freq [lindex $words $index+4 ] + break + } + + # look for sparc64, "Cpu0ClkTck : %lx" + if {[string match $entry "Cpu0ClkTck" ] == 1} { + set freq [lindex $words $index+2 ] + break + } + + # look for mips including loongson2, "BogoMIPS : %lu" + if {[string match $entry "BogoMIPS" ] == 1} { + set freq_str [lindex $words $index+2 ] + set freq [ expr ($freq_str * 2) / 3 ] + break + } + + set index [expr $index + 1] + } + } + return $freq +} + +proc ocount_get_version {} { + global ocount_version + + set test "OProfile ocount version check" + verbose $test + set result [ local_exec "ocount -v" "" "" 100 ] + + + if {[regexp "\[0-9\]+\(.\[0-9\]+\)+\[a-zA-Z_\]*" $result ocount_version] == 1} { +# Need to make sure the kernel has operf support as well + if {[lindex [local_exec op-check-perfevents "" "" 100] 0] == 0} { + pass $test + } else { + verbose "Kernel does not support ocount\n" + set ocount_version 0 + } + } else { + verbose "unable to determine version" + set ocount_version 0 + warning $test + } +} diff --git a/testsuite/oprofile-ocount/ocount-run.exp b/testsuite/oprofile-ocount/ocount-run.exp new file mode 100644 index 0000000..ea5dac1 --- /dev/null +++ b/testsuite/oprofile-ocount/ocount-run.exp @@ -0,0 +1,191 @@ +# ocount-run.exp +# Copyright (C) 2013 IBM +# +# Author: Carl Love <ca...@us...> +# +# This file is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# + +load_lib "ocount_util.exp" + + +proc do_test_ocount_cycle_test {workload_exec output_format} { + + # Check that counting cycles for "interval" seconds is non-zero + set event [get_cycles_event] + set interval 1 + + set pid [exec $workload_exec > /tmp/junky.xwyesu.xse &] + + # allow workload to reach steady state + local_exec "sleep 1" "" "" 10 + + set result [local_exec "ocount $output_format -e $event --time-interval $interval:1 -p $pid " "" "" 60] + + test_kill_workload $pid + + if {[string match $output_format "--brief-format"]} { + set count [get_event_count_brief $result $event] + } else { + set count [get_event_count $result $event] + } + + local_exec "rm /tmp/junky.xwyesu.xse" "" "" 10 + + set test "Count cycles matches CPU frequency" + + # check the count is not zero + if {[check_nonzero_count $count $workload_exec $event] == 0} { + return + } + +} + +proc do_test_ocount_scaling {workload_exec} { + + # The actual result is expected to be within the following percent of the + # actual count + set percent 5 + set interval1 1 + set interval2 2 + set interval4 4 + + set event [get_cycles_event] + + set pid [exec $workload_exec > /tmp/junky.xwyesu.xse &] + + # allow workload to reach steady state + local_exec "sleep 1" "" "" 10 + + set result1 [local_exec "taskset -c 0 ocount -e ${event} --time-interval $interval1:1 -p $pid" "" "" 60] + set result2 [local_exec "taskset -c 0 ocount -e ${event} --time-interval $interval2:1 -p $pid" "" "" 60] + set result4 [local_exec "taskset -c 0 ocount -e ${event} --time-interval $interval4:1 -p $pid" "" "" 60] + + test_kill_workload $pid + + set count1 [get_event_count $result1 $event] + set count2 [get_event_count $result2 $event] + set count4 [get_event_count $result4 $event] + + # Check the results are not zero + check_nonzero_count $count1 $workload_exec $event + check_nonzero_count $count2 $workload_exec $event + check_nonzero_count $count4 $workload_exec $event + + # Check the scaling of the results + set test "Event $event count scales by 2, workload $workload_exec" + + set expt_count [expr $count1 * 2] + if {[check_expected_value $count2 $expt_count $percent] == 1} { + pass $test + } else { + fail $test + send "Initial count $count1, expected count $expt_count, actual $count2\n\n" + } + + local_exec "rm /tmp/junky.xwyesu.xse" "" "" 10 + + set test "Event $event count scales by 4, workload $workload_exec" + set expt_count [expr $count1 * 4] + + if {[check_expected_value $count4 $expt_count $percent] == 1} { + pass $test + } else { + fail $test + send "Initial count $count1, expected count $expt_count, actual $count4\n\n" + } +} + +proc do_test_ocount_modes {workload_exec} { + + # The actual result is expected to be within the following percent of the + # actual count + set percent 5 + set interval 1 + + set event [get_cycles_event] + + # Run the workloads in user only, kernel only, then user and kernel + # modes. + set pid [exec $workload_exec > /tmp/junky.xwyesu.xse &] + + # allow workload to reach steady state + local_exec "sleep 1" "" "" 10 + + set user_result [local_exec "taskset -c 0 ocount -e ${event}:0:0:1 --time-interval $interval:1 -p $pid" "" "" 60] + + set kernel_result [local_exec "taskset -c 0 ocount -e ${event}:0:1:0 --time-interval $interval:1 -p $pid" "" "" 60] + + set user_kernel_result [local_exec "taskset -c 0 ocount -e ${event}:0:1:1 --time-interval $interval:1 -p $pid" "" "" 60] + + test_kill_workload $pid + + local_exec "rm /tmp/junky.xwyesu.xse" "" "" 10 + + # get the counts from the results + set u_count [get_event_count $user_result $event] + set k_count [get_event_count $kernel_result $event] + set u_k_count [get_event_count $user_kernel_result $event] + + # Check the counts are not zero + check_nonzero_count $u_count $workload_exec $event + check_nonzero_count $k_count $workload_exec $event] + check_nonzero_count $u_k_count $workload_exec $event + + # Check the scaling of the results + set test "Event $event, user mode count plus kernel mode count matches user and kernel mode count, workload $workload_exec" + + set expt_count [expr $u_count + $k_count] + + if {[check_expected_value $u_k_count $expt_count $percent] == 1} { + pass $test + } else { + fail $test + send "User count $u_count, kernel count $k_count, sum $expt_count\n" + send "User and kernel count, $u_k_count\n" + } +} + + +proc ocount_run_tests {} { + + set workload_exec [compile_ocount_workload "workload_ocount/load.c"] + +send "ocount_run_tests\n" + + # Check the brief format counting cycles gives non-zero count + do_test_ocount_cycle_test $workload_exec "--brief-format" + + # Check the cycles count gives non-zero count + do_test_ocount_cycle_test $workload_exec "" + + # Check counts for workload scale as expected + do_test_ocount_scaling $workload_exec + + # Check counts for workload for user, kernel, user and kernel modes + do_test_ocount_modes $workload_exec + +} + + +#main + +ocount_get_version + +if { $ocount_version == 0 } { + send "\nThe OProfile ocount user tool is not supported. Will not run ocount tests.\n" +} else { + ocount_run_tests +} diff --git a/testsuite/workload_ocount/load.c b/testsuite/workload_ocount/load.c new file mode 100644 index 0000000..d4fafcb --- /dev/null +++ b/testsuite/workload_ocount/load.c @@ -0,0 +1,81 @@ +/* load.c + * Copyright (C) 2013 IBM + * + * Author: Carl Love <ca...@us...> + * + * This file is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include <errno.h> +#include <stdio.h> +#include <stdlib.h> +#include <sys/time.h> +#include <sched.h> +#include <link.h> + +#define ARRAY_SIZE 7000 +#define ARRAY_STEP 128/sizeof(int) + +#define REPORT_FREQ 100 +#define NUM_ITER 20000000 +#define UPPER_LIMIT 10000 +#define LOWER_LIMIT 10 + +main(int argc, char *argv[]) +{ + + int array[ARRAY_SIZE]; + int i, j; + int sum=0; + int direction=1; + + int sum_add(int sum, int value); + int sum_sub(int sum, int value); + + for (i=0; i<ARRAY_SIZE; i++) { + array[i] = i; + } + + for (i=1; i<=NUM_ITER; i++) { + for (j=0; j<ARRAY_SIZE; j=j+ARRAY_STEP) { + + if (sum > UPPER_LIMIT) { + direction = 0; + } + + if (sum < LOWER_LIMIT) { + direction = 1; + } + + if (direction == 1) { + sum=sum_add(sum, array[j]); + } + + if (direction == 0) { + sum=sum_sub(sum, array[j]); + } + } + } +} + +int sum_add(int sum, int value) +{ + return(sum+value); +} + +int sum_sub(int sum, int value) +{ + return(sum-value); +} -- 1.7.12.rc1.22.gbfbf4d4 |
From: Maynard J. <may...@us...> - 2013-08-16 18:58:40
|
On 08/16/2013 01:30 PM, Carl E. Love wrote: > Maynard: > > I added the procedure "ocount_get_version {}" to lib/ocount_util.exp. > It is similar to the "operf_get_version {}" in lib/operf_util.exp. The > ocount_get_version procedure is called by the cycle-check-ocount and > oprofile-ocount tools to verify that the ocount tool is supported. If > the ocount tool is not supported, the test prints a message to that > effect and exits. I tested the changes on systems that have and do not > have ocount installed. > > Carl Love > > ------------------------------------------------------------------------- > Add test for the ocount tool Thanks much, Carl! Patch committed. Please do a fresh checkout from the upstream git repo and verify the patch was applied properly. -Maynard > > The patch adds support for two additional testsuites for testing the ocount > tool. The first testsuite runs a series of tests on the ocount tool. The > tests include: > > - each event generates non-zero counts > - counting for each event for an interval of n seconds, 2*n and 4*n scale as > expected > - the sum of the counts for each event in user mode only, kernel mode > only match counting in user and kernel mode > - the output using the brief output format is verified > > The above tests are run when the tool "oprofile" or "oprofile-ocount" are run. > > The second testsuite includes the additional test: > > - counting cycles for an interval of n seconds matches n*proc_frequency > > The testsuite is only run when the tool "cycle-check-ocount" is specified. > The testsuite checks the event count against the reported CPU frequency which > may or may not be the actual operating CPU frequency. The reported frequency > and the actual frequency may differ if the CPU is running in the Intel "turbo" > mode or at a lower frequency for thermal management. The user may need to > manually verify any test failures based on the actual operating CPU frequency > not the reported CPU frequency. > > Signed-off-by: Carl Love <ce...@us...> > --- > testsuite/README | 111 ++++++++--- > .../cycle-check-ocount/ocount-cycle-check-run.exp | 95 ++++++++++ > testsuite/lib/ocount_util.exp | 208 +++++++++++++++++++++ > testsuite/oprofile-ocount/ocount-run.exp | 191 +++++++++++++++++++ > testsuite/workload_ocount/load.c | 81 ++++++++ > 5 files changed, 655 insertions(+), 31 deletions(-) > create mode 100644 testsuite/cycle-check-ocount/ocount-cycle-check-run.exp > create mode 100644 testsuite/lib/ocount_util.exp > create mode 100644 testsuite/oprofile-ocount/ocount-run.exp > create mode 100644 testsuite/workload_ocount/load.c > [snip] |