* gdb.trace/tspeed.exp: New file.
* gdb.trace/tspeed.c: New file.
This commit is contained in:
parent
0672bf414a
commit
3c9057f381
|
@ -1,3 +1,8 @@
|
|||
2011-09-19 Stan Shebs <stan@codesourcery.com>
|
||||
|
||||
* gdb.trace/tspeed.exp: New file.
|
||||
* gdb.trace/tspeed.c: New file.
|
||||
|
||||
2011-09-18 Yao Qi <yao@codesourcery.com>
|
||||
|
||||
* gdb.arch/arm-disp-step.S (test_ldr_literal): Test for Thumb
|
||||
|
|
|
@ -0,0 +1,184 @@
|
|||
/* This testcase is part of GDB, the GNU debugger.
|
||||
|
||||
Copyright 2010, 2011
|
||||
Free Software Foundation, Inc.
|
||||
|
||||
This program 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 3 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, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
/* This program tests tracepoint speed. It consists of two identical
|
||||
loops, which in normal execution will run for exactly the same
|
||||
amount of time. A tracepoint in the second loop will slow it down
|
||||
by some amount, and then the program will report the slowdown
|
||||
observed. */
|
||||
|
||||
/* While primarily designed for the testsuite, it can also be used
|
||||
for interactive testing. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/resource.h>
|
||||
|
||||
int trace_speed_test (void);
|
||||
|
||||
/* We mark these globals as volatile so the speed-measuring loops
|
||||
don't get totally emptied out at high optimization levels. */
|
||||
|
||||
volatile int globfoo, globfoo2, globfoo3;
|
||||
|
||||
volatile short globarr[80000];
|
||||
|
||||
int init_iters = 10 * 1000;
|
||||
|
||||
int iters;
|
||||
|
||||
int max_iters = 1000 * 1000 * 1000;
|
||||
|
||||
int numtps = 1;
|
||||
|
||||
unsigned long long now2, now3, now4, now5;
|
||||
int total1, total2, idelta, mindelta, nsdelta;
|
||||
int nspertp = 0;
|
||||
|
||||
/* Return CPU usage (both user and system - trap-based tracepoints use
|
||||
a bunch of system time). */
|
||||
|
||||
unsigned long long
|
||||
myclock ()
|
||||
{
|
||||
struct timeval tm, tm2;
|
||||
struct rusage ru;
|
||||
getrusage (RUSAGE_SELF, &ru);
|
||||
tm = ru.ru_utime;
|
||||
tm2 = ru.ru_stime;
|
||||
return (((unsigned long long) tm.tv_sec) * 1000000) + tm.tv_usec
|
||||
+ (((unsigned long long) tm2.tv_sec) * 1000000) + tm2.tv_usec;
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
int problem;
|
||||
|
||||
iters = init_iters;
|
||||
|
||||
while (1)
|
||||
{
|
||||
numtps = 1; /* set pre-run breakpoint here */
|
||||
|
||||
/* Keep trying the speed test, with more iterations, until
|
||||
we get to a reasonable number. */
|
||||
while (problem = trace_speed_test())
|
||||
{
|
||||
/* If iteration isn't working, give up. */
|
||||
if (iters > max_iters)
|
||||
{
|
||||
printf ("Gone over %d iterations, giving up\n", max_iters);
|
||||
break;
|
||||
}
|
||||
if (problem < 0)
|
||||
{
|
||||
printf ("Negative times, giving up\n", max_iters);
|
||||
break;
|
||||
}
|
||||
|
||||
iters *= 2;
|
||||
printf ("Doubled iterations to %d\n", iters);
|
||||
}
|
||||
|
||||
printf ("Tracepoint time is %d ns\n", nspertp);
|
||||
|
||||
/* This is for the benefit of interactive testing and attaching,
|
||||
keeps the program from pegging the machine. */
|
||||
sleep (1); /* set post-run breakpoint here */
|
||||
|
||||
/* Issue a little bit of output periodically, so we can see if
|
||||
program is alive or hung. */
|
||||
printf ("%s keeping busy, clock=%llu\n", argv[0], myclock ());
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
trace_speed_test (void)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* Overall loop run time deltas under 1 ms are likely noise and
|
||||
should be ignored. */
|
||||
mindelta = 1000;
|
||||
|
||||
// The bodies of the two loops following must be identical.
|
||||
|
||||
now2 = myclock ();
|
||||
globfoo2 = 1;
|
||||
for (i = 0; i < iters; ++i)
|
||||
{
|
||||
globfoo2 *= 45;
|
||||
globfoo2 += globfoo + globfoo3;
|
||||
globfoo2 *= globfoo + globfoo3;
|
||||
globfoo2 -= globarr[4] + globfoo3;
|
||||
globfoo2 *= globfoo + globfoo3;
|
||||
globfoo2 += globfoo + globfoo3;
|
||||
}
|
||||
now3 = myclock ();
|
||||
total1 = now3 - now2;
|
||||
|
||||
now4 = myclock ();
|
||||
globfoo2 = 1;
|
||||
for (i = 0; i < iters; ++i)
|
||||
{
|
||||
globfoo2 *= 45;
|
||||
globfoo2 += globfoo + globfoo3; /* set tracepoint here */
|
||||
globfoo2 *= globfoo + globfoo3;
|
||||
globfoo2 -= globarr[4] + globfoo3;
|
||||
globfoo2 *= globfoo + globfoo3;
|
||||
globfoo2 += globfoo + globfoo3;
|
||||
}
|
||||
now5 = myclock ();
|
||||
total2 = now5 - now4;
|
||||
|
||||
/* Report on the test results. */
|
||||
|
||||
nspertp = 0;
|
||||
|
||||
idelta = total2 - total1;
|
||||
|
||||
printf ("Loops took %d usec and %d usec, delta is %d usec, %d iterations\n",
|
||||
total1, total2, idelta, iters);
|
||||
|
||||
/* If the second loop seems to run faster, things are weird so give up. */
|
||||
if (idelta < 0)
|
||||
return -1;
|
||||
|
||||
if (idelta > mindelta
|
||||
/* Total test time should be between 2 and 5 seconds. */
|
||||
&& (total1 + total2) > (2 * 1000000)
|
||||
&& (total1 + total2) < (5 * 1000000))
|
||||
{
|
||||
nsdelta = (((unsigned long long) idelta) * 1000) / iters;
|
||||
printf ("Second loop took %d ns longer per iter than first\n", nsdelta);
|
||||
nspertp = nsdelta / numtps;
|
||||
printf ("%d ns per tracepoint\n", nspertp);
|
||||
printf ("Base iteration time %d ns\n",
|
||||
((int) (((unsigned long long) total1) * 1000) / iters));
|
||||
printf ("Total test time %d secs\n", ((int) ((now5 - now2) / 1000000)));
|
||||
|
||||
/* Speed test ran with no problem. */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* The test run was too brief, or otherwise not useful. */
|
||||
return 1;
|
||||
}
|
|
@ -0,0 +1,140 @@
|
|||
# Copyright 2011
|
||||
# Free Software Foundation, Inc.
|
||||
|
||||
# This program 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
load_lib "trace-support.exp"
|
||||
|
||||
set testfile "tspeed"
|
||||
set srcfile ${testfile}.c
|
||||
set executable $testfile
|
||||
set binfile $objdir/$subdir/$executable
|
||||
|
||||
set ipalib $objdir/../gdbserver/libinproctrace.so
|
||||
|
||||
if { [gdb_compile "$srcdir/$subdir/$srcfile" $binfile \
|
||||
executable [concat {debug nowarnings c} libs=$ipalib]] != "" } {
|
||||
untested tspeed.exp
|
||||
return -1
|
||||
}
|
||||
|
||||
# Typically we need a little extra time for this test.
|
||||
set timeout 180
|
||||
|
||||
set ws "\[\r\n\t \]+"
|
||||
set cr "\[\r\n\]+"
|
||||
|
||||
#
|
||||
# Utility procs
|
||||
#
|
||||
|
||||
proc prepare_for_trace_test {} {
|
||||
global executable
|
||||
|
||||
clean_restart $executable
|
||||
|
||||
runto_main
|
||||
|
||||
set testline [gdb_get_line_number "set pre-run breakpoint here"]
|
||||
|
||||
gdb_test "break $testline" ".*" ""
|
||||
|
||||
set testline [gdb_get_line_number "set post-run breakpoint here"]
|
||||
|
||||
gdb_test "break $testline" ".*" ""
|
||||
}
|
||||
|
||||
proc run_trace_experiment {} {
|
||||
|
||||
gdb_test "continue" \
|
||||
".*Breakpoint \[0-9\]+, main .*" \
|
||||
"advance to trace begin"
|
||||
|
||||
gdb_test_no_output "tstart" "start trace experiment"
|
||||
|
||||
gdb_test "continue" \
|
||||
".*Breakpoint \[0-9\]+, main .*" \
|
||||
"advance through tracing"
|
||||
|
||||
gdb_test "tstatus" ".*Trace .*" "check on trace status"
|
||||
|
||||
gdb_test "tstop" "" ""
|
||||
}
|
||||
|
||||
proc gdb_slow_trace_speed_test { } {
|
||||
|
||||
gdb_delete_tracepoints
|
||||
|
||||
gdb_test "print iters = init_iters" ".* = .*";
|
||||
|
||||
set testline [gdb_get_line_number "set tracepoint here"]
|
||||
|
||||
gdb_test "trace $testline if (globfoo != 12 && globfoo2 == 45)" \
|
||||
"Tracepoint \[0-9\]+ at .*" \
|
||||
"set slow tracepoint"
|
||||
|
||||
# Begin the test.
|
||||
run_trace_experiment
|
||||
}
|
||||
|
||||
proc gdb_fast_trace_speed_test { } {
|
||||
|
||||
gdb_delete_tracepoints
|
||||
|
||||
gdb_test "print iters = init_iters" ".* = .*";
|
||||
|
||||
set run_ftrace 0
|
||||
|
||||
set testline [gdb_get_line_number "set tracepoint here"]
|
||||
|
||||
gdb_test_multiple "ftrace $testline if (globfoo != 12 && globfoo2 == 45)" \
|
||||
"set conditional fast tracepoint" {
|
||||
-re "Fast tracepoint \[0-9\]+ at .*" {
|
||||
pass "set conditional fast tracepoint, done"
|
||||
set run_ftrace 1
|
||||
}
|
||||
-re "May not have a fast tracepoint at .*" {
|
||||
pass "set conditional fast tracepoint, not allowed at line"
|
||||
}
|
||||
}
|
||||
|
||||
# If the fast tracepoint couldn't be set, don't bother with the run.
|
||||
if { $run_ftrace == 1 } then {
|
||||
|
||||
# Begin the test.
|
||||
run_trace_experiment
|
||||
}
|
||||
}
|
||||
|
||||
proc gdb_trace_collection_test {} {
|
||||
|
||||
prepare_for_trace_test
|
||||
|
||||
gdb_slow_trace_speed_test
|
||||
|
||||
gdb_fast_trace_speed_test
|
||||
}
|
||||
|
||||
clean_restart $executable
|
||||
runto_main
|
||||
|
||||
# We generously give ourselves one "pass" if we successfully
|
||||
# detect that this test cannot be run on this target!
|
||||
if { ![gdb_target_supports_trace] } then {
|
||||
pass "Current target does not support trace"
|
||||
return 1;
|
||||
}
|
||||
|
||||
# Body of test encased in a proc so we can return prematurely.
|
||||
gdb_trace_collection_test
|
Loading…
Reference in New Issue