benchmarks: remove unixbench
This code appears to be GPL-licensed and thus does not belong in the MINIX3 source tree. Change-Id: I9e88c3ffd8eae8697b629899dba9728863a4413a
This commit is contained in:
parent
65b4a7fa8d
commit
6d315cbf9e
75 changed files with 0 additions and 19988 deletions
|
@ -221,42 +221,6 @@
|
||||||
./usr/ast minix-sys obsolete
|
./usr/ast minix-sys obsolete
|
||||||
./usr/ast/.exrc minix-sys obsolete
|
./usr/ast/.exrc minix-sys obsolete
|
||||||
./usr/ast/.profile minix-sys obsolete
|
./usr/ast/.profile minix-sys obsolete
|
||||||
./usr/benchmarks minix-sys
|
|
||||||
./usr/benchmarks/unixbench minix-sys
|
|
||||||
./usr/benchmarks/unixbench/pgms minix-sys
|
|
||||||
./usr/benchmarks/unixbench/pgms/arithoh minix-sys
|
|
||||||
./usr/benchmarks/unixbench/pgms/context1 minix-sys
|
|
||||||
./usr/benchmarks/unixbench/pgms/dhry2 minix-sys
|
|
||||||
./usr/benchmarks/unixbench/pgms/dhry2reg minix-sys
|
|
||||||
./usr/benchmarks/unixbench/pgms/double minix-sys
|
|
||||||
./usr/benchmarks/unixbench/pgms/execl minix-sys
|
|
||||||
./usr/benchmarks/unixbench/pgms/float minix-sys
|
|
||||||
./usr/benchmarks/unixbench/pgms/fstime minix-sys
|
|
||||||
./usr/benchmarks/unixbench/pgms/hanoi minix-sys
|
|
||||||
./usr/benchmarks/unixbench/pgms/index.base minix-sys
|
|
||||||
./usr/benchmarks/unixbench/pgms/int minix-sys
|
|
||||||
./usr/benchmarks/unixbench/pgms/long minix-sys
|
|
||||||
./usr/benchmarks/unixbench/pgms/looper minix-sys
|
|
||||||
./usr/benchmarks/unixbench/pgms/multi.sh minix-sys
|
|
||||||
./usr/benchmarks/unixbench/pgms/pipe minix-sys
|
|
||||||
./usr/benchmarks/unixbench/pgms/poll minix-sys
|
|
||||||
./usr/benchmarks/unixbench/pgms/register minix-sys
|
|
||||||
./usr/benchmarks/unixbench/pgms/select minix-sys
|
|
||||||
./usr/benchmarks/unixbench/pgms/short minix-sys
|
|
||||||
./usr/benchmarks/unixbench/pgms/spawn minix-sys
|
|
||||||
./usr/benchmarks/unixbench/pgms/syscall minix-sys
|
|
||||||
./usr/benchmarks/unixbench/pgms/tst.sh minix-sys
|
|
||||||
./usr/benchmarks/unixbench/pgms/unixbench.logo minix-sys
|
|
||||||
./usr/benchmarks/unixbench/pgms/whetstone-double minix-sys
|
|
||||||
./usr/benchmarks/unixbench/results minix-sys
|
|
||||||
./usr/benchmarks/unixbench/Run minix-sys
|
|
||||||
./usr/benchmarks/unixbench/run.sh minix-sys
|
|
||||||
./usr/benchmarks/unixbench/testdir minix-sys
|
|
||||||
./usr/benchmarks/unixbench/testdir/cctest.c minix-sys
|
|
||||||
./usr/benchmarks/unixbench/testdir/dc.dat minix-sys
|
|
||||||
./usr/benchmarks/unixbench/testdir/large.txt minix-sys
|
|
||||||
./usr/benchmarks/unixbench/testdir/sort.src minix-sys
|
|
||||||
./usr/benchmarks/unixbench/tmp minix-sys
|
|
||||||
./usr/bin minix-sys
|
./usr/bin minix-sys
|
||||||
./usr/bin/addr2line minix-sys binutils
|
./usr/bin/addr2line minix-sys binutils
|
||||||
./usr/bin/add_route minix-sys
|
./usr/bin/add_route minix-sys
|
||||||
|
|
|
@ -54,12 +54,6 @@
|
||||||
./usr/adm/old
|
./usr/adm/old
|
||||||
./usr/bin
|
./usr/bin
|
||||||
./usr/etc
|
./usr/etc
|
||||||
./usr/benchmarks
|
|
||||||
./usr/benchmarks/unixbench
|
|
||||||
./usr/benchmarks/unixbench/pgms
|
|
||||||
./usr/benchmarks/unixbench/tmp
|
|
||||||
./usr/benchmarks/unixbench/testdir
|
|
||||||
./usr/benchmarks/unixbench/results
|
|
||||||
./usr/games
|
./usr/games
|
||||||
./usr/games/hide gname=games mode=0750
|
./usr/games/hide gname=games mode=0750
|
||||||
./usr/include
|
./usr/include
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
|
|
||||||
SUBDIR+= include .WAIT
|
SUBDIR+= include .WAIT
|
||||||
SUBDIR+= benchmarks
|
|
||||||
SUBDIR+= bin
|
SUBDIR+= bin
|
||||||
SUBDIR+= commands
|
SUBDIR+= commands
|
||||||
SUBDIR+= fs
|
SUBDIR+= fs
|
||||||
|
|
|
@ -1,5 +0,0 @@
|
||||||
# Makefile for the benchmarks.
|
|
||||||
|
|
||||||
SUBDIR=unixbench-5.1.2
|
|
||||||
|
|
||||||
.include <bsd.subdir.mk>
|
|
|
@ -1 +0,0 @@
|
||||||
.include "../Makefile.inc"
|
|
|
@ -1,51 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
|
|
||||||
set -e
|
|
||||||
|
|
||||||
make
|
|
||||||
|
|
||||||
BENCHDIR=/usr/local/benchmarks
|
|
||||||
|
|
||||||
basebenchmarks=`echo *bench*`
|
|
||||||
|
|
||||||
if [ -d $BENCHDIR ]
|
|
||||||
then packagebenchmarks=`(cd $BENCHDIR && echo *bench*)`
|
|
||||||
fi
|
|
||||||
|
|
||||||
runbench() {
|
|
||||||
bench=$1
|
|
||||||
out="Results/$bench.`date +%Y%m%d.%H%M%S`"
|
|
||||||
if [ -d $bench ]
|
|
||||||
then dir=$bench
|
|
||||||
fi
|
|
||||||
if [ -d $BENCHDIR/$bench ]
|
|
||||||
then dir=$BENCHDIR/$bench
|
|
||||||
fi
|
|
||||||
clear
|
|
||||||
echo "Running $dir."
|
|
||||||
echo "Saving output to $out."
|
|
||||||
echo ""
|
|
||||||
( cd $dir && sh run.sh 2>&1 ) | tee $out
|
|
||||||
}
|
|
||||||
|
|
||||||
clear
|
|
||||||
n=1
|
|
||||||
for b in $basebenchmarks $packagebenchmarks
|
|
||||||
do echo "$n. $b"
|
|
||||||
eval "n$n=$b"
|
|
||||||
n=`expr $n + 1`
|
|
||||||
done
|
|
||||||
echo
|
|
||||||
echo -n "Run which benchmark or 'all'? "
|
|
||||||
read bench
|
|
||||||
eval var=\$n$bench
|
|
||||||
if [ "$bench" = all ]
|
|
||||||
then for b in $basebenchmarks $packagebenchmarks
|
|
||||||
do runbench $b
|
|
||||||
done
|
|
||||||
else if [ -d "$var" -o -d "$BENCHDIR/$var" ]
|
|
||||||
then runbench $var
|
|
||||||
else echo "Unknown benchmark $var."
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
fi
|
|
|
@ -1,8 +0,0 @@
|
||||||
SCRIPTS=Run
|
|
||||||
|
|
||||||
SUBDIR=pgms testdir run.sh
|
|
||||||
|
|
||||||
BINDIR=/usr/benchmarks/unixbench
|
|
||||||
|
|
||||||
.include <bsd.prog.mk>
|
|
||||||
.include <bsd.subdir.mk>
|
|
|
@ -1,406 +0,0 @@
|
||||||
Version 5.1.2 -- 2007-12-26
|
|
||||||
|
|
||||||
================================================================
|
|
||||||
To use Unixbench:
|
|
||||||
|
|
||||||
1. UnixBench from version 5.1 on has both system and graphics tests.
|
|
||||||
If you want to use the graphic tests, edit the Makefile and make sure
|
|
||||||
that the line "GRAPHIC_TESTS = defined" is not commented out; then check
|
|
||||||
that the "GL_LIBS" definition is OK for your system. Also make sure
|
|
||||||
that the "x11perf" command is on your search path.
|
|
||||||
|
|
||||||
If you don't want the graphics tests, then comment out the
|
|
||||||
"GRAPHIC_TESTS = defined" line. Note: comment it out, don't
|
|
||||||
set it to anything.
|
|
||||||
|
|
||||||
2. Do "make".
|
|
||||||
|
|
||||||
3. Do "Run" to run the system test; "Run graphics" to run the graphics
|
|
||||||
tests; "Run gindex" to run both.
|
|
||||||
|
|
||||||
You will need perl, as Run is written in perl.
|
|
||||||
|
|
||||||
For more information on using the tests, read "USAGE".
|
|
||||||
|
|
||||||
For information on adding tests into the benchmark, see "WRITING_TESTS".
|
|
||||||
|
|
||||||
|
|
||||||
===================== RELEASE NOTES =====================================
|
|
||||||
|
|
||||||
======================== Dec 07 ==========================
|
|
||||||
|
|
||||||
v5.1.2
|
|
||||||
|
|
||||||
One big fix: if unixbench is installed in a directory whose pathname contains
|
|
||||||
a space, it should now run (previously it failed).
|
|
||||||
|
|
||||||
To avoid possible clashes, the environment variables unixbench uses are now
|
|
||||||
prefixed with "UB_". These are all optional, and for most people will be
|
|
||||||
completely unnecessary, but if you want you can set these:
|
|
||||||
|
|
||||||
UB_BINDIR Directory where the test programs live.
|
|
||||||
UB_TMPDIR Temp directory, for temp files.
|
|
||||||
UB_RESULTDIR Directory to put results in.
|
|
||||||
UB_TESTDIR Directory where the tests are executed.
|
|
||||||
|
|
||||||
And a couple of tiny fixes:
|
|
||||||
* In pgms/tst.sh, changed "sort -n +1" to "sort -n -k 1"
|
|
||||||
* In Makefile, made it clearer that GRAPHIC_TESTS should be commented
|
|
||||||
out (not set to 0) to disable graphics
|
|
||||||
Thanks to nordi for pointing these out.
|
|
||||||
|
|
||||||
|
|
||||||
Ian Smith, December 26, 2007
|
|
||||||
johantheghost at yahoo period com
|
|
||||||
|
|
||||||
|
|
||||||
======================== Oct 07 ==========================
|
|
||||||
|
|
||||||
v5.1.1
|
|
||||||
|
|
||||||
It turns out that the setting of LANG is crucial to the results. This
|
|
||||||
explains why people in different regions were seeing odd results, and also
|
|
||||||
why runlevel 1 produced odd results -- runlevel 1 doesn't set LANG, and
|
|
||||||
hence reverts to ASCII, whereas most people use a UTF-8 encoding, which is
|
|
||||||
much slower in some tests (eg. shell tests).
|
|
||||||
|
|
||||||
So now we manually set LANG to "en_US.utf8", which is configured with the
|
|
||||||
variable "$language". Don't change this if you want to share your results.
|
|
||||||
We also report the language settings in use.
|
|
||||||
|
|
||||||
See "The Language Setting" in USAGE for more info. Thanks to nordi for
|
|
||||||
pointing out the LANG issue.
|
|
||||||
|
|
||||||
I also added the "grep" and "sysexec" tests. These are non-index tests,
|
|
||||||
and "grep" uses the system's grep, so it's not much use for comparing
|
|
||||||
different systems. But some folks on the OpenSuSE list have been finding
|
|
||||||
these useful. They aren't in any of the main test groups; do "Run grep
|
|
||||||
sysexec" to run them.
|
|
||||||
|
|
||||||
Index Changes
|
|
||||||
-------------
|
|
||||||
|
|
||||||
The setting of LANG will affect consistency with systems where this is
|
|
||||||
not the default value. However, it should produce more consistent results
|
|
||||||
in future.
|
|
||||||
|
|
||||||
|
|
||||||
Ian Smith, October 15, 2007
|
|
||||||
johantheghost at yahoo period com
|
|
||||||
|
|
||||||
|
|
||||||
======================== Oct 07 ==========================
|
|
||||||
|
|
||||||
v5.1
|
|
||||||
|
|
||||||
The major new feature in this version is the addition of graphical
|
|
||||||
benchmarks. Since these may not compile on all systems, you can enable/
|
|
||||||
disable them with the GRAPHIC_TESTS variable in the Makefile.
|
|
||||||
|
|
||||||
As before, each test is run for 3 or 10 iterations. However, we now discard
|
|
||||||
the worst 1/3 of the scores before averaging the remainder. The logic is
|
|
||||||
that a glitch in the system (background process waking up, for example) may
|
|
||||||
make one or two runs go slow, so let's discard those. Hopefully this will
|
|
||||||
produce more consistent and repeatable results. Check the log file
|
|
||||||
for a test run to see the discarded scores.
|
|
||||||
|
|
||||||
Made the tests compile and run on x86-64/Linux (fixed an execl bug passing
|
|
||||||
int instead of pointer).
|
|
||||||
|
|
||||||
Also fixed some general bugs.
|
|
||||||
|
|
||||||
Thanks to Stefan Esser for help and testing / bug reporting.
|
|
||||||
|
|
||||||
Index Changes
|
|
||||||
-------------
|
|
||||||
|
|
||||||
The tests are now divided into categories, and each category generates
|
|
||||||
its own index. This keeps the graphics test results separate from
|
|
||||||
the system tests.
|
|
||||||
|
|
||||||
The "graphics" test and corresponding index are new.
|
|
||||||
|
|
||||||
The "discard the worst scores" strategy should produce slightly higher
|
|
||||||
test scores, but at least they should (hopefully!) be more consistent.
|
|
||||||
The scores should not be higher than the best scores you would have got
|
|
||||||
with 5.0, so this should not be a huge consistency issue.
|
|
||||||
|
|
||||||
Ian Smith, October 11, 2007
|
|
||||||
johantheghost at yahoo period com
|
|
||||||
|
|
||||||
|
|
||||||
======================== Sep 07 ==========================
|
|
||||||
|
|
||||||
v5.0
|
|
||||||
|
|
||||||
All the work I've done on this release is Linux-based, because that's
|
|
||||||
the only Unix I have access to. I've tried to make it more OS-agnostic
|
|
||||||
if anything; for example, it no longer has to figure out the format reported
|
|
||||||
by /usr/bin/time. However, it's possible that portability has been damaged.
|
|
||||||
If anyone wants to fix this, please feel free to mail me patches.
|
|
||||||
|
|
||||||
In particular, the analysis of the system's CPUs is done via /proc/cpuinfo.
|
|
||||||
For systems which don't have this, please make appropriate changes in
|
|
||||||
getCpuInfo() and getSystemInfo().
|
|
||||||
|
|
||||||
The big change has been to make the tests multi-CPU aware. See the
|
|
||||||
"Multiple CPUs" section in "USAGE" for details. Other changes:
|
|
||||||
|
|
||||||
* Completely rewrote Run in Perl; drastically simplified the way data is
|
|
||||||
processed. The confusing system of interlocking shell and awk scripts is
|
|
||||||
now just one script. Various intermediate files used to store and process
|
|
||||||
results are now replaced by Perl data structures internal to the script.
|
|
||||||
|
|
||||||
* Removed from the index runs file system read and write tests which were
|
|
||||||
ignored for the index and wasted about 10 minutes per run (see fstime.c).
|
|
||||||
The read and write tests can now be selected individually. Made fstime.c
|
|
||||||
take parameters, so we no longer need to build 3 versions of it.
|
|
||||||
|
|
||||||
* Made the output file names unique; they are built from
|
|
||||||
hostname-date-sequence.
|
|
||||||
|
|
||||||
* Worked on result reporting, error handling, and logging. See TESTS.
|
|
||||||
We now generate both text and HTML reports.
|
|
||||||
|
|
||||||
* Removed some obsolete files.
|
|
||||||
|
|
||||||
Index Changes
|
|
||||||
-------------
|
|
||||||
|
|
||||||
The index is still based on David Niemi's SPARCstation 20-61 (rated at 10.0),
|
|
||||||
and the intention in the changes I've made has been to keep the tests
|
|
||||||
unchanged, in order to maintain consistency with old result sets.
|
|
||||||
|
|
||||||
However, the following changes have been made to the index:
|
|
||||||
|
|
||||||
* The Pipe-based Context Switching test (context1) was being dropped
|
|
||||||
from the index report in v4.1.0 due to a bug; I've put it back in.
|
|
||||||
|
|
||||||
* I've added shell1 to the index, to get a measure of how the shell tests
|
|
||||||
scale with multiple CPUs (shell8 already exercises all the CPUs, even
|
|
||||||
in single-copy mode). I made up the baseline score for this by
|
|
||||||
extrapolation.
|
|
||||||
|
|
||||||
Both of these test can be dropped, if you wish, by editing the "TEST
|
|
||||||
SPECIFICATIONS" section of Run.
|
|
||||||
|
|
||||||
Ian Smith, September 20, 2007
|
|
||||||
johantheghost at yahoo period com
|
|
||||||
|
|
||||||
======================== Aug 97 ==========================
|
|
||||||
|
|
||||||
v4.1.0
|
|
||||||
|
|
||||||
Double precision Whetstone put in place instead of the old "double" benchmark.
|
|
||||||
|
|
||||||
Removal of some obsolete files.
|
|
||||||
|
|
||||||
"system" suite adds shell8.
|
|
||||||
|
|
||||||
perlbench and poll added as "exhibition" (non-index) benchmarks.
|
|
||||||
|
|
||||||
Incorporates several suggestions by Andre Derrick Balsa <andrewbalsa@usa.net>
|
|
||||||
|
|
||||||
Code cleanups to reduce compiler warnings by David C Niemi <niemi@tux.org>
|
|
||||||
and Andy Kahn <kahn@zk3.dec.com>; Digital Unix options by Andy Kahn.
|
|
||||||
|
|
||||||
======================== Jun 97 ==========================
|
|
||||||
|
|
||||||
v4.0.1
|
|
||||||
|
|
||||||
Minor change to fstime.c to fix overflow problems on fast machines. Counting
|
|
||||||
is now done in units of 256 (smallest BUFSIZE) and unsigned longs are used,
|
|
||||||
giving another 23 dB or so of headroom ;^) Results should be virtually
|
|
||||||
identical aside from very small rounding errors.
|
|
||||||
|
|
||||||
======================== Dec 95 ==========================
|
|
||||||
|
|
||||||
v4.0
|
|
||||||
|
|
||||||
Byte no longer seems to have anything to do with this benchmark, and I was
|
|
||||||
unable to reach any of the original authors; so I have taken it upon myself
|
|
||||||
to clean it up.
|
|
||||||
|
|
||||||
This is version 4. Major assumptions made in these benchmarks have changed
|
|
||||||
since they were written, but they are nonetheless popular (particularly for
|
|
||||||
measuring hardware for Linux). Some changes made:
|
|
||||||
|
|
||||||
- The biggest change is to put a lot more operating system-oriented
|
|
||||||
tests into the index. I experimented for a while with a decibel-like
|
|
||||||
logarithmic scale, but finally settled on using a geometric mean for
|
|
||||||
the final index (the individual scores are a normalized, and their
|
|
||||||
logs are averaged; the resulting value is exponentiated).
|
|
||||||
|
|
||||||
"George", certain SPARCstation 20-61 with 128 MB RAM, a SPARC Storage
|
|
||||||
Array, and Solaris 2.3 is my new baseline; it is rated at 10.0 in each
|
|
||||||
of the index scores for a final score of 10.0.
|
|
||||||
|
|
||||||
Overall I find the geometric averaging is a big improvement for
|
|
||||||
avoiding the skew that was once possible (e.g. a Pentium-75 which got
|
|
||||||
40 on the buggy version of fstime, such that fstime accounted for over
|
|
||||||
half of its total score and hence wildly skewed its average).
|
|
||||||
|
|
||||||
I also expect that the new numbers look different enough from the old
|
|
||||||
ones that no one is too likely to casually mistake them for each other.
|
|
||||||
|
|
||||||
I am finding new SPARCs running Solaris 2.4 getting about 15-20, and
|
|
||||||
my 486 DX2-66 Compaq running Linux 1.3.45 got a 9.1. It got
|
|
||||||
understandably poor scores on CPU and FPU benchmarks (a horrible
|
|
||||||
1.8 on "double" and 1.3 on "fsdisk"); but made up for it by averaging
|
|
||||||
over 20 on the OS-oriented benchmarks. The Pentium-75 running
|
|
||||||
Linux gets about 20 (and it *still* runs Windows 3.1 slowly. Oh well).
|
|
||||||
|
|
||||||
- It is difficult to get a modern compiler to even consider making
|
|
||||||
dhry2 without registers, short of turning off *all* optimizations.
|
|
||||||
This is also not a terribly meaningful test, even if it were possible,
|
|
||||||
as noone compiles without registers nowadays. Replaced this benchmark
|
|
||||||
with dhry2reg in the index, and dropped it out of usage in general as
|
|
||||||
it is so hard to make a legitimate one.
|
|
||||||
|
|
||||||
- fstime: this had some bugs when compiled on modern systems which return
|
|
||||||
the number of bytes read/written for read(2)/write(2) calls. The code
|
|
||||||
assumed that a negative return code was given for EOF, but most modern
|
|
||||||
systems return 0 (certainly on SunOS 4, Solaris2, and Linux, which is
|
|
||||||
what counts for me). The old code yielded wildly inflated read scores,
|
|
||||||
would eat up tens of MB of disk space on fast systems, and yielded
|
|
||||||
roughly 50% lower than normal copy scores than it should have.
|
|
||||||
|
|
||||||
Also, it counted partial blocks *fully*; made it count the proportional
|
|
||||||
part of the block which was actually finished.
|
|
||||||
|
|
||||||
Made bigger and smaller variants of fstime which are designed to beat
|
|
||||||
up the disk I/O and the buffer cache, respectively. Adjusted the
|
|
||||||
sleeps so that they are short for short benchmarks.
|
|
||||||
|
|
||||||
- Instead of 1,2,4, and 8-shell benchmarks, went to 1, 8, and 16 to
|
|
||||||
give a broader range of information (and to run 1 fewer test).
|
|
||||||
The only real problem with this is that not many iterations get
|
|
||||||
done with 16 at a time on slow systems, so there are some significant
|
|
||||||
rounding errors; 8 therefore still used for the benchmark. There is
|
|
||||||
also the problem that the last (uncompleted) loop is counted as a full
|
|
||||||
loop, so it is impossible to score below 1.0 lpm (which gave my laptop
|
|
||||||
a break). Probably redesigning Shell to do each loop a bit more
|
|
||||||
quickly (but with less intensity) would be a good idea.
|
|
||||||
|
|
||||||
This benchmark appears to be very heavily influenced by the speed
|
|
||||||
of the loader, by which shell is being used as /bin/sh, and by how
|
|
||||||
well-compiled some of the common shell utilities like grep, sed, and
|
|
||||||
sort are. With a consistent tool set it is also a good indicator of
|
|
||||||
the bandwidth between main memory and the CPU (e.g. Pentia score about
|
|
||||||
twice as high as 486es due to their 64-bit bus). Small, sometimes
|
|
||||||
broken shells like "ash-linux" do particularly well here, while big,
|
|
||||||
robust shells like bash do not.
|
|
||||||
|
|
||||||
- "dc" is a somewhat iffy benchmark, because there are two versions of
|
|
||||||
it floating around, one being small, very fast, and buggy, and one
|
|
||||||
being more correct but slow. It was never in the index anyway.
|
|
||||||
|
|
||||||
- Execl is a somewhat troubling benchmark in that it yields much higher
|
|
||||||
scores if compiled statically. I frown on this practice because it
|
|
||||||
distorts the scores away from reflecting how programs are really used
|
|
||||||
(i.e. dynamically linked).
|
|
||||||
|
|
||||||
- Arithoh is really more an indicator of the compiler quality than of
|
|
||||||
the computer itself. For example, GCC 2.7.x with -O2 and a few extra
|
|
||||||
options optimizes much of it away, resulting in about a 1200% boost
|
|
||||||
to the score. Clearly not a good one for the index.
|
|
||||||
|
|
||||||
I am still a bit unhappy with the variance in some of the benchmarks, most
|
|
||||||
notably the fstime suite; and with how long it takes to run. But I think
|
|
||||||
it gets significantly more reliable results than the older version in less
|
|
||||||
time.
|
|
||||||
|
|
||||||
If anyone has ideas on how to make these benchmarks faster, lower-variance,
|
|
||||||
or more meaningful; or has nice, new, portable benchmarks to add, don't
|
|
||||||
hesitate to e-mail me.
|
|
||||||
|
|
||||||
David C Niemi <niemi@tux.org> 7 Dec 1995
|
|
||||||
|
|
||||||
======================== May 91 ==========================
|
|
||||||
This is version 3. This set of programs should be able to determine if
|
|
||||||
your system is BSD or SysV. (It uses the output format of time (1)
|
|
||||||
to see. If you have any problems, contact me (by email,
|
|
||||||
preferably): ben@bytepb.byte.com
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
The document doc/bench.doc describes the basic flow of the
|
|
||||||
benchmark system. The document doc/bench3.doc describes the major
|
|
||||||
changes in design of this version. As a user of the benchmarks,
|
|
||||||
you should understand some of the methods that have been
|
|
||||||
implemented to generate loop counts:
|
|
||||||
|
|
||||||
Tests that are compiled C code:
|
|
||||||
The function wake_me(second, func) is included (from the file
|
|
||||||
timeit.c). This function uses signal and alarm to set a countdown
|
|
||||||
for the time request by the benchmark administration script
|
|
||||||
(Run). As soon as the clock is started, the test is run with a
|
|
||||||
counter keeping track of the number of loops that the test makes.
|
|
||||||
When alarm sends its signal, the loop counter value is sent to stderr
|
|
||||||
and the program terminates. Since the time resolution, signal
|
|
||||||
trapping and other factors don't insure that the test is for the
|
|
||||||
precise time that was requested, the test program is also run
|
|
||||||
from the time (1) command. The real time value returned from time
|
|
||||||
(1) is what is used in calculating the number of loops per second
|
|
||||||
(or minute, depending on the test). As is obvious, there is some
|
|
||||||
overhead time that is not taken into account, therefore the
|
|
||||||
number of loops per second is not absolute. The overhead of the
|
|
||||||
test starting and stopping and the signal and alarm calls is
|
|
||||||
common to the overhead of real applications. If a program loads
|
|
||||||
quickly, the number of loops per second increases; a phenomenon
|
|
||||||
that favors systems that can load programs quickly. (Setting the
|
|
||||||
sticky bit of the test programs is not considered fair play.)
|
|
||||||
|
|
||||||
Test that use existing UNIX programs or shell scripts:
|
|
||||||
The concept is the same as that of compiled tests, except the
|
|
||||||
alarm and signal are contained in separate compiled program,
|
|
||||||
looper (source is looper.c). Looper uses an execvp to invoke the
|
|
||||||
test with its arguments. Here, the overhead includes the
|
|
||||||
invocation and execution of looper.
|
|
||||||
|
|
||||||
--
|
|
||||||
|
|
||||||
The index numbers are generated from a baseline file that is in
|
|
||||||
pgms/index.base. You can put tests that you wish in this file.
|
|
||||||
All you need to do is take the results/log file from your
|
|
||||||
baseline machine, edit out the comment and blank lines, and sort
|
|
||||||
the result (vi/ex command: 1,$!sort). The sort in necessary
|
|
||||||
because the process of generating the index report uses join (1).
|
|
||||||
You can regenerate the reports by running "make report."
|
|
||||||
|
|
||||||
--
|
|
||||||
|
|
||||||
========================= Jan 90 =============================
|
|
||||||
Tom Yager has joined the effort here at BYTE; he is responsible
|
|
||||||
for many refinements in the UNIX benchmarks.
|
|
||||||
|
|
||||||
The memory access tests have been deleted from the benchmarks.
|
|
||||||
The file access tests have been reversed so that the test is run
|
|
||||||
for a fixed time. The amount of data transfered (written, read,
|
|
||||||
and copied) is the variable. !WARNING! This test can eat up a
|
|
||||||
large hunk of disk space.
|
|
||||||
|
|
||||||
The initial line of all shell scripts has been changed from the
|
|
||||||
SCO and XENIX form (:) to the more standard form "#! /bin/sh".
|
|
||||||
But different systems handle shell switching differently. Check
|
|
||||||
the documentation on your system and find out how you are
|
|
||||||
supposed to do it. Or, simpler yet, just run the benchmarks from
|
|
||||||
the Bourne shell. (You may need to set SHELL=/bin/sh as well.)
|
|
||||||
|
|
||||||
The options to Run have not been checked in a while. They may no
|
|
||||||
longer function. Next time, I'll get back on them. There needs to
|
|
||||||
be another option added (next time) that halts testing between
|
|
||||||
each test. !WARNING! Some systems have caches that are not getting flushed
|
|
||||||
before the next test or iteration is run. This can cause
|
|
||||||
erroneous values.
|
|
||||||
|
|
||||||
========================= Sept 89 =============================
|
|
||||||
The database (db) programs now have a tuneable message queue space.
|
|
||||||
queue space. The default set in the Run script is 1024 bytes.
|
|
||||||
Other major changes are in the format of the times. We now show
|
|
||||||
Arithmetic and Geometric mean and standard deviation for User
|
|
||||||
Time, System Time, and Real Time. Generally, in reporting, we
|
|
||||||
plan on using the Real Time values with the benchs run with one
|
|
||||||
active user (the bench user). Comments and arguments are requested.
|
|
||||||
|
|
||||||
contact: BIX bensmith or rick_g
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,394 +0,0 @@
|
||||||
Running the Tests
|
|
||||||
=================
|
|
||||||
|
|
||||||
All the tests are executed using the "Run" script in the top-level directory.
|
|
||||||
|
|
||||||
The simplest way to generate results is with the commmand:
|
|
||||||
./Run
|
|
||||||
|
|
||||||
This will run a standard "index" test (see "The BYTE Index" below), and
|
|
||||||
save the report in the "results" directory, with a filename like
|
|
||||||
hostname-2007-09-23-01
|
|
||||||
An HTML version is also saved.
|
|
||||||
|
|
||||||
If you want to generate both the basic system index and the graphics index,
|
|
||||||
then do:
|
|
||||||
./Run gindex
|
|
||||||
|
|
||||||
If your system has more than one CPU, the tests will be run twice -- once
|
|
||||||
with a single copy of each test running at once, and once with N copies,
|
|
||||||
where N is the number of CPUs. Some categories of tests, however (currently
|
|
||||||
the graphics tests) will only run with a single copy.
|
|
||||||
|
|
||||||
Since the tests are based on constant time (variable work), a "system"
|
|
||||||
run usually takes about 29 minutes; the "graphics" part about 18 minutes.
|
|
||||||
A "gindex" run on a dual-core machine will do 2 "system" passes (single-
|
|
||||||
and dual-processing) and one "graphics" run, for a total around one and
|
|
||||||
a quarter hours.
|
|
||||||
|
|
||||||
============================================================================
|
|
||||||
|
|
||||||
Detailed Usage
|
|
||||||
==============
|
|
||||||
|
|
||||||
The Run script takes a number of options which you can use to customise a
|
|
||||||
test, and you can specify the names of the tests to run. The full usage
|
|
||||||
is:
|
|
||||||
|
|
||||||
Run [ -q | -v ] [-i <n> ] [-c <n> [-c <n> ...]] [test ...]
|
|
||||||
|
|
||||||
The option flags are:
|
|
||||||
|
|
||||||
-q Run in quiet mode.
|
|
||||||
-v Run in verbose mode.
|
|
||||||
-i <count> Run <count> iterations for each test -- slower tests
|
|
||||||
use <count> / 3, but at least 1. Defaults to 10 (3 for
|
|
||||||
slow tests).
|
|
||||||
-c <n> Run <n> copies of each test in parallel.
|
|
||||||
|
|
||||||
The -c option can be given multiple times; for example:
|
|
||||||
|
|
||||||
./Run -c 1 -c 4
|
|
||||||
|
|
||||||
will run a single-streamed pass, then a 4-streamed pass. Note that some
|
|
||||||
tests (currently the graphics tests) will only run in a single-streamed pass.
|
|
||||||
|
|
||||||
The remaining non-flag arguments are taken to be the names of tests to run.
|
|
||||||
The default is to run "index". See "Tests" below.
|
|
||||||
|
|
||||||
When running the tests, I do *not* recommend switching to single-user mode
|
|
||||||
("init 1"). This seems to change the results in ways I don't understand,
|
|
||||||
and it's not realistic (unless your system will actually be running in this
|
|
||||||
mode, of course). However, if using a windowing system, you may want to
|
|
||||||
switch to a minimal window setup (for example, log in to a "twm" session),
|
|
||||||
so that randomly-churning background processes don't randomise the results
|
|
||||||
too much. This is particularly true for the graphics tests.
|
|
||||||
|
|
||||||
|
|
||||||
============================================================================
|
|
||||||
|
|
||||||
Tests
|
|
||||||
=====
|
|
||||||
|
|
||||||
The available tests are organised into categories; when generating index
|
|
||||||
scores (see "The BYTE Index" below) the results for each category are
|
|
||||||
produced separately. The categories are:
|
|
||||||
|
|
||||||
system The original Unix system tests (not all are actually
|
|
||||||
in the index)
|
|
||||||
2d 2D graphics tests (not all are actually in the index)
|
|
||||||
3d 3D graphics tests
|
|
||||||
misc Various non-indexed tests
|
|
||||||
|
|
||||||
The following individual tests are available:
|
|
||||||
|
|
||||||
system:
|
|
||||||
dhry2reg Dhrystone 2 using register variables
|
|
||||||
whetstone-double Double-Precision Whetstone
|
|
||||||
syscall System Call Overhead
|
|
||||||
pipe Pipe Throughput
|
|
||||||
context1 Pipe-based Context Switching
|
|
||||||
spawn Process Creation
|
|
||||||
execl Execl Throughput
|
|
||||||
fstime-w File Write 1024 bufsize 2000 maxblocks
|
|
||||||
fstime-r File Read 1024 bufsize 2000 maxblocks
|
|
||||||
fstime File Copy 1024 bufsize 2000 maxblocks
|
|
||||||
fsbuffer-w File Write 256 bufsize 500 maxblocks
|
|
||||||
fsbuffer-r File Read 256 bufsize 500 maxblocks
|
|
||||||
fsbuffer File Copy 256 bufsize 500 maxblocks
|
|
||||||
fsdisk-w File Write 4096 bufsize 8000 maxblocks
|
|
||||||
fsdisk-r File Read 4096 bufsize 8000 maxblocks
|
|
||||||
fsdisk File Copy 4096 bufsize 8000 maxblocks
|
|
||||||
shell1 Shell Scripts (1 concurrent) (runs "looper 60 multi.sh 1")
|
|
||||||
shell8 Shell Scripts (8 concurrent) (runs "looper 60 multi.sh 8")
|
|
||||||
shell16 Shell Scripts (8 concurrent) (runs "looper 60 multi.sh 16")
|
|
||||||
|
|
||||||
2d:
|
|
||||||
2d-rects 2D graphics: rectangles
|
|
||||||
2d-lines 2D graphics: lines
|
|
||||||
2d-circle 2D graphics: circles
|
|
||||||
2d-ellipse 2D graphics: ellipses
|
|
||||||
2d-shapes 2D graphics: polygons
|
|
||||||
2d-aashapes 2D graphics: aa polygons
|
|
||||||
2d-polys 2D graphics: complex polygons
|
|
||||||
2d-text 2D graphics: text
|
|
||||||
2d-blit 2D graphics: images and blits
|
|
||||||
2d-window 2D graphics: windows
|
|
||||||
|
|
||||||
3d:
|
|
||||||
ubgears 3D graphics: gears
|
|
||||||
|
|
||||||
misc:
|
|
||||||
C C Compiler Throughput ("looper 60 $cCompiler cctest.c")
|
|
||||||
arithoh Arithoh (huh?)
|
|
||||||
short Arithmetic Test (short) (this is arith.c configured for
|
|
||||||
"short" variables; ditto for the ones below)
|
|
||||||
int Arithmetic Test (int)
|
|
||||||
long Arithmetic Test (long)
|
|
||||||
float Arithmetic Test (float)
|
|
||||||
double Arithmetic Test (double)
|
|
||||||
dc Dc: sqrt(2) to 99 decimal places (runs
|
|
||||||
"looper 30 dc < dc.dat", using your system's copy of "dc")
|
|
||||||
hanoi Recursion Test -- Tower of Hanoi
|
|
||||||
grep Grep for a string in a large file, using your system's
|
|
||||||
copy of "grep"
|
|
||||||
sysexec Exercise fork() and exec().
|
|
||||||
|
|
||||||
The following pseudo-test names are aliases for combinations of other
|
|
||||||
tests:
|
|
||||||
|
|
||||||
arithmetic Runs arithoh, short, int, long, float, double,
|
|
||||||
and whetstone-double
|
|
||||||
dhry Alias for dhry2reg
|
|
||||||
dhrystone Alias for dhry2reg
|
|
||||||
whets Alias for whetstone-double
|
|
||||||
whetstone Alias for whetstone-double
|
|
||||||
load Runs shell1, shell8, and shell16
|
|
||||||
misc Runs C, dc, and hanoi
|
|
||||||
speed Runs the arithmetic and system groups
|
|
||||||
oldsystem Runs execl, fstime, fsbuffer, fsdisk, pipe, context1,
|
|
||||||
spawn, and syscall
|
|
||||||
system Runs oldsystem plus shell1, shell8, and shell16
|
|
||||||
fs Runs fstime-w, fstime-r, fstime, fsbuffer-w,
|
|
||||||
fsbuffer-r, fsbuffer, fsdisk-w, fsdisk-r, and fsdisk
|
|
||||||
shell Runs shell1, shell8, and shell16
|
|
||||||
|
|
||||||
index Runs the tests which constitute the official index:
|
|
||||||
the oldsystem group, plus dhry2reg, whetstone-double,
|
|
||||||
shell1, and shell8
|
|
||||||
See "The BYTE Index" below for more information.
|
|
||||||
graphics Runs the tests which constitute the graphics index:
|
|
||||||
2d-rects, 2d-ellipse, 2d-aashapes, 2d-text, 2d-blit,
|
|
||||||
2d-window, and ubgears
|
|
||||||
gindex Runs the index and graphics groups, to generate both
|
|
||||||
sets of index results
|
|
||||||
|
|
||||||
all Runs all tests
|
|
||||||
|
|
||||||
|
|
||||||
============================================================================
|
|
||||||
|
|
||||||
The BYTE Index
|
|
||||||
==============
|
|
||||||
|
|
||||||
The purpose of this test is to provide a basic indicator of the performance
|
|
||||||
of a Unix-like system; hence, multiple tests are used to test various
|
|
||||||
aspects of the system's performance. These test results are then compared
|
|
||||||
to the scores from a baseline system to produce an index value, which is
|
|
||||||
generally easier to handle than the raw sores. The entire set of index
|
|
||||||
values is then combined to make an overall index for the system.
|
|
||||||
|
|
||||||
Since 1995, the baseline system has been "George", a SPARCstation 20-61
|
|
||||||
with 128 MB RAM, a SPARC Storage Array, and Solaris 2.3, whose ratings
|
|
||||||
were set at 10.0. (So a system which scores 520 is 52 times faster than
|
|
||||||
this machine.) Since the numbers are really only useful in a relative
|
|
||||||
sense, there's no particular reason to update the base system, so for the
|
|
||||||
sake of consistency it's probably best to leave it alone. George's scores
|
|
||||||
are in the file "pgms/index.base"; this file is used to calculate the
|
|
||||||
index scores for any particular run.
|
|
||||||
|
|
||||||
Over the years, various changes have been made to the set of tests in the
|
|
||||||
index. Although there is a desire for a consistent baseline, various tests
|
|
||||||
have been determined to be misleading, and have been removed; and a few
|
|
||||||
alternatives have been added. These changes are detailed in the README,
|
|
||||||
and should be born in mind when looking at old scores.
|
|
||||||
|
|
||||||
A number of tests are included in the benchmark suite which are not part of
|
|
||||||
the index, for various reasons; these tests can of course be run manually.
|
|
||||||
See "Tests" above.
|
|
||||||
|
|
||||||
|
|
||||||
============================================================================
|
|
||||||
|
|
||||||
Graphics Tests
|
|
||||||
==============
|
|
||||||
|
|
||||||
As of version 5.1, UnixBench now contains some graphics benchmarks. These
|
|
||||||
are intended to give a rough idea of the general graphics performance of
|
|
||||||
a system.
|
|
||||||
|
|
||||||
The graphics tests are in categories "2d" and "3d", so the index scores
|
|
||||||
for these tests are separate from the basic system index. This seems
|
|
||||||
like a sensible division, since the graphics performance of a system
|
|
||||||
depends largely on the graphics adaptor.
|
|
||||||
|
|
||||||
The tests currently consist of some 2D "x11perf" tests and "ubgears".
|
|
||||||
|
|
||||||
* The 2D tests are a selection of the x11perf tests, using the host
|
|
||||||
system's x11perf command (which must be installed and in the search
|
|
||||||
path). Only a few of the x11perf tests are used, in the interests
|
|
||||||
of completing a test run in a reasonable time; if you want to do
|
|
||||||
detailed diagnosis of an X server or graphics chip, then use x11perf
|
|
||||||
directly.
|
|
||||||
|
|
||||||
* The 3D test is "ubgears", a modified version of the familiar "glxgears".
|
|
||||||
This version runs for 5 seconds to "warm up", then performs a timed
|
|
||||||
run and displays the average frames-per-second.
|
|
||||||
|
|
||||||
On multi-CPU systems, the graphics tests will only run in single-processing
|
|
||||||
mode. This is because the meaning of running two copies of a test at once
|
|
||||||
is dubious; and the test windows tend to overlay each other, meaning that
|
|
||||||
the window behind isn't actually doing any work.
|
|
||||||
|
|
||||||
|
|
||||||
============================================================================
|
|
||||||
|
|
||||||
Multiple CPUs
|
|
||||||
=============
|
|
||||||
|
|
||||||
If your system has multiple CPUs, the default behaviour is to run the selected
|
|
||||||
tests twice -- once with one copy of each test program running at a time,
|
|
||||||
and once with N copies, where N is the number of CPUs. (You can override
|
|
||||||
this with the "-c" option; see "Detailed Usage" above.) This is designed to
|
|
||||||
allow you to assess:
|
|
||||||
|
|
||||||
- the performance of your system when running a single task
|
|
||||||
- the performance of your system when running multiple tasks
|
|
||||||
- the gain from your system's implementation of parallel processing
|
|
||||||
|
|
||||||
The results, however, need to be handled with care. Here are the results
|
|
||||||
of two runs on a dual-processor system, one in single-processing mode, one
|
|
||||||
dual-processing:
|
|
||||||
|
|
||||||
Test Single Dual Gain
|
|
||||||
-------------------- ------ ------ ----
|
|
||||||
Dhrystone 2 562.5 1110.3 97%
|
|
||||||
Double Whetstone 320.0 640.4 100%
|
|
||||||
Execl Throughput 450.4 880.3 95%
|
|
||||||
File Copy 1024 759.4 595.9 -22%
|
|
||||||
File Copy 256 535.8 438.8 -18%
|
|
||||||
File Copy 4096 1261.8 1043.4 -17%
|
|
||||||
Pipe Throughput 481.0 979.3 104%
|
|
||||||
Pipe-based Switching 326.8 1229.0 276%
|
|
||||||
Process Creation 917.2 1714.1 87%
|
|
||||||
Shell Scripts (1) 1064.9 1566.3 47%
|
|
||||||
Shell Scripts (8) 1567.7 1709.9 9%
|
|
||||||
System Call Overhead 944.2 1445.5 53%
|
|
||||||
-------------------- ------ ------ ----
|
|
||||||
Index Score: 678.2 1026.2 51%
|
|
||||||
|
|
||||||
As expected, the heavily CPU-dependent tasks -- dhrystone, whetstone,
|
|
||||||
execl, pipe throughput, process creation -- show close to 100% gain when
|
|
||||||
running 2 copies in parallel.
|
|
||||||
|
|
||||||
The Pipe-based Context Switching test measures context switching overhead
|
|
||||||
by sending messages back and forth between 2 processes. I don't know why
|
|
||||||
it shows such a huge gain with 2 copies (ie. 4 processes total) running,
|
|
||||||
but it seems to be consistent on my system. I think this may be an issue
|
|
||||||
with the SMP implementation.
|
|
||||||
|
|
||||||
The System Call Overhead shows a lesser gain, presumably because it uses a
|
|
||||||
lot of CPU time in single-threaded kernel code. The shell scripts test with
|
|
||||||
8 concurrent processes shows no gain -- because the test itself runs 8
|
|
||||||
scripts in parallel, it's already using both CPUs, even when the benchmark
|
|
||||||
is run in single-stream mode. The same test with one process per copy
|
|
||||||
shows a real gain.
|
|
||||||
|
|
||||||
The filesystem throughput tests show a loss, instead of a gain, when
|
|
||||||
multi-processing. That there's no gain is to be expected, since the tests
|
|
||||||
are presumably constrained by the throughput of the I/O subsystem and the
|
|
||||||
disk drive itself; the drop in performance is presumably down to the
|
|
||||||
increased contention for resources, and perhaps greater disk head movement.
|
|
||||||
|
|
||||||
So what tests should you use, how many copies should you run, and how should
|
|
||||||
you interpret the results? Well, that's up to you, since it depends on
|
|
||||||
what it is you're trying to measure.
|
|
||||||
|
|
||||||
Implementation
|
|
||||||
--------------
|
|
||||||
|
|
||||||
The multi-processing mode is implemented at the level of test iterations.
|
|
||||||
During each iteration of a test, N slave processes are started using fork().
|
|
||||||
Each of these slaves executes the test program using fork() and exec(),
|
|
||||||
reads and stores the entire output, times the run, and prints all the
|
|
||||||
results to a pipe. The Run script reads the pipes for each of the slaves
|
|
||||||
in turn to get the results and times. The scores are added, and the times
|
|
||||||
averaged.
|
|
||||||
|
|
||||||
The result is that each test program has N copies running at once. They
|
|
||||||
should all finish at around the same time, since they run for constant time.
|
|
||||||
|
|
||||||
If a test program itself starts off K multiple processes (as with the shell8
|
|
||||||
test), then the effect will be that there are N * K processes running at
|
|
||||||
once. This is probably not very useful for testing multi-CPU performance.
|
|
||||||
|
|
||||||
|
|
||||||
============================================================================
|
|
||||||
|
|
||||||
The Language Setting
|
|
||||||
====================
|
|
||||||
|
|
||||||
The $LANG environment variable determines how programs abnd library
|
|
||||||
routines interpret text. This can have a big impact on the test results.
|
|
||||||
|
|
||||||
If $LANG is set to POSIX, or is left unset, text is treated as ASCII; if
|
|
||||||
it is set to en_US.UTF-8, foir example, then text is treated as being
|
|
||||||
encoded in UTF-8, which is more complex and therefore slower. Setting
|
|
||||||
it to other languages can have varying results.
|
|
||||||
|
|
||||||
To ensure consistency between test runs, the Run script now (as of version
|
|
||||||
5.1.1) sets $LANG to "en_US.utf8".
|
|
||||||
|
|
||||||
This setting which is configured with the variable "$language". You
|
|
||||||
should not change this if you want to share your results to allow
|
|
||||||
comparisons between systems; however, you may want to change it to see
|
|
||||||
how different language settings affect performance.
|
|
||||||
|
|
||||||
Each test report now includes the language settings in use. The reported
|
|
||||||
language is what is set in $LANG, and is not necessarily supported by the
|
|
||||||
system; but we also report the character mapping and collation order which
|
|
||||||
are actually in use (as reported by "locale").
|
|
||||||
|
|
||||||
|
|
||||||
============================================================================
|
|
||||||
|
|
||||||
Interpreting the Results
|
|
||||||
========================
|
|
||||||
|
|
||||||
Interpreting the results of these tests is tricky, and totally depends on
|
|
||||||
what you're trying to measure.
|
|
||||||
|
|
||||||
For example, are you trying to measure how fast your CPU is? Or how good
|
|
||||||
your compiler is? Because these tests are all recompiled using your host
|
|
||||||
system's compiler, the performance of the compiler will inevitably impact
|
|
||||||
the performance of the tests. Is this a problem? If you're choosing a
|
|
||||||
system, you probably care about its overall speed, which may well depend
|
|
||||||
on how good its compiler is; so including that in the test results may be
|
|
||||||
the right answer. But you may want to ensure that the right compiler is
|
|
||||||
used to build the tests.
|
|
||||||
|
|
||||||
On the other hand, with the vast majority of Unix systems being x86 / PC
|
|
||||||
compatibles, running Linux and the GNU C compiler, the results will tend
|
|
||||||
to be more dependent on the hardware; but the versions of the compiler and
|
|
||||||
OS can make a big difference. (I measured a 50% gain between SUSE 10.1
|
|
||||||
and OpenSUSE 10.2 on the same machine.) So you may want to make sure that
|
|
||||||
all your test systems are running the same version of the OS; or at least
|
|
||||||
publish the OS and compuiler versions with your results. Then again, it may
|
|
||||||
be compiler performance that you're interested in.
|
|
||||||
|
|
||||||
The C test is very dubious -- it tests the speed of compilation. If you're
|
|
||||||
running the exact same compiler on each system, OK; but otherwise, the
|
|
||||||
results should probably be discarded. A slower compilation doesn't say
|
|
||||||
anything about the speed of your system, since the compiler may simply be
|
|
||||||
spending more time to super-optimise the code, which would actually make it
|
|
||||||
faster.
|
|
||||||
|
|
||||||
This will be particularly true on architectures like IA-64 (Itanium etc.)
|
|
||||||
where the compiler spends huge amounts of effort scheduling instructions
|
|
||||||
to run in parallel, with a resultant significant gain in execution speed.
|
|
||||||
|
|
||||||
Some tests are even more dubious in terms of host-dependency -- for example,
|
|
||||||
the "dc" test uses the host's version of dc (a calculator program). The
|
|
||||||
version of this which is available can make a huge difference to the score,
|
|
||||||
which is why it's not in the index group. Read through the release notes
|
|
||||||
for more on these kinds of issues.
|
|
||||||
|
|
||||||
Another age-old issue is that of the benchmarks being too trivial to be
|
|
||||||
meaningful. With compilers getting ever smarter, and performing more
|
|
||||||
wide-ranging flow path analyses, the danger of parts of the benchmarks
|
|
||||||
simply being optimised out of existance is always present.
|
|
||||||
|
|
||||||
All in all, the "index" and "gindex" tests (see above) are designed to
|
|
||||||
give a reasonable measure of overall system performance; but the results
|
|
||||||
of any test run should always be used with care.
|
|
||||||
|
|
|
@ -1,133 +0,0 @@
|
||||||
Writing a Test
|
|
||||||
==============
|
|
||||||
|
|
||||||
Writing a test program is pretty easy. Basically, a test is configured via
|
|
||||||
a monster array in the Run script, which specifics (among other things) the
|
|
||||||
program to execute and the parameters to pass it.
|
|
||||||
|
|
||||||
The test itself is simply a program which is given the optional parameters
|
|
||||||
on the command line, and produces logging data on stdout and its results on
|
|
||||||
stderr.
|
|
||||||
|
|
||||||
|
|
||||||
============================================================================
|
|
||||||
|
|
||||||
Test Configuration
|
|
||||||
==================
|
|
||||||
|
|
||||||
In Run, all tests are named in the "$testList" array. This names the
|
|
||||||
individual tests, and also sets up aliases for groups of tests, eg. "index".
|
|
||||||
|
|
||||||
The test specifications are in the "$testParams" array. This contains the
|
|
||||||
details of each individual test as a hash. The fields in the hash are:
|
|
||||||
|
|
||||||
* "logmsg": the full name to display for this test.
|
|
||||||
* "cat": the category this test belongs to; must be configured
|
|
||||||
in $testCats.
|
|
||||||
* "prog": the name of the program to execute; defaults to the name of
|
|
||||||
the benchmark.
|
|
||||||
* "repeat": number of passes to run; either 'short' (the default),
|
|
||||||
'long', or 'single'. For 'short' and 'long', the actual numbers of
|
|
||||||
passes are given by $shortIterCount and $longIterCount, which are
|
|
||||||
configured at the top of the script or by the "-i" flag. 'single'
|
|
||||||
means just run one pass; this should be used for test which do their
|
|
||||||
own multi-pass handling internally.
|
|
||||||
* "stdout": non-0 to add the test's stdout to the log file; defaults to 1.
|
|
||||||
Set to 0 for tests that are too wordy.
|
|
||||||
* "stdin": name of a file to send to the program's stdin; default null.
|
|
||||||
* "options": options to be put on the program's command line; default null.
|
|
||||||
|
|
||||||
|
|
||||||
============================================================================
|
|
||||||
|
|
||||||
Output Format
|
|
||||||
=============
|
|
||||||
|
|
||||||
The results on stderr take the form of a line header and fields, separated
|
|
||||||
by "|" characters. A result line can be one of:
|
|
||||||
|
|
||||||
COUNT|score|timebase|label
|
|
||||||
TIME|seconds
|
|
||||||
ERROR|message
|
|
||||||
|
|
||||||
Any other text on stderr is treated as if it were:
|
|
||||||
|
|
||||||
ERROR|text
|
|
||||||
|
|
||||||
Any output to stdout is placed in a log file, and can be used for debugging.
|
|
||||||
|
|
||||||
COUNT
|
|
||||||
-----
|
|
||||||
|
|
||||||
The COUNT line is the line used to report a test score.
|
|
||||||
|
|
||||||
* "score" is the result, typically the number of loops performed during
|
|
||||||
the run
|
|
||||||
* "timebase" is the time base used for the final report to the user. A
|
|
||||||
value of 1 reports the score as is; a value of 60, for example, divides
|
|
||||||
the time taken by 60 to get loops per minute. Atimebase of zero indicates
|
|
||||||
that the score is already a rate, ie. a count of things per second.
|
|
||||||
* "label" is the label to use for the score; like "lps" (loops per
|
|
||||||
second), etc.
|
|
||||||
|
|
||||||
TIME
|
|
||||||
----
|
|
||||||
|
|
||||||
The TIME line is optionally used to report the time taken. The Run script
|
|
||||||
normally measures this, but if your test has signifant overhead outside the
|
|
||||||
actual test loop, you should use TIME to report the time taken for the actual
|
|
||||||
test. The argument is the time in seconds in floating-point.
|
|
||||||
|
|
||||||
ERROR
|
|
||||||
-----
|
|
||||||
|
|
||||||
The argument is an error message; this will abort the benchmarking run and
|
|
||||||
display the message.
|
|
||||||
|
|
||||||
Any output to stderr which is not a formatted line will be treated as an
|
|
||||||
error message, so use of ERROR is optional.
|
|
||||||
|
|
||||||
|
|
||||||
============================================================================
|
|
||||||
|
|
||||||
Test Examples
|
|
||||||
=============
|
|
||||||
|
|
||||||
Iteration Count
|
|
||||||
---------------
|
|
||||||
|
|
||||||
The simplest thing is to count the number of loops executed in a given time;
|
|
||||||
see eg. arith.c. The utlilty functions in timeit.c can be used to implement
|
|
||||||
the fixed time interval, which is generally passed in on the command line.
|
|
||||||
|
|
||||||
The result is reported simply as the number of iterations completed:
|
|
||||||
|
|
||||||
fprintf(stderr,"COUNT|%lu|1|lps\n", iterations);
|
|
||||||
|
|
||||||
The bnenchmark framework will measure the time taken itself. If the test
|
|
||||||
code has significant overhead (eg. a "pump-priming" pass), then you should
|
|
||||||
explicitly report the time taken for the test by adding a line like this:
|
|
||||||
|
|
||||||
fprintf(stderr, "TIME|%.1f\n", seconds);
|
|
||||||
|
|
||||||
If you want results reported as loops per minute, then set timebase to 60:
|
|
||||||
|
|
||||||
fprintf(stderr,"COUNT|%lu|60|lpm\n", iterations);
|
|
||||||
|
|
||||||
Note that this only affects the final report; all times passed to or
|
|
||||||
from the test are still in seconds.
|
|
||||||
|
|
||||||
Rate
|
|
||||||
----
|
|
||||||
|
|
||||||
The other technique is to calculate the rate (things per second) in the test,
|
|
||||||
and report that directly. To do this, just set timebase to 0:
|
|
||||||
|
|
||||||
fprintf(stderr, "COUNT|%ld|0|KBps\n", kbytes_per_sec);
|
|
||||||
|
|
||||||
Again, you can use TIME to explicitly report the time taken:
|
|
||||||
|
|
||||||
fprintf(stderr, "TIME|%.1f\n", end - start);
|
|
||||||
|
|
||||||
but this isn't so important since you've already calculated the rate.
|
|
||||||
|
|
|
@ -1,6 +0,0 @@
|
||||||
|
|
||||||
SUBDIR=arithoh register short int long float double whetstone-double hanoi \
|
|
||||||
poll select fstime syscall context1 pipe spawn execl dhry2 \
|
|
||||||
dhry2reg looper multi.sh tst.sh unixbench.logo index.base # ubgears poll2BB
|
|
||||||
|
|
||||||
.include <bsd.subdir.mk>
|
|
|
@ -1,5 +0,0 @@
|
||||||
CPPFLAGS+=-DTIME -DMINIX=1 -I../../src/
|
|
||||||
HZ=60
|
|
||||||
BINDIR=/usr/benchmarks/unixbench/pgms
|
|
||||||
|
|
||||||
.PATH: ${.CURDIR}/../../src
|
|
|
@ -1,7 +0,0 @@
|
||||||
|
|
||||||
PROG=arithoh
|
|
||||||
SRCS=arith.c
|
|
||||||
CPPFLAGS+=-Darithoh
|
|
||||||
MAN=
|
|
||||||
|
|
||||||
.include <bsd.prog.mk>
|
|
|
@ -1,5 +0,0 @@
|
||||||
|
|
||||||
PROG=context1
|
|
||||||
MAN=
|
|
||||||
|
|
||||||
.include <bsd.prog.mk>
|
|
|
@ -1,7 +0,0 @@
|
||||||
|
|
||||||
PROG=dhry2
|
|
||||||
SRCS=dhry_1.c dhry_2.c
|
|
||||||
CPPFLAGS+=-DHZ=${HZ}
|
|
||||||
MAN=
|
|
||||||
|
|
||||||
.include <bsd.prog.mk>
|
|
|
@ -1,7 +0,0 @@
|
||||||
|
|
||||||
PROG=dhry2reg
|
|
||||||
SRCS=dhry_1.c dhry_2.c
|
|
||||||
CPPFLAGS+=-DHZ=${HZ} -DREG=register
|
|
||||||
MAN=
|
|
||||||
|
|
||||||
.include <bsd.prog.mk>
|
|
|
@ -1,7 +0,0 @@
|
||||||
|
|
||||||
PROG=double
|
|
||||||
SRCS=arith.c
|
|
||||||
CPPFLAGS=-Ddatum='double'
|
|
||||||
MAN=
|
|
||||||
|
|
||||||
.include <bsd.prog.mk>
|
|
|
@ -1,5 +0,0 @@
|
||||||
|
|
||||||
PROG=execl
|
|
||||||
MAN=
|
|
||||||
|
|
||||||
.include <bsd.prog.mk>
|
|
|
@ -1,7 +0,0 @@
|
||||||
|
|
||||||
PROG=float
|
|
||||||
SRCS=arith.c
|
|
||||||
CPPFLAGS=-Ddatum='float'
|
|
||||||
MAN=
|
|
||||||
|
|
||||||
.include <bsd.prog.mk>
|
|
|
@ -1,5 +0,0 @@
|
||||||
|
|
||||||
PROG=fstime
|
|
||||||
MAN=
|
|
||||||
|
|
||||||
.include <bsd.prog.mk>
|
|
|
@ -1,476 +0,0 @@
|
||||||
#!/usr/bin/perl -w
|
|
||||||
|
|
||||||
use strict;
|
|
||||||
|
|
||||||
|
|
||||||
############################################################################
|
|
||||||
# gfx-x11: a front-end for x11perf. Runs a selected x11perf test, and
|
|
||||||
# produces output in the format needed by UnixBench.
|
|
||||||
############################################################################
|
|
||||||
# Modification Log:
|
|
||||||
# 2007.09.26 Ian Smith Created
|
|
||||||
############################################################################
|
|
||||||
|
|
||||||
# This program runs sets of x11perf tests, indexes the results against
|
|
||||||
# a common base reference system (see $testData below), and reports the
|
|
||||||
# final score.
|
|
||||||
#
|
|
||||||
# Usage:
|
|
||||||
# gfx-x11 <group> <reps> <time>
|
|
||||||
# where:
|
|
||||||
# <group> is one of the test groups defined in $testGroups below
|
|
||||||
# <reps> is the number of repeats to do per test (the -repeat
|
|
||||||
# argument to x11perf)
|
|
||||||
# <time> is the number of seconds to run each repeat for (the
|
|
||||||
# -time argument to x11perf)
|
|
||||||
# Note that x11perf runs a calibration pass before the requested number
|
|
||||||
# of test passes. The score we compute for a test is the average of the
|
|
||||||
# test passes, divided by the base value in $testData, times 1000.0.
|
|
||||||
# The final score we report is the average of the test scores.
|
|
||||||
|
|
||||||
|
|
||||||
############################################################################
|
|
||||||
# TEST DATA
|
|
||||||
############################################################################
|
|
||||||
|
|
||||||
# This array lists all of the x11perf tests, together with their scores
|
|
||||||
# on an HP Compaq nc8430, with an ATI Mobility Radeon X1600 (256MB)
|
|
||||||
# graphics adapter. There isn't anything special about this reference
|
|
||||||
# system, but scaling all the scores back to a single reference system
|
|
||||||
# allows us to average them in a roughly meaningful way, which in turn
|
|
||||||
# allows us to produce sensible scores for the test groups defined below.
|
|
||||||
#
|
|
||||||
# The results we report are indexed to these values, at a base of 1000.0.
|
|
||||||
my $testData = {
|
|
||||||
'dot' => [ 31700000.0, "Dot" ],
|
|
||||||
'rect1' => [ 18400000.0, "1x1 rectangle" ],
|
|
||||||
'rect10' => [ 7180000.0, "10x10 rectangle" ],
|
|
||||||
'rect100' => [ 110000.0, "100x100 rectangle" ],
|
|
||||||
'rect500' => [ 4110.0, "500x500 rectangle" ],
|
|
||||||
'srect1' => [ 15800000.0, "1x1 stippled rectangle (8x8 stipple)" ],
|
|
||||||
'srect10' => [ 7400000.0, "10x10 stippled rectangle (8x8 stipple)" ],
|
|
||||||
'srect100' => [ 110000.0, "100x100 stippled rectangle (8x8 stipple)" ],
|
|
||||||
'srect500' => [ 4110.0, "500x500 stippled rectangle (8x8 stipple)" ],
|
|
||||||
'osrect1' => [ 15900000.0, "1x1 opaque stippled rectangle (8x8 stipple)" ],
|
|
||||||
'osrect10' => [ 7170000.0, "10x10 opaque stippled rectangle (8x8 stipple)" ],
|
|
||||||
'osrect100' => [ 110000.0, "100x100 opaque stippled rectangle (8x8 stipple)" ],
|
|
||||||
'osrect500' => [ 4110.0, "500x500 opaque stippled rectangle (8x8 stipple)" ],
|
|
||||||
'tilerect1' => [ 15800000.0, "1x1 tiled rectangle (4x4 tile)" ],
|
|
||||||
'tilerect10' => [ 7170000.0, "10x10 tiled rectangle (4x4 tile)" ],
|
|
||||||
'tilerect100' => [ 110000.0, "100x100 tiled rectangle (4x4 tile)" ],
|
|
||||||
'tilerect500' => [ 4110.0, "500x500 tiled rectangle (4x4 tile)" ],
|
|
||||||
'oddsrect1' => [ 2990000.0, "1x1 stippled rectangle (17x15 stipple)" ],
|
|
||||||
'oddsrect10' => [ 1490000.0, "10x10 stippled rectangle (17x15 stipple)" ],
|
|
||||||
'oddsrect100' => [ 55600.0, "100x100 stippled rectangle (17x15 stipple)" ],
|
|
||||||
'oddsrect500' => [ 2360.0, "500x500 stippled rectangle (17x15 stipple)" ],
|
|
||||||
'oddosrect1' => [ 2990000.0, "1x1 opaque stippled rectangle (17x15 stipple)" ],
|
|
||||||
'oddosrect10' => [ 1430000.0, "10x10 opaque stippled rectangle (17x15 stipple)" ],
|
|
||||||
'oddosrect100' => [ 54500.0, "100x100 opaque stippled rectangle (17x15 stipple)" ],
|
|
||||||
'oddosrect500' => [ 2320.0, "500x500 opaque stippled rectangle (17x15 stipple)" ],
|
|
||||||
'oddtilerect1' => [ 2990000.0, "1x1 tiled rectangle (17x15 tile)" ],
|
|
||||||
'oddtilerect10' => [ 1430000.0, "10x10 tiled rectangle (17x15 tile)" ],
|
|
||||||
'oddtilerect100' => [ 54500.0, "100x100 tiled rectangle (17x15 tile)" ],
|
|
||||||
'oddtilerect500' => [ 2320.0, "500x500 tiled rectangle (17x15 tile)" ],
|
|
||||||
'bigsrect1' => [ 4300000.0, "1x1 stippled rectangle (161x145 stipple)" ],
|
|
||||||
'bigsrect10' => [ 705000.0, "10x10 stippled rectangle (161x145 stipple)" ],
|
|
||||||
'bigsrect100' => [ 12300.0, "100x100 stippled rectangle (161x145 stipple)" ],
|
|
||||||
'bigsrect500' => [ 524.0, "500x500 stippled rectangle (161x145 stipple)" ],
|
|
||||||
'bigosrect1' => [ 3980000.0, "1x1 opaque stippled rectangle (161x145 stipple)" ],
|
|
||||||
'bigosrect10' => [ 644000.0, "10x10 opaque stippled rectangle (161x145 stipple)" ],
|
|
||||||
'bigosrect100' => [ 12800.0, "100x100 opaque stippled rectangle (161x145 stipple)" ],
|
|
||||||
'bigosrect500' => [ 584.0, "500x500 opaque stippled rectangle (161x145 stipple)" ],
|
|
||||||
'bigtilerect1' => [ 5970000.0, "1x1 tiled rectangle (161x145 tile)" ],
|
|
||||||
'bigtilerect10' => [ 684000.0, "10x10 tiled rectangle (161x145 tile)" ],
|
|
||||||
'bigtilerect100' => [ 16200.0, "100x100 tiled rectangle (161x145 tile)" ],
|
|
||||||
'bigtilerect500' => [ 872.0, "500x500 tiled rectangle (161x145 tile)" ],
|
|
||||||
'eschertilerect1' => [ 5940000.0, "1x1 tiled rectangle (216x208 tile)" ],
|
|
||||||
'eschertilerect10' => [ 639000.0, "10x10 tiled rectangle (216x208 tile)" ],
|
|
||||||
'eschertilerect100' => [ 18000.0, "100x100 tiled rectangle (216x208 tile)" ],
|
|
||||||
'eschertilerect500' => [ 922.0, "500x500 tiled rectangle (216x208 tile)" ],
|
|
||||||
'seg1' => [ 28800000.0, "1-pixel line segment" ],
|
|
||||||
'seg10' => [ 4460000.0, "10-pixel line segment" ],
|
|
||||||
'seg100' => [ 470000.0, "100-pixel line segment" ],
|
|
||||||
'seg500' => [ 94600.0, "500-pixel line segment" ],
|
|
||||||
'seg100c1' => [ 449000.0, "100-pixel line segment (1 kid)" ],
|
|
||||||
'seg100c2' => [ 432000.0, "100-pixel line segment (2 kids)" ],
|
|
||||||
'seg100c3' => [ 421000.0, "100-pixel line segment (3 kids)" ],
|
|
||||||
'dseg10' => [ 3720000.0, "10-pixel dashed segment" ],
|
|
||||||
'dseg100' => [ 687000.0, "100-pixel dashed segment" ],
|
|
||||||
'ddseg100' => [ 454000.0, "100-pixel double-dashed segment" ],
|
|
||||||
'hseg10' => [ 7020000.0, "10-pixel horizontal line segment" ],
|
|
||||||
'hseg100' => [ 2170000.0, "100-pixel horizontal line segment" ],
|
|
||||||
'hseg500' => [ 456000.0, "500-pixel horizontal line segment" ],
|
|
||||||
'vseg10' => [ 3990000.0, "10-pixel vertical line segment" ],
|
|
||||||
'vseg100' => [ 411000.0, "100-pixel vertical line segment" ],
|
|
||||||
'vseg500' => [ 82400.0, "500-pixel vertical line segment" ],
|
|
||||||
'whseg10' => [ 2880000.0, "10x1 wide horizontal line segment" ],
|
|
||||||
'whseg100' => [ 616000.0, "100x10 wide horizontal line segment" ],
|
|
||||||
'whseg500' => [ 33300.0, "500x50 wide horizontal line segment" ],
|
|
||||||
'wvseg10' => [ 2890000.0, "10x1 wide vertical line segment" ],
|
|
||||||
'wvseg100' => [ 584000.0, "100x10 wide vertical line segment" ],
|
|
||||||
'wvseg500' => [ 31700.0, "500x50 wide vertical line segment" ],
|
|
||||||
'line1' => [ 28300000.0, "1-pixel line" ],
|
|
||||||
'line10' => [ 4470000.0, "10-pixel line" ],
|
|
||||||
'line100' => [ 472000.0, "100-pixel line" ],
|
|
||||||
'line500' => [ 94200.0, "500-pixel line" ],
|
|
||||||
'dline10' => [ 3640000.0, "10-pixel dashed line" ],
|
|
||||||
'dline100' => [ 673000.0, "100-pixel dashed line" ],
|
|
||||||
'ddline100' => [ 453000.0, "100-pixel double-dashed line" ],
|
|
||||||
'wline10' => [ 908000.0, "10x1 wide line" ],
|
|
||||||
'wline100' => [ 146000.0, "100x10 wide line" ],
|
|
||||||
'wline500' => [ 30600.0, "500x50 wide line" ],
|
|
||||||
'wdline100' => [ 69900.0, "100x10 wide dashed line" ],
|
|
||||||
'wddline100' => [ 60600.0, "100x10 wide double-dashed line" ],
|
|
||||||
'orect10' => [ 5100000.0, "10x10 rectangle outline" ],
|
|
||||||
'orect100' => [ 709000.0, "100x100 rectangle outline" ],
|
|
||||||
'orect500' => [ 146000.0, "500x500 rectangle outline" ],
|
|
||||||
'worect10' => [ 4530000.0, "10x10 wide rectangle outline" ],
|
|
||||||
'worect100' => [ 204000.0, "100x100 wide rectangle outline" ],
|
|
||||||
'worect500' => [ 9790.0, "500x500 wide rectangle outline" ],
|
|
||||||
'circle1' => [ 5160000.0, "1-pixel circle" ],
|
|
||||||
'circle10' => [ 1160000.0, "10-pixel circle" ],
|
|
||||||
'circle100' => [ 141000.0, "100-pixel circle" ],
|
|
||||||
'circle500' => [ 28900.0, "500-pixel circle" ],
|
|
||||||
'dcircle100' => [ 98400.0, "100-pixel dashed circle" ],
|
|
||||||
'ddcircle100' => [ 75000.0, "100-pixel double-dashed circle" ],
|
|
||||||
'wcircle10' => [ 780000.0, "10-pixel wide circle" ],
|
|
||||||
'wcircle100' => [ 90900.0, "100-pixel wide circle" ],
|
|
||||||
'wcircle500' => [ 11300.0, "500-pixel wide circle" ],
|
|
||||||
'wdcircle100' => [ 8100.0, "100-pixel wide dashed circle" ],
|
|
||||||
'wddcircle100' => [ 8300.0, "100-pixel wide double-dashed circle" ],
|
|
||||||
'pcircle10' => [ 1270000.0, "10-pixel partial circle" ],
|
|
||||||
'pcircle100' => [ 212000.0, "100-pixel partial circle" ],
|
|
||||||
'wpcircle10' => [ 104000.0, "10-pixel wide partial circle" ],
|
|
||||||
'wpcircle100' => [ 39000.0, "100-pixel wide partial circle" ],
|
|
||||||
'fcircle1' => [ 61300000.0, "1-pixel solid circle" ],
|
|
||||||
'fcircle10' => [ 1720000.0, "10-pixel solid circle" ],
|
|
||||||
'fcircle100' => [ 120000.0, "100-pixel solid circle" ],
|
|
||||||
'fcircle500' => [ 5170.0, "500-pixel solid circle" ],
|
|
||||||
'fcpcircle10' => [ 981000.0, "10-pixel fill chord partial circle" ],
|
|
||||||
'fcpcircle100' => [ 205000.0, "100-pixel fill chord partial circle" ],
|
|
||||||
'fspcircle10' => [ 876000.0, "10-pixel fill slice partial circle" ],
|
|
||||||
'fspcircle100' => [ 187000.0, "100-pixel fill slice partial circle" ],
|
|
||||||
'ellipse10' => [ 1410000.0, "10-pixel ellipse" ],
|
|
||||||
'ellipse100' => [ 172000.0, "100-pixel ellipse" ],
|
|
||||||
'ellipse500' => [ 35100.0, "500-pixel ellipse" ],
|
|
||||||
'dellipse100' => [ 114000.0, "100-pixel dashed ellipse" ],
|
|
||||||
'ddellipse100' => [ 88900.0, "100-pixel double-dashed ellipse" ],
|
|
||||||
'wellipse10' => [ 889000.0, "10-pixel wide ellipse" ],
|
|
||||||
'wellipse100' => [ 124000.0, "100-pixel wide ellipse" ],
|
|
||||||
'wellipse500' => [ 15600.0, "500-pixel wide ellipse" ],
|
|
||||||
'wdellipse100' => [ 7730.0, "100-pixel wide dashed ellipse" ],
|
|
||||||
'wddellipse100' => [ 6680.0, "100-pixel wide double-dashed ellipse" ],
|
|
||||||
'pellipse10' => [ 1350000.0, "10-pixel partial ellipse" ],
|
|
||||||
'pellipse100' => [ 260000.0, "100-pixel partial ellipse" ],
|
|
||||||
'wpellipse10' => [ 97900.0, "10-pixel wide partial ellipse" ],
|
|
||||||
'wpellipse100' => [ 16800.0, "100-pixel wide partial ellipse" ],
|
|
||||||
'fellipse10' => [ 2110000.0, "10-pixel filled ellipse" ],
|
|
||||||
'fellipse100' => [ 212000.0, "100-pixel filled ellipse" ],
|
|
||||||
'fellipse500' => [ 11000.0, "500-pixel filled ellipse" ],
|
|
||||||
'fcpellipse10' => [ 1060000.0, "10-pixel fill chord partial ellipse" ],
|
|
||||||
'fcpellipse100' => [ 296000.0, "100-pixel fill chord partial ellipse" ],
|
|
||||||
'fspellipse10' => [ 945000.0, "10-pixel fill slice partial ellipse" ],
|
|
||||||
'fspellipse100' => [ 269000.0, "100-pixel fill slice partial ellipse" ],
|
|
||||||
'triangle1' => [ 2460000.0, "Fill 1x1 equivalent triangle" ],
|
|
||||||
'triangle10' => [ 969000.0, "Fill 10x10 equivalent triangle" ],
|
|
||||||
'triangle100' => [ 97000.0, "Fill 100x100 equivalent triangle" ],
|
|
||||||
'trap1' => [ 2630000.0, "Fill 1x1 trapezoid" ],
|
|
||||||
'trap10' => [ 1260000.0, "Fill 10x10 trapezoid" ],
|
|
||||||
'trap100' => [ 106000.0, "Fill 100x100 trapezoid" ],
|
|
||||||
'trap300' => [ 11600.0, "Fill 300x300 trapezoid" ],
|
|
||||||
'strap1' => [ 2010000.0, "Fill 1x1 stippled trapezoid (8x8 stipple)" ],
|
|
||||||
'strap10' => [ 910000.0, "Fill 10x10 stippled trapezoid (8x8 stipple)" ],
|
|
||||||
'strap100' => [ 104000.0, "Fill 100x100 stippled trapezoid (8x8 stipple)" ],
|
|
||||||
'strap300' => [ 11700.0, "Fill 300x300 stippled trapezoid (8x8 stipple)" ],
|
|
||||||
'ostrap1' => [ 2000000.0, "Fill 1x1 opaque stippled trapezoid (8x8 stipple)" ],
|
|
||||||
'ostrap10' => [ 907000.0, "Fill 10x10 opaque stippled trapezoid (8x8 stipple)" ],
|
|
||||||
'ostrap100' => [ 104000.0, "Fill 100x100 opaque stippled trapezoid (8x8 stipple)" ],
|
|
||||||
'ostrap300' => [ 11600.0, "Fill 300x300 opaque stippled trapezoid (8x8 stipple)" ],
|
|
||||||
'tiletrap1' => [ 1430000.0, "Fill 1x1 tiled trapezoid (4x4 tile)" ],
|
|
||||||
'tiletrap10' => [ 778000.0, "Fill 10x10 tiled trapezoid (4x4 tile)" ],
|
|
||||||
'tiletrap100' => [ 104000.0, "Fill 100x100 tiled trapezoid (4x4 tile)" ],
|
|
||||||
'tiletrap300' => [ 11600.0, "Fill 300x300 tiled trapezoid (4x4 tile)" ],
|
|
||||||
'oddstrap1' => [ 1700000.0, "Fill 1x1 stippled trapezoid (17x15 stipple)" ],
|
|
||||||
'oddstrap10' => [ 296000.0, "Fill 10x10 stippled trapezoid (17x15 stipple)" ],
|
|
||||||
'oddstrap100' => [ 18600.0, "Fill 100x100 stippled trapezoid (17x15 stipple)" ],
|
|
||||||
'oddstrap300' => [ 2090.0, "Fill 300x300 stippled trapezoid (17x15 stipple)" ],
|
|
||||||
'oddostrap1' => [ 1830000.0, "Fill 1x1 opaque stippled trapezoid (17x15 stipple)" ],
|
|
||||||
'oddostrap10' => [ 296000.0, "Fill 10x10 opaque stippled trapezoid (17x15 stipple)" ],
|
|
||||||
'oddostrap100' => [ 18400.0, "Fill 100x100 opaque stippled trapezoid (17x15 stipple)" ],
|
|
||||||
'oddostrap300' => [ 2080.0, "Fill 300x300 opaque stippled trapezoid (17x15 stipple)" ],
|
|
||||||
'oddtiletrap1' => [ 1710000.0, "Fill 1x1 tiled trapezoid (17x15 tile)" ],
|
|
||||||
'oddtiletrap10' => [ 296000.0, "Fill 10x10 tiled trapezoid (17x15 tile)" ],
|
|
||||||
'oddtiletrap100' => [ 18400.0, "Fill 100x100 tiled trapezoid (17x15 tile)" ],
|
|
||||||
'oddtiletrap300' => [ 2080.0, "Fill 300x300 tiled trapezoid (17x15 tile)" ],
|
|
||||||
'bigstrap1' => [ 1510000.0, "Fill 1x1 stippled trapezoid (161x145 stipple)" ],
|
|
||||||
'bigstrap10' => [ 235000.0, "Fill 10x10 stippled trapezoid (161x145 stipple)" ],
|
|
||||||
'bigstrap100' => [ 9110.0, "Fill 100x100 stippled trapezoid (161x145 stipple)" ],
|
|
||||||
'bigstrap300' => [ 1260.0, "Fill 300x300 stippled trapezoid (161x145 stipple)" ],
|
|
||||||
'bigostrap1' => [ 1480000.0, "Fill 1x1 opaque stippled trapezoid (161x145 stipple)" ],
|
|
||||||
'bigostrap10' => [ 213000.0, "Fill 10x10 opaque stippled trapezoid (161x145 stipple)" ],
|
|
||||||
'bigostrap100' => [ 8830.0, "Fill 100x100 opaque stippled trapezoid (161x145 stipple)" ],
|
|
||||||
'bigostrap300' => [ 1420.0, "Fill 300x300 opaque stippled trapezoid (161x145 stipple)" ],
|
|
||||||
'bigtiletrap1' => [ 1630000.0, "Fill 1x1 tiled trapezoid (161x145 tile)" ],
|
|
||||||
'bigtiletrap10' => [ 272000.0, "Fill 10x10 tiled trapezoid (161x145 tile)" ],
|
|
||||||
'bigtiletrap100' => [ 12900.0, "Fill 100x100 tiled trapezoid (161x145 tile)" ],
|
|
||||||
'bigtiletrap300' => [ 2350.0, "Fill 300x300 tiled trapezoid (161x145 tile)" ],
|
|
||||||
'eschertiletrap1' => [ 1650000.0, "Fill 1x1 tiled trapezoid (216x208 tile)" ],
|
|
||||||
'eschertiletrap10' => [ 273000.0, "Fill 10x10 tiled trapezoid (216x208 tile)" ],
|
|
||||||
'eschertiletrap100' => [ 13400.0, "Fill 100x100 tiled trapezoid (216x208 tile)" ],
|
|
||||||
'eschertiletrap300' => [ 2450.0, "Fill 300x300 tiled trapezoid (216x208 tile)" ],
|
|
||||||
'aatrap1' => [ 260000.0, "Fill 1x1 aa trap" ],
|
|
||||||
'aatrap10' => [ 23500.0, "Fill 10x10 aa trap" ],
|
|
||||||
'aatrap100' => [ 13300.0, "Fill 100x100 aa trap" ],
|
|
||||||
'aatrap300' => [ 4450.0, "Fill 300x300 aa trap" ],
|
|
||||||
'aa4trap1' => [ 2150.0, "Fill 1x1 aa trap with 4 bit alpha" ],
|
|
||||||
'aa4trap10' => [ 2130.0, "Fill 10x10 aa trap with 4 bit alpha" ],
|
|
||||||
'aa4trap100' => [ 1890.0, "Fill 100x100 aa trap with 4 bit alpha" ],
|
|
||||||
'aa4trap300' => [ 1460.0, "Fill 300x300 aa trap with 4 bit alpha" ],
|
|
||||||
'aa1trap1' => [ 2200000.0, "Fill 1x1 aa trap with 1 bit alpha" ],
|
|
||||||
'aa1trap10' => [ 357000.0, "Fill 10x10 aa trap with 1 bit alpha" ],
|
|
||||||
'aa1trap100' => [ 167000.0, "Fill 100x100 aa trap with 1 bit alpha" ],
|
|
||||||
'aa1trap300' => [ 67000.0, "Fill 300x300 aa trap with 1 bit alpha" ],
|
|
||||||
'aatrap2x1' => [ 368000.0, "Fill 2x1 aa trap" ],
|
|
||||||
'aatrap2x10' => [ 25700.0, "Fill 2x10 aa trap" ],
|
|
||||||
'aatrap2x100' => [ 12400.0, "Fill 2x100 aa trap" ],
|
|
||||||
'aatrap2x300' => [ 5710.0, "Fill 2x300 aa trap" ],
|
|
||||||
'aatrapezoid1' => [ 372000.0, "Fill 1x1 aa trapezoid" ],
|
|
||||||
'aatrapezoid10' => [ 137000.0, "Fill 10x10 aa trapezoid" ],
|
|
||||||
'aatrapezoid100' => [ 9590.0, "Fill 100x100 aa trapezoid" ],
|
|
||||||
'aatrapezoid300' => [ 1420.0, "Fill 300x300 aa trapezoid" ],
|
|
||||||
'addaatrapezoid1' => [ 433000.0, "Fill 1x1 aa pre-added trapezoid" ],
|
|
||||||
'addaatrapezoid10' => [ 24100.0, "Fill 10x10 aa pre-added trapezoid" ],
|
|
||||||
'addaatrapezoid100' => [ 13300.0, "Fill 100x100 aa pre-added trapezoid" ],
|
|
||||||
'addaatrapezoid300' => [ 4460.0, "Fill 300x300 aa pre-added trapezoid" ],
|
|
||||||
'complex10' => [ 655000.0, "Fill 10x10 equivalent complex polygon" ],
|
|
||||||
'complex100' => [ 87000.0, "Fill 100x100 equivalent complex polygons" ],
|
|
||||||
'64poly10convex' => [ 481000.0, "Fill 10x10 64-gon (Convex)" ],
|
|
||||||
'64poly100convex' => [ 105000.0, "Fill 100x100 64-gon (Convex)" ],
|
|
||||||
'64poly10complex' => [ 353000.0, "Fill 10x10 64-gon (Complex)" ],
|
|
||||||
'64poly100complex' => [ 105000.0, "Fill 100x100 64-gon (Complex)" ],
|
|
||||||
'ftext' => [ 2200000.0, "Char in 80-char line (6x13)" ],
|
|
||||||
'f8text' => [ 1970000.0, "Char in 70-char line (8x13)" ],
|
|
||||||
'f9text' => [ 1690000.0, "Char in 60-char line (9x15)" ],
|
|
||||||
'f14text16' => [ 679000.0, "Char16 in 40-char line (k14)" ],
|
|
||||||
'f24text16' => [ 272000.0, "Char16 in 23-char line (k24)" ],
|
|
||||||
'tr10text' => [ 2520000.0, "Char in 80-char line (TR 10)" ],
|
|
||||||
'tr24text' => [ 940000.0, "Char in 30-char line (TR 24)" ],
|
|
||||||
'polytext' => [ 2230000.0, "Char in 20/40/20 line (6x13, TR 10)" ],
|
|
||||||
'polytext16' => [ 369000.0, "Char16 in 7/14/7 line (k14, k24)" ],
|
|
||||||
'fitext' => [ 1350000.0, "Char in 80-char image line (6x13)" ],
|
|
||||||
'f8itext' => [ 1130000.0, "Char in 70-char image line (8x13)" ],
|
|
||||||
'f9itext' => [ 902000.0, "Char in 60-char image line (9x15)" ],
|
|
||||||
'f14itext16' => [ 449000.0, "Char16 in 40-char image line (k14)" ],
|
|
||||||
'f24itext16' => [ 169000.0, "Char16 in 23-char image line (k24)" ],
|
|
||||||
'tr10itext' => [ 1590000.0, "Char in 80-char image line (TR 10)" ],
|
|
||||||
'tr24itext' => [ 435000.0, "Char in 30-char image line (TR 24)" ],
|
|
||||||
'aa10text' => [ 53200.0, "Char in 80-char aa line (Charter 10)" ],
|
|
||||||
'aa24text' => [ 13300.0, "Char in 30-char aa line (Charter 24)" ],
|
|
||||||
'aaftext' => [ 45200.0, "Char in 80-char aa line (Courier 12)" ],
|
|
||||||
'a10text' => [ 53100.0, "Char in 80-char a line (Charter 10)" ],
|
|
||||||
'a24text' => [ 13300.0, "Char in 30-char a line (Charter 24)" ],
|
|
||||||
'aftext' => [ 45200.0, "Char in 80-char a line (Courier 12)" ],
|
|
||||||
'rgb10text' => [ 49400.0, "Char in 80-char rgb line (Charter 10)" ],
|
|
||||||
'rgb24text' => [ 10200.0, "Char in 30-char rgb line (Charter 24)" ],
|
|
||||||
'rgbftext' => [ 42200.0, "Char in 80-char rgb line (Courier 12)" ],
|
|
||||||
'caa10text' => [ 15300.0, "Char in 80-char aa core line (Charter 10)" ],
|
|
||||||
'caa24text' => [ 2540.0, "Char in 30-char aa core line (Charter 24)" ],
|
|
||||||
'caaftext' => [ 10900.0, "Char in 80-char aa core line (Courier 12)" ],
|
|
||||||
'ca10text' => [ 15300.0, "Char in 80-char a core line (Charter 10)" ],
|
|
||||||
'ca24text' => [ 2540.0, "Char in 30-char a core line (Charter 24)" ],
|
|
||||||
'caftext' => [ 10900.0, "Char in 80-char a core line (Courier 12)" ],
|
|
||||||
'rgb10text' => [ 15000.0, "Char in 80-char rgb core line (Charter 10)" ],
|
|
||||||
'rgb24text' => [ 2510.0, "Char in 30-char rgb core line (Charter 24)" ],
|
|
||||||
'rgbftext' => [ 10700.0, "Char in 80-char rgb core line (Courier 12)" ],
|
|
||||||
'scroll10' => [ 1310000.0, "Scroll 10x10 pixels" ],
|
|
||||||
'scroll100' => [ 52000.0, "Scroll 100x100 pixels" ],
|
|
||||||
'scroll500' => [ 2190.0, "Scroll 500x500 pixels" ],
|
|
||||||
'copywinwin10' => [ 1030000.0, "Copy 10x10 from window to window" ],
|
|
||||||
'copywinwin100' => [ 52200.0, "Copy 100x100 from window to window" ],
|
|
||||||
'copywinwin500' => [ 2080.0, "Copy 500x500 from window to window" ],
|
|
||||||
'copypixwin10' => [ 502000.0, "Copy 10x10 from pixmap to window" ],
|
|
||||||
'copypixwin100' => [ 20300.0, "Copy 100x100 from pixmap to window" ],
|
|
||||||
'copypixwin500' => [ 1020.0, "Copy 500x500 from pixmap to window" ],
|
|
||||||
'copywinpix10' => [ 7730.0, "Copy 10x10 from window to pixmap" ],
|
|
||||||
'copywinpix100' => [ 127.0, "Copy 100x100 from window to pixmap" ],
|
|
||||||
'copywinpix500' => [ 5.0, "Copy 500x500 from window to pixmap" ],
|
|
||||||
'copypixpix10' => [ 1260000.0, "Copy 10x10 from pixmap to pixmap" ],
|
|
||||||
'copypixpix100' => [ 56300.0, "Copy 100x100 from pixmap to pixmap" ],
|
|
||||||
'copypixpix500' => [ 2470.0, "Copy 500x500 from pixmap to pixmap" ],
|
|
||||||
'copyplane10' => [ 466000.0, "Copy 10x10 1-bit deep plane" ],
|
|
||||||
'copyplane100' => [ 13700.0, "Copy 100x100 1-bit deep plane" ],
|
|
||||||
'copyplane500' => [ 671.0, "Copy 500x500 1-bit deep plane" ],
|
|
||||||
'deepcopyplane10' => [ 151000.0, "Copy 10x10 n-bit deep plane" ],
|
|
||||||
'deepcopyplane100' => [ 6090.0, "Copy 100x100 n-bit deep plane" ],
|
|
||||||
'deepcopyplane500' => [ 278.0, "Copy 500x500 n-bit deep plane" ],
|
|
||||||
'putimage10' => [ 434000.0, "PutImage 10x10 square" ],
|
|
||||||
'putimage100' => [ 13600.0, "PutImage 100x100 square" ],
|
|
||||||
'putimage500' => [ 713.0, "PutImage 500x500 square" ],
|
|
||||||
'putimagexy10' => [ 321.0, "PutImage XY 10x10 square" ],
|
|
||||||
'putimagexy100' => [ 3.2, "PutImage XY 100x100 square" ],
|
|
||||||
'putimagexy500' => [ 0.1, "PutImage XY 500x500 square" ],
|
|
||||||
'shmput10' => [ 465000.0, "ShmPutImage 10x10 square" ],
|
|
||||||
'shmput100' => [ 20200.0, "ShmPutImage 100x100 square" ],
|
|
||||||
'shmput500' => [ 1020.0, "ShmPutImage 500x500 square" ],
|
|
||||||
'shmputxy10' => [ 31400.0, "ShmPutImage XY 10x10 square" ],
|
|
||||||
'shmputxy100' => [ 458.0, "ShmPutImage XY 100x100 square" ],
|
|
||||||
'shmputxy500' => [ 19.0, "ShmPutImage XY 500x500 square" ],
|
|
||||||
'getimage10' => [ 6650.0, "GetImage 10x10 square" ],
|
|
||||||
'getimage100' => [ 77.0, "GetImage 100x100 square" ],
|
|
||||||
'getimage500' => [ 3.1, "GetImage 500x500 square" ],
|
|
||||||
'getimagexy10' => [ 320.0, "GetImage XY 10x10 square" ],
|
|
||||||
'getimagexy100' => [ 3.2, "GetImage XY 100x100 square" ],
|
|
||||||
'getimagexy500' => [ 0.1, "GetImage XY 500x500 square" ],
|
|
||||||
'noop' => [ 8760000.0, "X protocol NoOperation" ],
|
|
||||||
'pointer' => [ 54800.0, "QueryPointer" ],
|
|
||||||
'prop' => [ 50900.0, "GetProperty" ],
|
|
||||||
'gc' => [ 1190000.0, "Change graphics context" ],
|
|
||||||
'create' => [ 597000.0, "Create and map subwindows (25 kids)" ],
|
|
||||||
'ucreate' => [ 1100000.0, "Create unmapped window (25 kids)" ],
|
|
||||||
'map' => [ 1350000.0, "Map window via parent (25 kids)" ],
|
|
||||||
'unmap' => [ 3360000.0, "Unmap window via parent (25 kids)" ],
|
|
||||||
'destroy' => [ 1190000.0, "Destroy window via parent (25 kids)" ],
|
|
||||||
'popup' => [ 660000.0, "Hide/expose window via popup (25 kids)" ],
|
|
||||||
'move' => [ 120000.0, "Move window (25 kids)" ],
|
|
||||||
'umove' => [ 1990000.0, "Moved unmapped window (25 kids)" ],
|
|
||||||
'movetree' => [ 877000.0, "Move window via parent (25 kids)" ],
|
|
||||||
'resize' => [ 136000.0, "Resize window (25 kids)" ],
|
|
||||||
'uresize' => [ 1870000.0, "Resize unmapped window (25 kids)" ],
|
|
||||||
'circulate' => [ 56300.0, "Circulate window (25 kids)" ],
|
|
||||||
'ucirculate' => [ 3630000.0, "Circulate Unmapped window (25 kids)" ],
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
# This array defines named groups of tests. This is designed to allow
|
|
||||||
# for simpler runs of related tests.
|
|
||||||
#
|
|
||||||
# Note that this array does *not* include all the x11perf tests. The idea
|
|
||||||
# here is to run a representative sampling of the available tests, to get
|
|
||||||
# a general idea of a system's performance, without taking forever to
|
|
||||||
# do it. If you want to do detailed analysis of an X server or graphics
|
|
||||||
# chip, then use x11perf directly.
|
|
||||||
my $testGroups = {
|
|
||||||
'rects' => [ "rect10", "rect100", "oddtilerect10", "eschertilerect100" ],
|
|
||||||
'lines' => [ "seg100c3", "wvseg100", "ddline100", "worect500" ],
|
|
||||||
'circle' => [ "circle500", "wddcircle100", "wpcircle100", "fspcircle100" ],
|
|
||||||
'ellipse' => [ "ddellipse100", "wddellipse100", "pellipse10", "fspellipse100" ],
|
|
||||||
'shapes' => [ "triangle10", "trap300", "oddostrap300", "eschertiletrap300" ],
|
|
||||||
'aashapes' => [ "aa4trap300", "aa1trap10", "aatrap2x300", "addaatrapezoid300" ],
|
|
||||||
'polys' => [ "complex10", "64poly100convex", "64poly10complex", "64poly100complex" ],
|
|
||||||
'text' => [ "polytext16", "rgb24text", "caa10text", "ca24text" ],
|
|
||||||
'blit' => [ "scroll100", "copypixwin10", "deepcopyplane10", "putimagexy500" ],
|
|
||||||
'window' => [ "popup", "move", "movetree", "resize" ],
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
############################################################################
|
|
||||||
# CODE
|
|
||||||
############################################################################
|
|
||||||
|
|
||||||
# Exec the given command, and catch its standard output.
|
|
||||||
# We return an array containing the PID and the filehandle on the
|
|
||||||
# process' standard output. It's up to the caller to wait for the command
|
|
||||||
# to terminate.
|
|
||||||
sub command {
|
|
||||||
my ( $cmd ) = @_;
|
|
||||||
|
|
||||||
my $pid = open(my $childFd, "-|");
|
|
||||||
if (!defined($pid)) {
|
|
||||||
die("Run: fork() failed (undef)\n");
|
|
||||||
} elsif ($pid == 0) {
|
|
||||||
exec($cmd);
|
|
||||||
die("Run: exec() failed (returned)\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
return ( $pid, $childFd );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
# Get data from running a system command. Used for things like getting
|
|
||||||
# the host OS from `uname -o` etc.
|
|
||||||
#
|
|
||||||
# Ignores initial blank lines from the command and returns the first
|
|
||||||
# non-blank line, with white space trimmed off.
|
|
||||||
sub runTest {
|
|
||||||
my ( $test, $reps, $time ) = @_;
|
|
||||||
|
|
||||||
my $tdata = $testData->{$test};
|
|
||||||
if (!defined($tdata)) {
|
|
||||||
printf STDERR "gfx-x11: No such test: %s\n", $test;
|
|
||||||
exit(9);
|
|
||||||
}
|
|
||||||
|
|
||||||
my $cmd = sprintf "x11perf -repeat %d -subs 25 -time %d -%s",
|
|
||||||
$reps, $time, $test;
|
|
||||||
my ( $pid, $fd ) = command($cmd);
|
|
||||||
my $average = 0;
|
|
||||||
while (<$fd>) {
|
|
||||||
chomp;
|
|
||||||
|
|
||||||
# Display the output for logging.
|
|
||||||
printf "%s\n", $_;
|
|
||||||
|
|
||||||
# Save the score.
|
|
||||||
my ( $reps, $per, $rate ) =
|
|
||||||
( m:([0-9]+)\s+trep\s+@\s+([0-9.]+)\s+msec\s+\(\s*([0-9.]+)/sec\): );
|
|
||||||
$average = $rate if (defined($rate));
|
|
||||||
}
|
|
||||||
|
|
||||||
# Close the command and wait for it to die. Bomb out if it failed.
|
|
||||||
# close($fd);
|
|
||||||
my $p = waitpid($pid, 0);
|
|
||||||
my $status = $?;
|
|
||||||
exit($status) if ($status != 0);
|
|
||||||
|
|
||||||
# Calculate and return the weighted result.
|
|
||||||
my $score = $average / $tdata->[0] * 1000.0;
|
|
||||||
printf "Test %s: %d --> %.1f\n", $test, $average, $score;
|
|
||||||
return $score;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
sub runGroup {
|
|
||||||
my ( $group, $reps, $time ) = @_;
|
|
||||||
|
|
||||||
my $gdata = $testGroups->{$group};
|
|
||||||
if (!defined($gdata)) {
|
|
||||||
printf STDERR "gfx-x11: No such test group: %s\n", $group;
|
|
||||||
exit(9);
|
|
||||||
}
|
|
||||||
|
|
||||||
my $count = 0;
|
|
||||||
my $total = 0;
|
|
||||||
foreach my $test (@$gdata) {
|
|
||||||
$total += runTest($test, $reps, $time);
|
|
||||||
++$count;
|
|
||||||
}
|
|
||||||
$total /= $count;
|
|
||||||
|
|
||||||
$total;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
############################################################################
|
|
||||||
# MAIN
|
|
||||||
############################################################################
|
|
||||||
|
|
||||||
sub main {
|
|
||||||
my @args = @_;
|
|
||||||
|
|
||||||
if (scalar(@args) < 3) {
|
|
||||||
printf STDERR "Usage: gfx-x11 group reps time\n";
|
|
||||||
exit(9);
|
|
||||||
}
|
|
||||||
|
|
||||||
my $reps = $args[1];
|
|
||||||
my $time = $args[2];
|
|
||||||
|
|
||||||
my $score = runGroup($args[0], $reps, $time);
|
|
||||||
printf STDERR "COUNT|%.1f|0|score\n", $score;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
exit(main(@ARGV));
|
|
||||||
|
|
|
@ -1,5 +0,0 @@
|
||||||
|
|
||||||
PROG=hanoi
|
|
||||||
MAN=
|
|
||||||
|
|
||||||
.include <bsd.prog.mk>
|
|
|
@ -1,3 +0,0 @@
|
||||||
SCRIPTS=index.base
|
|
||||||
SCRIPTSNAME=index.base
|
|
||||||
.include <bsd.prog.mk>
|
|
|
@ -1,46 +0,0 @@
|
||||||
# Baseline benchmark scores, used for calculating index results.
|
|
||||||
|
|
||||||
# Scores from "George", a SPARCstation 20-61.
|
|
||||||
dhry2reg|10|lps|116700|116700|2
|
|
||||||
whetstone-double|10|MWIPS|55.0|55.0|2
|
|
||||||
execl|20|lps|43.0|43.0|1
|
|
||||||
fstime|20|KBps|3960|3960|1
|
|
||||||
fsbuffer|20|KBps|1655|1655|1
|
|
||||||
fsdisk|20|KBps|5800|5800|1
|
|
||||||
pipe|10|lps|12440|12440|2
|
|
||||||
context1|10|lps|4000|4000|2
|
|
||||||
spawn|20|lps|126|126|1
|
|
||||||
shell8|60|lpm|6|6|1
|
|
||||||
syscall|10|lps|15000|15000|2
|
|
||||||
|
|
||||||
# The shell1 test was added to the index in 5.0, and this baseline score
|
|
||||||
# was extrapolated to roughly match George's performance.
|
|
||||||
shell1|60|lpm|42.4|42.4|1
|
|
||||||
|
|
||||||
# The 2D baseline scores were derived from a test run on an HP Compaq nc8430
|
|
||||||
# with an ATI Mobility Radeon X1600 Video (256MB) — this is a fairly
|
|
||||||
# common modern adaptor with 3D. The baseline scores here are then
|
|
||||||
# 1/66.6 of the values from that run, to bring them roughly in line with
|
|
||||||
# George. (The HP has an index score of 666.6 single-process.)
|
|
||||||
2d-rects|3|score|15|15|1
|
|
||||||
#2d-lines|3|score|15|15|1
|
|
||||||
#2d-circle|3|score|15|15|1
|
|
||||||
2d-ellipse|3|score|15|15|1
|
|
||||||
#2d-shapes|3|score|15|15|1
|
|
||||||
2d-aashapes|3|score|15|15|1
|
|
||||||
#2d-polys|3|score|15|15|1
|
|
||||||
2d-text|3|score|15|15|1
|
|
||||||
2d-blit|3|score|15|15|1
|
|
||||||
2d-window|3|score|15|15|1
|
|
||||||
|
|
||||||
# The gears test score is derived from a test run on an HP Compaq nc8430
|
|
||||||
# with an ATI Mobility Radeon X1600 Video (256MB) — this is a fairly
|
|
||||||
# common modern adaptor with 3D. The baseline scores here are then
|
|
||||||
# 1/66.6 of the values from that run, to bring them roughly in line with
|
|
||||||
# George.
|
|
||||||
ubgears|20|fps|33.4|33.4|3
|
|
||||||
|
|
||||||
# The grep and sysexec tests were added in 5.1.1; they are not index tests,
|
|
||||||
# but these baseline scores were added for convenience.
|
|
||||||
grep|30|lpm|1|1|3
|
|
||||||
sysexec|10|lps|25|25|10
|
|
|
@ -1,7 +0,0 @@
|
||||||
|
|
||||||
PROG=int
|
|
||||||
SRCS=arith.c
|
|
||||||
CPPFLAGS=-Ddatum='int'
|
|
||||||
MAN=
|
|
||||||
|
|
||||||
.include <bsd.prog.mk>
|
|
|
@ -1,7 +0,0 @@
|
||||||
|
|
||||||
PROG=long
|
|
||||||
SRCS=arith.c
|
|
||||||
CPPFLAGS=-Ddatum='long'
|
|
||||||
MAN=
|
|
||||||
|
|
||||||
.include <bsd.prog.mk>
|
|
|
@ -1,5 +0,0 @@
|
||||||
|
|
||||||
PROG=looper
|
|
||||||
MAN=
|
|
||||||
|
|
||||||
.include <bsd.prog.mk>
|
|
|
@ -1,3 +0,0 @@
|
||||||
SCRIPTS=multi.sh
|
|
||||||
SCRIPTSNAME=multi.sh
|
|
||||||
.include <bsd.prog.mk>
|
|
|
@ -1,23 +0,0 @@
|
||||||
#! /bin/sh
|
|
||||||
###############################################################################
|
|
||||||
# The BYTE UNIX Benchmarks - Release 3
|
|
||||||
# Module: multi.sh SID: 3.4 5/15/91 19:30:24
|
|
||||||
#
|
|
||||||
###############################################################################
|
|
||||||
# Bug reports, patches, comments, suggestions should be sent to:
|
|
||||||
#
|
|
||||||
# Ben Smith or Rick Grehan at BYTE Magazine
|
|
||||||
# ben@bytepb.UUCP rick_g@bytepb.UUCP
|
|
||||||
#
|
|
||||||
###############################################################################
|
|
||||||
# Modification Log:
|
|
||||||
#
|
|
||||||
###############################################################################
|
|
||||||
ID="@(#)multi.sh:3.4 -- 5/15/91 19:30:24";
|
|
||||||
instance=1
|
|
||||||
while [ $instance -le $1 ]; do
|
|
||||||
/bin/sh "$UB_BINDIR/tst.sh" &
|
|
||||||
instance=`expr $instance + 1`
|
|
||||||
done
|
|
||||||
wait
|
|
||||||
|
|
|
@ -1,5 +0,0 @@
|
||||||
|
|
||||||
PROG=pipe
|
|
||||||
MAN=
|
|
||||||
|
|
||||||
.include <bsd.prog.mk>
|
|
|
@ -1,7 +0,0 @@
|
||||||
|
|
||||||
PROG=poll
|
|
||||||
SRCS=time-polling.c
|
|
||||||
CPPFLAGS+=-DHAS_POLL -DUNIXBENCH
|
|
||||||
MAN=
|
|
||||||
|
|
||||||
.include <bsd.prog.mk>
|
|
|
@ -1,7 +0,0 @@
|
||||||
|
|
||||||
PROG=poll2
|
|
||||||
SRCS=time-polling.c
|
|
||||||
CPPFLAGS+=-DHAS_POLL2 -DUNIXBENCH
|
|
||||||
MAN=
|
|
||||||
|
|
||||||
.include <bsd.prog.mk>
|
|
|
@ -1,7 +0,0 @@
|
||||||
|
|
||||||
PROG=register
|
|
||||||
SRCS=arith.c
|
|
||||||
CPPFLAGS=-Ddatum='register int'
|
|
||||||
MAN=
|
|
||||||
|
|
||||||
.include <bsd.prog.mk>
|
|
|
@ -1,7 +0,0 @@
|
||||||
|
|
||||||
PROG=select
|
|
||||||
SRCS=time-polling.c
|
|
||||||
CPPFLAGS+=-DHAS_SELECT -DUNIXBENCH
|
|
||||||
MAN=
|
|
||||||
|
|
||||||
.include <bsd.prog.mk>
|
|
|
@ -1,7 +0,0 @@
|
||||||
|
|
||||||
PROG=short
|
|
||||||
SRCS=arith.c
|
|
||||||
CPPFLAGS=-Ddatum='short'
|
|
||||||
MAN=
|
|
||||||
|
|
||||||
.include <bsd.prog.mk>
|
|
|
@ -1,5 +0,0 @@
|
||||||
|
|
||||||
PROG=spawn
|
|
||||||
MAN=
|
|
||||||
|
|
||||||
.include <bsd.prog.mk>
|
|
|
@ -1,5 +0,0 @@
|
||||||
|
|
||||||
PROG=syscall
|
|
||||||
MAN=
|
|
||||||
|
|
||||||
.include <bsd.prog.mk>
|
|
|
@ -1,3 +0,0 @@
|
||||||
SCRIPTS=tst.sh
|
|
||||||
SCRIPTSNAME=tst.sh
|
|
||||||
.include <bsd.prog.mk>
|
|
|
@ -1,19 +0,0 @@
|
||||||
#! /bin/sh
|
|
||||||
###############################################################################
|
|
||||||
# The BYTE UNIX Benchmarks - Release 3
|
|
||||||
# Module: tst.sh SID: 3.4 5/15/91 19:30:24
|
|
||||||
#
|
|
||||||
###############################################################################
|
|
||||||
# Bug reports, patches, comments, suggestions should be sent to:
|
|
||||||
#
|
|
||||||
# Ben Smith or Rick Grehan at BYTE Magazine
|
|
||||||
# ben@bytepb.UUCP rick_g@bytepb.UUCP
|
|
||||||
#
|
|
||||||
###############################################################################
|
|
||||||
# Modification Log:
|
|
||||||
#
|
|
||||||
###############################################################################
|
|
||||||
ID="@(#)tst.sh:3.4 -- 5/15/91 19:30:24";
|
|
||||||
sort >sort.$$ <sort.src
|
|
||||||
grep the sort.$$ | tee grep.$$ | wc > wc.$$
|
|
||||||
rm sort.$$ grep.$$ wc.$$
|
|
|
@ -1,5 +0,0 @@
|
||||||
|
|
||||||
PROG=ubgears
|
|
||||||
MAN=
|
|
||||||
|
|
||||||
.include <bsd.prog.mk>
|
|
|
@ -1,3 +0,0 @@
|
||||||
SCRIPTS=unixbench.logo
|
|
||||||
SCRIPTSNAME=unixbench.logo
|
|
||||||
.include <bsd.prog.mk>
|
|
|
@ -1,14 +0,0 @@
|
||||||
|
|
||||||
# # # # # # # ##### ###### # # #### # #
|
|
||||||
# # ## # # # # # # # ## # # # # #
|
|
||||||
# # # # # # ## ##### ##### # # # # ######
|
|
||||||
# # # # # # ## # # # # # # # # #
|
|
||||||
# # # ## # # # # # # # ## # # # #
|
|
||||||
#### # # # # # ##### ###### # # #### # #
|
|
||||||
|
|
||||||
Version 5.1.2 Based on the Byte Magazine Unix Benchmark
|
|
||||||
|
|
||||||
Multi-CPU version Version 5 revisions by Ian Smith,
|
|
||||||
Sunnyvale, CA, USA
|
|
||||||
December 22, 2007 johantheghost at yahoo period com
|
|
||||||
|
|
|
@ -1,8 +0,0 @@
|
||||||
|
|
||||||
PROG=whetstone-double
|
|
||||||
SRCS=whets.c
|
|
||||||
CPPFLAGS+= -DDP -DUNIX -DUNIXBENCH
|
|
||||||
LDADD+=-lm
|
|
||||||
MAN=
|
|
||||||
|
|
||||||
.include <bsd.prog.mk>
|
|
|
@ -1,5 +0,0 @@
|
||||||
SCRIPTS=run.sh
|
|
||||||
SCRIPTSNAME=run.sh
|
|
||||||
SCRIPTSDIR=/usr/benchmarks/unixbench
|
|
||||||
|
|
||||||
.include <bsd.prog.mk>
|
|
|
@ -1,4 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
export CC=cc
|
|
||||||
export MINIX=1
|
|
||||||
./Run
|
|
|
@ -1,108 +0,0 @@
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
* The BYTE UNIX Benchmarks - Release 3
|
|
||||||
* Module: arith.c SID: 3.3 5/15/91 19:30:19
|
|
||||||
*
|
|
||||||
*******************************************************************************
|
|
||||||
* Bug reports, patches, comments, suggestions should be sent to:
|
|
||||||
*
|
|
||||||
* Ben Smith, Rick Grehan or Tom Yager
|
|
||||||
* ben@bytepb.byte.com rick_g@bytepb.byte.com tyager@bytepb.byte.com
|
|
||||||
*
|
|
||||||
*******************************************************************************
|
|
||||||
* Modification Log:
|
|
||||||
* May 12, 1989 - modified empty loops to avoid nullifying by optimizing
|
|
||||||
* compilers
|
|
||||||
* August 28, 1990 - changed timing relationship--now returns total number
|
|
||||||
* of iterations (ty)
|
|
||||||
* November 9, 1990 - made changes suggested by Keith Cantrell
|
|
||||||
* (digi!kcantrel) to defeat optimization
|
|
||||||
* to non-existence
|
|
||||||
* October 22, 1997 - code cleanup to remove ANSI C compiler warnings
|
|
||||||
* Andy Kahn <kahn@zk3.dec.com>
|
|
||||||
*
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
char SCCSid[] = "@(#) @(#)arith.c:3.3 -- 5/15/91 19:30:19";
|
|
||||||
/*
|
|
||||||
* arithmetic test
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include "timeit.c"
|
|
||||||
|
|
||||||
int dumb_stuff(int);
|
|
||||||
|
|
||||||
unsigned long iter;
|
|
||||||
|
|
||||||
/* this function is called when the alarm expires */
|
|
||||||
void report(int sig)
|
|
||||||
{
|
|
||||||
fprintf(stderr,"COUNT|%ld|1|lps\n", iter);
|
|
||||||
exit(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
|
||||||
{
|
|
||||||
int duration;
|
|
||||||
int result = 0;
|
|
||||||
|
|
||||||
if (argc != 2) {
|
|
||||||
printf("Usage: %s duration\n", argv[0]);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
duration = atoi(argv[1]);
|
|
||||||
|
|
||||||
/* set up alarm call */
|
|
||||||
iter = 0; /* init iteration count */
|
|
||||||
wake_me(duration, report);
|
|
||||||
|
|
||||||
/* this loop will be interrupted by the alarm call */
|
|
||||||
while (1)
|
|
||||||
{
|
|
||||||
/* in switching to time-based (instead of iteration-based),
|
|
||||||
the following statement was added. It should not skew
|
|
||||||
the timings too much--there was an increment and test
|
|
||||||
in the "while" expression above. The only difference is
|
|
||||||
that now we're incrementing a long instead of an int. (ty) */
|
|
||||||
++iter;
|
|
||||||
/* the loop calls a function to insure that something is done
|
|
||||||
the results of the function are fed back in (just so they
|
|
||||||
they won't be thrown away. A loop with
|
|
||||||
unused assignments may get optimized out of existence */
|
|
||||||
result = dumb_stuff(result);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/************************** dumb_stuff *******************/
|
|
||||||
int dumb_stuff(i)
|
|
||||||
int i;
|
|
||||||
{
|
|
||||||
#ifndef arithoh
|
|
||||||
datum x, y, z;
|
|
||||||
z = 0;
|
|
||||||
#endif
|
|
||||||
/*
|
|
||||||
* 101
|
|
||||||
* sum i*i/(i*i-1)
|
|
||||||
* i=2
|
|
||||||
*/
|
|
||||||
/* notice that the i value is always reset by the loop */
|
|
||||||
for (i=2; i<=101; i++)
|
|
||||||
{
|
|
||||||
#ifndef arithoh
|
|
||||||
x = i;
|
|
||||||
y = x*x;
|
|
||||||
z += y/(y-1);
|
|
||||||
}
|
|
||||||
return(x+y+z);
|
|
||||||
#else
|
|
||||||
}
|
|
||||||
return(0);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,595 +0,0 @@
|
||||||
/*******************************************************************************
|
|
||||||
* The BYTE UNIX Benchmarks - Release 3
|
|
||||||
* Module: big.c SID: 3.3 5/15/91 19:30:18
|
|
||||||
*
|
|
||||||
*******************************************************************************
|
|
||||||
* Bug reports, patches, comments, suggestions should be sent to:
|
|
||||||
*
|
|
||||||
* Ben Smith, Rick Grehan or Tom Yager
|
|
||||||
* ben@bytepb.byte.com rick_g@bytepb.byte.com tyager@bytepb.byte.com
|
|
||||||
*
|
|
||||||
*******************************************************************************
|
|
||||||
* Modification Log:
|
|
||||||
* 10/22/97 - code cleanup to remove ANSI C compiler warnings
|
|
||||||
* Andy Kahn <kahn@zk3.dec.com>
|
|
||||||
*
|
|
||||||
******************************************************************************/
|
|
||||||
/*
|
|
||||||
* dummy code for execl test [ old version of makework.c ]
|
|
||||||
*
|
|
||||||
* makework [ -r rate ] [ -c copyfile ] nusers
|
|
||||||
*
|
|
||||||
* job streams are specified on standard input with lines of the form
|
|
||||||
* full_path_name_for_command [ options ] [ <standard_input_file ]
|
|
||||||
*
|
|
||||||
* "standard input" is send to all nuser instances of the commands in the
|
|
||||||
* job streams at a rate not in excess of "rate" characters per second
|
|
||||||
* per command
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
/* this code is included in other files and therefore has no SCCSid */
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <signal.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <time.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <sys/wait.h>
|
|
||||||
|
|
||||||
|
|
||||||
#define DEF_RATE 5.0
|
|
||||||
#define GRANULE 5
|
|
||||||
#define CHUNK 60
|
|
||||||
#define MAXCHILD 12
|
|
||||||
#define MAXWORK 10
|
|
||||||
|
|
||||||
/* Can't seem to get this declared in the headers... */
|
|
||||||
extern int kill(pid_t pid, int sig);
|
|
||||||
|
|
||||||
void wrapup(char *);
|
|
||||||
void onalarm(int);
|
|
||||||
void pipeerr(int sig);
|
|
||||||
void grunt(int sig);
|
|
||||||
void getwork(void);
|
|
||||||
#if debug
|
|
||||||
void dumpwork(void);
|
|
||||||
#endif
|
|
||||||
void fatal(char *s);
|
|
||||||
|
|
||||||
float thres;
|
|
||||||
float est_rate = DEF_RATE;
|
|
||||||
int nusers; /* number of concurrent users to be simulated by
|
|
||||||
* this process */
|
|
||||||
int firstuser; /* ordinal identification of first user for this
|
|
||||||
* process */
|
|
||||||
int nwork = 0; /* number of job streams */
|
|
||||||
int exit_status = 0; /* returned to parent */
|
|
||||||
int sigpipe; /* pipe write error flag */
|
|
||||||
|
|
||||||
struct st_work {
|
|
||||||
char *cmd; /* name of command to run */
|
|
||||||
char **av; /* arguments to command */
|
|
||||||
char *input; /* standard input buffer */
|
|
||||||
int inpsize; /* size of standard input buffer */
|
|
||||||
char *outf; /* standard output (filename) */
|
|
||||||
} work[MAXWORK];
|
|
||||||
|
|
||||||
struct {
|
|
||||||
int xmit; /* # characters sent */
|
|
||||||
char *bp; /* std input buffer pointer */
|
|
||||||
int blen; /* std input buffer length */
|
|
||||||
int fd; /* stdin to command */
|
|
||||||
int pid; /* child PID */
|
|
||||||
char *line; /* start of input line */
|
|
||||||
int firstjob; /* inital piece of work */
|
|
||||||
int thisjob; /* current piece of work */
|
|
||||||
} child[MAXCHILD], *cp;
|
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
int l;
|
|
||||||
int fcopy = 0; /* fd for copy output */
|
|
||||||
int master = 1; /* the REAL master, == 0 for clones */
|
|
||||||
int nchild; /* no. of children for a clone to run */
|
|
||||||
int done; /* count of children finished */
|
|
||||||
int output; /* aggregate output char count for all
|
|
||||||
children */
|
|
||||||
int c;
|
|
||||||
int thiswork = 0; /* next job stream to allocate */
|
|
||||||
int nch; /* # characters to write */
|
|
||||||
int written; /* # characters actully written */
|
|
||||||
char logname[15]; /* name of the log file(s) */
|
|
||||||
int pvec[2]; /* for pipes */
|
|
||||||
char *p;
|
|
||||||
char *prog; /* my name */
|
|
||||||
|
|
||||||
#if ! debug
|
|
||||||
freopen("masterlog.00", "a", stderr);
|
|
||||||
#endif
|
|
||||||
prog = argv[0];
|
|
||||||
while (argc > 1 && argv[1][0] == '-') {
|
|
||||||
p = &argv[1][1];
|
|
||||||
argc--;
|
|
||||||
argv++;
|
|
||||||
while (*p) {
|
|
||||||
switch (*p) {
|
|
||||||
case 'r':
|
|
||||||
est_rate = atoi(argv[1]);
|
|
||||||
sscanf(argv[1], "%f", &est_rate);
|
|
||||||
if (est_rate <= 0) {
|
|
||||||
fprintf(stderr, "%s: bad rate, reset to %.2f chars/sec\n", prog, DEF_RATE);
|
|
||||||
est_rate = DEF_RATE;
|
|
||||||
}
|
|
||||||
argc--;
|
|
||||||
argv++;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'c':
|
|
||||||
fcopy = open(argv[1], 1);
|
|
||||||
if (fcopy < 0)
|
|
||||||
fcopy = creat(argv[1], 0600);
|
|
||||||
if (fcopy < 0) {
|
|
||||||
fprintf(stderr, "%s: cannot open copy file '%s'\n",
|
|
||||||
prog, argv[1]);
|
|
||||||
exit(2);
|
|
||||||
}
|
|
||||||
lseek(fcopy, 0L, 2); /* append at end of file */
|
|
||||||
argc--;
|
|
||||||
argv++;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
fprintf(stderr, "%s: bad flag '%c'\n", prog, *p);
|
|
||||||
exit(4);
|
|
||||||
}
|
|
||||||
p++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (argc < 2) {
|
|
||||||
fprintf(stderr, "%s: missing nusers\n", prog);
|
|
||||||
exit(4);
|
|
||||||
}
|
|
||||||
|
|
||||||
nusers = atoi(argv[1]);
|
|
||||||
if (nusers < 1) {
|
|
||||||
fprintf(stderr, "%s: impossible nusers (%d<-%s)\n", prog, nusers, argv[1]);
|
|
||||||
exit(4);
|
|
||||||
}
|
|
||||||
fprintf(stderr, "%d Users\n", nusers);
|
|
||||||
argc--;
|
|
||||||
argv++;
|
|
||||||
|
|
||||||
/* build job streams */
|
|
||||||
getwork();
|
|
||||||
#if debug
|
|
||||||
dumpwork();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* clone copies of myself to run up to MAXCHILD jobs each */
|
|
||||||
firstuser = MAXCHILD;
|
|
||||||
fprintf(stderr, "master pid %d\n", getpid());
|
|
||||||
fflush(stderr);
|
|
||||||
while (nusers > MAXCHILD) {
|
|
||||||
fflush(stderr);
|
|
||||||
if (nusers >= 2*MAXCHILD)
|
|
||||||
/* the next clone must run MAXCHILD jobs */
|
|
||||||
nchild = MAXCHILD;
|
|
||||||
else
|
|
||||||
/* the next clone must run the leftover jobs */
|
|
||||||
nchild = nusers - MAXCHILD;
|
|
||||||
if ((l = fork()) == -1) {
|
|
||||||
/* fork failed */
|
|
||||||
fatal("** clone fork failed **\n");
|
|
||||||
goto bepatient;
|
|
||||||
} else if (l > 0) {
|
|
||||||
fprintf(stderr, "master clone pid %d\n", l);
|
|
||||||
/* I am the master with nchild fewer jobs to run */
|
|
||||||
nusers -= nchild;
|
|
||||||
firstuser += MAXCHILD;
|
|
||||||
continue;
|
|
||||||
} else {
|
|
||||||
/* I am a clone, run MAXCHILD jobs */
|
|
||||||
#if ! debug
|
|
||||||
sprintf(logname, "masterlog.%02d", firstuser/MAXCHILD);
|
|
||||||
freopen(logname, "w", stderr);
|
|
||||||
#endif
|
|
||||||
master = 0;
|
|
||||||
nusers = nchild;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (master)
|
|
||||||
firstuser = 0;
|
|
||||||
|
|
||||||
close(0);
|
|
||||||
for (i = 0; i < nusers; i++ ) {
|
|
||||||
fprintf(stderr, "user %d job %d ", firstuser+i, thiswork);
|
|
||||||
if (pipe(pvec) == -1) {
|
|
||||||
/* this is fatal */
|
|
||||||
fatal("** pipe failed **\n");
|
|
||||||
goto bepatient;
|
|
||||||
}
|
|
||||||
fflush(stderr);
|
|
||||||
if ((child[i].pid = fork()) == 0) {
|
|
||||||
int fd;
|
|
||||||
/* the command */
|
|
||||||
if (pvec[0] != 0) {
|
|
||||||
close(0);
|
|
||||||
dup(pvec[0]);
|
|
||||||
}
|
|
||||||
#if ! debug
|
|
||||||
sprintf(logname, "userlog.%02d", firstuser+i);
|
|
||||||
freopen(logname, "w", stderr);
|
|
||||||
#endif
|
|
||||||
for (fd = 3; fd < 24; fd++)
|
|
||||||
close(fd);
|
|
||||||
if (work[thiswork].outf[0] != '\0') {
|
|
||||||
/* redirect std output */
|
|
||||||
char *q;
|
|
||||||
for (q = work[thiswork].outf; *q != '\n'; q++) ;
|
|
||||||
*q = '\0';
|
|
||||||
if (freopen(work[thiswork].outf, "w", stdout) == NULL) {
|
|
||||||
fprintf(stderr, "makework: cannot open %s for std output\n",
|
|
||||||
work[thiswork].outf);
|
|
||||||
fflush(stderr);
|
|
||||||
}
|
|
||||||
*q = '\n';
|
|
||||||
}
|
|
||||||
execv(work[thiswork].cmd, work[thiswork].av);
|
|
||||||
/* don't expect to get here! */
|
|
||||||
fatal("** exec failed **\n");
|
|
||||||
goto bepatient;
|
|
||||||
}
|
|
||||||
else if (child[i].pid == -1) {
|
|
||||||
fatal("** fork failed **\n");
|
|
||||||
goto bepatient;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
close(pvec[0]);
|
|
||||||
child[i].fd = pvec[1];
|
|
||||||
child[i].line = child[i].bp = work[thiswork].input;
|
|
||||||
child[i].blen = work[thiswork].inpsize;
|
|
||||||
child[i].thisjob = thiswork;
|
|
||||||
child[i].firstjob = thiswork;
|
|
||||||
fprintf(stderr, "pid %d pipe fd %d", child[i].pid, child[i].fd);
|
|
||||||
if (work[thiswork].outf[0] != '\0') {
|
|
||||||
char *q;
|
|
||||||
fprintf(stderr, " > ");
|
|
||||||
for (q=work[thiswork].outf; *q != '\n'; q++)
|
|
||||||
fputc(*q, stderr);
|
|
||||||
}
|
|
||||||
fputc('\n', stderr);
|
|
||||||
thiswork++;
|
|
||||||
if (thiswork >= nwork)
|
|
||||||
thiswork = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fflush(stderr);
|
|
||||||
|
|
||||||
srand(time(0));
|
|
||||||
thres = 0;
|
|
||||||
done = output = 0;
|
|
||||||
for (i = 0; i < nusers; i++) {
|
|
||||||
if (child[i].blen == 0)
|
|
||||||
done++;
|
|
||||||
else
|
|
||||||
thres += est_rate * GRANULE;
|
|
||||||
}
|
|
||||||
est_rate = thres;
|
|
||||||
|
|
||||||
signal(SIGALRM, onalarm);
|
|
||||||
signal(SIGPIPE, pipeerr);
|
|
||||||
alarm(GRANULE);
|
|
||||||
while (done < nusers) {
|
|
||||||
for (i = 0; i < nusers; i++) {
|
|
||||||
cp = &child[i];
|
|
||||||
if (cp->xmit >= cp->blen) continue;
|
|
||||||
l = rand() % CHUNK + 1; /* 1-CHUNK chars */
|
|
||||||
if (l == 0) continue;
|
|
||||||
if (cp->xmit + l > cp->blen)
|
|
||||||
l = cp->blen - cp->xmit;
|
|
||||||
p = cp->bp;
|
|
||||||
cp->bp += l;
|
|
||||||
cp->xmit += l;
|
|
||||||
#if debug
|
|
||||||
fprintf(stderr, "child %d, %d processed, %d to go\n", i, cp->xmit, cp->blen - cp->xmit);
|
|
||||||
#endif
|
|
||||||
while (p < cp->bp) {
|
|
||||||
if (*p == '\n' || (p == &cp->bp[-1] && cp->xmit >= cp->blen)) {
|
|
||||||
/* write it out */
|
|
||||||
nch = p - cp->line + 1;
|
|
||||||
if ((written = write(cp->fd, cp->line, nch)) != nch) {
|
|
||||||
/* argh! */
|
|
||||||
cp->line[nch] = '\0';
|
|
||||||
fprintf(stderr, "user %d job %d cmd %s ",
|
|
||||||
firstuser+i, cp->thisjob, cp->line);
|
|
||||||
fprintf(stderr, "write(,,%d) returns %d\n", nch, written);
|
|
||||||
if (sigpipe)
|
|
||||||
fatal("** SIGPIPE error **\n");
|
|
||||||
else
|
|
||||||
fatal("** write error **\n");
|
|
||||||
goto bepatient;
|
|
||||||
|
|
||||||
}
|
|
||||||
if (fcopy)
|
|
||||||
write(fcopy, cp->line, p - cp->line + 1);
|
|
||||||
#if debug
|
|
||||||
fprintf(stderr, "child %d gets \"", i);
|
|
||||||
{
|
|
||||||
char *q = cp->line;
|
|
||||||
while (q <= p) {
|
|
||||||
if (*q >= ' ' && *q <= '~')
|
|
||||||
fputc(*q, stderr);
|
|
||||||
else
|
|
||||||
fprintf(stderr, "\\%03o", *q);
|
|
||||||
q++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fputc('"', stderr);
|
|
||||||
#endif
|
|
||||||
cp->line = &p[1];
|
|
||||||
}
|
|
||||||
p++;
|
|
||||||
}
|
|
||||||
if (cp->xmit >= cp->blen) {
|
|
||||||
done++;
|
|
||||||
close(cp->fd);
|
|
||||||
#if debug
|
|
||||||
fprintf(stderr, "child %d, close std input\n", i);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
output += l;
|
|
||||||
}
|
|
||||||
while (output > thres) {
|
|
||||||
pause();
|
|
||||||
#if debug
|
|
||||||
fprintf(stderr, "after pause: output, thres, done %d %.2f %d\n", output, thres, done);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bepatient:
|
|
||||||
alarm(0);
|
|
||||||
/****
|
|
||||||
* If everything is going OK, we should simply be able to keep
|
|
||||||
* looping unitil 'wait' fails, however some descendent process may
|
|
||||||
* be in a state from which it can never exit, and so a timeout
|
|
||||||
* is used.
|
|
||||||
* 5 minutes should be ample, since the time to run all jobs is of
|
|
||||||
* the order of 5-10 minutes, however some machines are painfully slow,
|
|
||||||
* so the timeout has been set at 20 minutes (1200 seconds).
|
|
||||||
****/
|
|
||||||
signal(SIGALRM, grunt);
|
|
||||||
alarm(1200);
|
|
||||||
while ((c = wait(&l)) != -1) {
|
|
||||||
for (i = 0; i < nusers; i++) {
|
|
||||||
if (c == child[i].pid) {
|
|
||||||
fprintf(stderr, "user %d job %d pid %d done", firstuser+i, child[i].thisjob, c);
|
|
||||||
if (l != 0) {
|
|
||||||
if (l & 0x7f)
|
|
||||||
fprintf(stderr, " status %d", l & 0x7f);
|
|
||||||
if (l & 0xff00)
|
|
||||||
fprintf(stderr, " exit code %d", (l>>8) & 0xff);
|
|
||||||
exit_status = 4;
|
|
||||||
}
|
|
||||||
fputc('\n', stderr);
|
|
||||||
c = child[i].pid = -1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (c != -1) {
|
|
||||||
fprintf(stderr, "master clone done, pid %d ", c);
|
|
||||||
if (l != 0) {
|
|
||||||
if (l & 0x7f)
|
|
||||||
fprintf(stderr, " status %d", l & 0x7f);
|
|
||||||
if (l & 0xff00)
|
|
||||||
fprintf(stderr, " exit code %d", (l>>8) & 0xff);
|
|
||||||
exit_status = 4;
|
|
||||||
}
|
|
||||||
fputc('\n', stderr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
alarm(0);
|
|
||||||
wrapup("Finished waiting ...");
|
|
||||||
|
|
||||||
exit(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void onalarm(int foo)
|
|
||||||
{
|
|
||||||
thres += est_rate;
|
|
||||||
signal(SIGALRM, onalarm);
|
|
||||||
alarm(GRANULE);
|
|
||||||
}
|
|
||||||
|
|
||||||
void grunt(int sig)
|
|
||||||
{
|
|
||||||
/* timeout after label "bepatient" in main */
|
|
||||||
exit_status = 4;
|
|
||||||
wrapup("Timed out waiting for jobs to finish ...");
|
|
||||||
}
|
|
||||||
|
|
||||||
void pipeerr(int sig)
|
|
||||||
{
|
|
||||||
sigpipe++;
|
|
||||||
}
|
|
||||||
|
|
||||||
void wrapup(char *reason)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
int killed = 0;
|
|
||||||
fflush(stderr);
|
|
||||||
for (i = 0; i < nusers; i++) {
|
|
||||||
if (child[i].pid > 0 && kill(child[i].pid, SIGKILL) != -1) {
|
|
||||||
if (!killed) {
|
|
||||||
killed++;
|
|
||||||
fprintf(stderr, "%s\n", reason);
|
|
||||||
fflush(stderr);
|
|
||||||
}
|
|
||||||
fprintf(stderr, "user %d job %d pid %d killed off\n", firstuser+i, child[i].thisjob, child[i].pid);
|
|
||||||
fflush(stderr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
exit(exit_status);
|
|
||||||
}
|
|
||||||
|
|
||||||
#define MAXLINE 512
|
|
||||||
void getwork(void)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
int f;
|
|
||||||
int ac=0;
|
|
||||||
char *lp = (void *)0;
|
|
||||||
char *q = (void *)0;
|
|
||||||
struct st_work *w = (void *)0;
|
|
||||||
char line[MAXLINE];
|
|
||||||
char c;
|
|
||||||
|
|
||||||
while (fgets(line, MAXLINE, stdin) != NULL) {
|
|
||||||
if (nwork >= MAXWORK) {
|
|
||||||
fprintf(stderr, "Too many jobs specified, .. increase MAXWORK\n");
|
|
||||||
exit(4);
|
|
||||||
}
|
|
||||||
w = &work[nwork];
|
|
||||||
lp = line;
|
|
||||||
i = 1;
|
|
||||||
while (*lp && *lp != ' ') {
|
|
||||||
i++;
|
|
||||||
lp++;
|
|
||||||
}
|
|
||||||
w->cmd = (char *)malloc(i);
|
|
||||||
strncpy(w->cmd, line, i-1);
|
|
||||||
w->cmd[i-1] = '\0';
|
|
||||||
w->inpsize = 0;
|
|
||||||
w->input = "";
|
|
||||||
/* start to build arg list */
|
|
||||||
ac = 2;
|
|
||||||
w->av = (char **)malloc(2*sizeof(char *));
|
|
||||||
q = w->cmd;
|
|
||||||
while (*q) q++;
|
|
||||||
q--;
|
|
||||||
while (q >= w->cmd) {
|
|
||||||
if (*q == '/') {
|
|
||||||
q++;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
q--;
|
|
||||||
}
|
|
||||||
w->av[0] = q;
|
|
||||||
while (*lp) {
|
|
||||||
if (*lp == ' ') {
|
|
||||||
/* space */
|
|
||||||
lp++;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
else if (*lp == '<') {
|
|
||||||
/* standard input for this job */
|
|
||||||
q = ++lp;
|
|
||||||
while (*lp && *lp != ' ') lp++;
|
|
||||||
c = *lp;
|
|
||||||
*lp = '\0';
|
|
||||||
if ((f = open(q, 0)) == -1) {
|
|
||||||
fprintf(stderr, "cannot open input file (%s) for job %d\n",
|
|
||||||
q, nwork);
|
|
||||||
exit(4);
|
|
||||||
}
|
|
||||||
/* gobble input */
|
|
||||||
w->input = (char *)malloc(512);
|
|
||||||
while ((i = read(f, &w->input[w->inpsize], 512)) > 0) {
|
|
||||||
w->inpsize += i;
|
|
||||||
w->input = (char *)realloc(w->input, w->inpsize+512);
|
|
||||||
}
|
|
||||||
w->input = (char *)realloc(w->input, w->inpsize);
|
|
||||||
close(f);
|
|
||||||
/* extract stdout file name from line beginning "C=" */
|
|
||||||
w->outf = "";
|
|
||||||
for (q = w->input; q < &w->input[w->inpsize-10]; q++) {
|
|
||||||
if (*q == '\n' && strncmp(&q[1], "C=", 2) == 0) {
|
|
||||||
w->outf = &q[3];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#if debug
|
|
||||||
if (*w->outf) {
|
|
||||||
fprintf(stderr, "stdout->");
|
|
||||||
for (q=w->outf; *q != '\n'; q++)
|
|
||||||
fputc(*q, stderr);
|
|
||||||
fputc('\n', stderr);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
/* a command option */
|
|
||||||
ac++;
|
|
||||||
w->av = (char **)realloc(w->av, ac*sizeof(char *));
|
|
||||||
q = lp;
|
|
||||||
i = 1;
|
|
||||||
while (*lp && *lp != ' ') {
|
|
||||||
lp++;
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
w->av[ac-2] = (char *)malloc(i);
|
|
||||||
strncpy(w->av[ac-2], q, i-1);
|
|
||||||
w->av[ac-2][i-1] = '\0';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
w->av[ac-1] = (char *)0;
|
|
||||||
nwork++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#if debug
|
|
||||||
void dumpwork(void)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
int j;
|
|
||||||
|
|
||||||
for (i = 0; i < nwork; i++) {
|
|
||||||
fprintf(stderr, "job %d: cmd: %s\n", i, work[i].cmd);
|
|
||||||
j = 0;
|
|
||||||
while (work[i].av[j]) {
|
|
||||||
fprintf(stderr, "argv[%d]: %s\n", j, work[i].av[j]);
|
|
||||||
j++;
|
|
||||||
}
|
|
||||||
fprintf(stderr, "input: %d chars text: ", work[i].inpsize);
|
|
||||||
if (work[i].input == (char *)0)
|
|
||||||
fprintf(stderr, "<NULL>\n");
|
|
||||||
else {
|
|
||||||
register char *pend;
|
|
||||||
char *p;
|
|
||||||
char c;
|
|
||||||
p = work[i].input;
|
|
||||||
while (*p) {
|
|
||||||
pend = p;
|
|
||||||
while (*pend && *pend != '\n')
|
|
||||||
pend++;
|
|
||||||
c = *pend;
|
|
||||||
*pend = '\0';
|
|
||||||
fprintf(stderr, "%s\n", p);
|
|
||||||
*pend = c;
|
|
||||||
p = &pend[1];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void fatal(char *s)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
fprintf(stderr, "%s", s);
|
|
||||||
fflush(stderr);
|
|
||||||
perror("Reason?");
|
|
||||||
fflush(stderr);
|
|
||||||
for (i = 0; i < nusers; i++) {
|
|
||||||
if (child[i].pid > 0 && kill(child[i].pid, SIGKILL) != -1) {
|
|
||||||
fprintf(stderr, "pid %d killed off\n", child[i].pid);
|
|
||||||
fflush(stderr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
exit_status = 4;
|
|
||||||
}
|
|
|
@ -1,125 +0,0 @@
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
* The BYTE UNIX Benchmarks - Release 3
|
|
||||||
* Module: context1.c SID: 3.3 5/15/91 19:30:18
|
|
||||||
*
|
|
||||||
*******************************************************************************
|
|
||||||
* Bug reports, patches, comments, suggestions should be sent to:
|
|
||||||
*
|
|
||||||
* Ben Smith, Rick Grehan or Tom Yager
|
|
||||||
* ben@bytepb.byte.com rick_g@bytepb.byte.com tyager@bytepb.byte.com
|
|
||||||
*
|
|
||||||
*******************************************************************************
|
|
||||||
* Modification Log:
|
|
||||||
* $Header: context1.c,v 3.4 87/06/22 14:22:59 kjmcdonell Beta $
|
|
||||||
* August 28, 1990 - changed timing routines--now returns total number of
|
|
||||||
* iterations in specified time period
|
|
||||||
* October 22, 1997 - code cleanup to remove ANSI C compiler warnings
|
|
||||||
* Andy Kahn <kahn@zk3.dec.com>
|
|
||||||
*
|
|
||||||
******************************************************************************/
|
|
||||||
char SCCSid[] = "@(#) @(#)context1.c:3.3 -- 5/15/91 19:30:18";
|
|
||||||
/*
|
|
||||||
* Context switching via synchronized unbuffered pipe i/o
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef MINIX
|
|
||||||
#include <signal.h>
|
|
||||||
#endif
|
|
||||||
#ifdef LINUX
|
|
||||||
#include <sys/types.h>
|
|
||||||
#endif
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include "timeit.c"
|
|
||||||
|
|
||||||
unsigned long iter;
|
|
||||||
#ifdef MINIX
|
|
||||||
pid_t child;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void report(int sig)
|
|
||||||
{
|
|
||||||
fprintf(stderr, "COUNT|%lu|1|lps\n", iter);
|
|
||||||
#ifdef MINIX
|
|
||||||
kill(child, SIGKILL);
|
|
||||||
#endif
|
|
||||||
exit(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
|
||||||
{
|
|
||||||
int duration;
|
|
||||||
unsigned long check;
|
|
||||||
int p1[2], p2[2];
|
|
||||||
|
|
||||||
if (argc != 2) {
|
|
||||||
fprintf(stderr, "Usage: context duration\n");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
duration = atoi(argv[1]);
|
|
||||||
|
|
||||||
/* set up alarm call */
|
|
||||||
iter = 0;
|
|
||||||
wake_me(duration, report);
|
|
||||||
|
|
||||||
if (pipe(p1) || pipe(p2)) {
|
|
||||||
perror("pipe create failed");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifndef MINIX
|
|
||||||
if (fork()) { /* parent process */
|
|
||||||
#else
|
|
||||||
if ((child = fork())) {
|
|
||||||
#endif
|
|
||||||
/* master, write p1 & read p2 */
|
|
||||||
close(p1[0]); close(p2[1]);
|
|
||||||
while (1) {
|
|
||||||
if (write(p1[1], (char *)&iter, sizeof(iter)) != sizeof(iter)) {
|
|
||||||
if ((errno != 0) && (errno != EINTR))
|
|
||||||
perror("master write failed");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
if (read(p2[0], (char *)&check, sizeof(check)) != sizeof(check)) {
|
|
||||||
if ((errno != 0) && (errno != EINTR))
|
|
||||||
perror("master read failed");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
if (check != iter) {
|
|
||||||
fprintf(stderr, "Master sync error: expect %lu, got %lu\n",
|
|
||||||
iter, check);
|
|
||||||
exit(2);
|
|
||||||
}
|
|
||||||
iter++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else { /* child process */
|
|
||||||
unsigned long iter1;
|
|
||||||
|
|
||||||
iter1 = 0;
|
|
||||||
/* slave, read p1 & write p2 */
|
|
||||||
close(p1[1]); close(p2[0]);
|
|
||||||
while (1) {
|
|
||||||
if (read(p1[0], (char *)&check, sizeof(check)) != sizeof(check)) {
|
|
||||||
if ((errno != 0) && (errno != EINTR))
|
|
||||||
perror("slave read failed");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
if (check != iter1) {
|
|
||||||
fprintf(stderr, "Slave sync error: expect %lu, got %lu\n",
|
|
||||||
iter, check);
|
|
||||||
exit(2);
|
|
||||||
}
|
|
||||||
if (write(p2[1], (char *)&iter1, sizeof(iter1)) != sizeof(check)) {
|
|
||||||
if ((errno != 0) && (errno != EINTR))
|
|
||||||
perror("slave write failed");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
iter1++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,435 +0,0 @@
|
||||||
/*****************************************************************************
|
|
||||||
* The BYTE UNIX Benchmarks - Release 3
|
|
||||||
* Module: dhry.h SID: 3.4 5/15/91 19:30:21
|
|
||||||
*
|
|
||||||
*****************************************************************************
|
|
||||||
* Bug reports, patches, comments, suggestions should be sent to:
|
|
||||||
*
|
|
||||||
* Ben Smith, Rick Grehan or Tom Yager
|
|
||||||
* ben@bytepb.byte.com rick_g@bytepb.byte.com tyager@bytepb.byte.com
|
|
||||||
*
|
|
||||||
*****************************************************************************
|
|
||||||
* Modification Log:
|
|
||||||
* addapted from:
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* "DHRYSTONE" Benchmark Program
|
|
||||||
* -----------------------------
|
|
||||||
*
|
|
||||||
* Version: C, Version 2.1
|
|
||||||
*
|
|
||||||
* File: dhry.h (part 1 of 3)
|
|
||||||
*
|
|
||||||
* Date: May 25, 1988
|
|
||||||
*
|
|
||||||
* Author: Reinhold P. Weicker
|
|
||||||
* Siemens AG, AUT E 51
|
|
||||||
* Postfach 3220
|
|
||||||
* 8520 Erlangen
|
|
||||||
* Germany (West)
|
|
||||||
* Phone: [+49]-9131-7-20330
|
|
||||||
* (8-17 Central European Time)
|
|
||||||
* Usenet: ..!mcvax!unido!estevax!weicker
|
|
||||||
*
|
|
||||||
* Original Version (in Ada) published in
|
|
||||||
* "Communications of the ACM" vol. 27., no. 10 (Oct. 1984),
|
|
||||||
* pp. 1013 - 1030, together with the statistics
|
|
||||||
* on which the distribution of statements etc. is based.
|
|
||||||
*
|
|
||||||
* In this C version, the following C library functions are used:
|
|
||||||
* - strcpy, strcmp (inside the measurement loop)
|
|
||||||
* - printf, scanf (outside the measurement loop)
|
|
||||||
* In addition, Berkeley UNIX system calls "times ()" or "time ()"
|
|
||||||
* are used for execution time measurement. For measurements
|
|
||||||
* on other systems, these calls have to be changed.
|
|
||||||
*
|
|
||||||
* Collection of Results:
|
|
||||||
* Reinhold Weicker (address see above) and
|
|
||||||
*
|
|
||||||
* Rick Richardson
|
|
||||||
* PC Research. Inc.
|
|
||||||
* 94 Apple Orchard Drive
|
|
||||||
* Tinton Falls, NJ 07724
|
|
||||||
* Phone: (201) 834-1378 (9-17 EST)
|
|
||||||
* Usenet: ...!seismo!uunet!pcrat!rick
|
|
||||||
*
|
|
||||||
* Please send results to Rick Richardson and/or Reinhold Weicker.
|
|
||||||
* Complete information should be given on hardware and software used.
|
|
||||||
* Hardware information includes: Machine type, CPU, type and size
|
|
||||||
* of caches; for microprocessors: clock frequency, memory speed
|
|
||||||
* (number of wait states).
|
|
||||||
* Software information includes: Compiler (and runtime library)
|
|
||||||
* manufacturer and version, compilation switches, OS version.
|
|
||||||
* The Operating System version may give an indication about the
|
|
||||||
* compiler; Dhrystone itself performs no OS calls in the measurement loop.
|
|
||||||
*
|
|
||||||
* The complete output generated by the program should be mailed
|
|
||||||
* such that at least some checks for correctness can be made.
|
|
||||||
*
|
|
||||||
***************************************************************************
|
|
||||||
*
|
|
||||||
* History: This version C/2.1 has been made for two reasons:
|
|
||||||
*
|
|
||||||
* 1) There is an obvious need for a common C version of
|
|
||||||
* Dhrystone, since C is at present the most popular system
|
|
||||||
* programming language for the class of processors
|
|
||||||
* (microcomputers, minicomputers) where Dhrystone is used most.
|
|
||||||
* There should be, as far as possible, only one C version of
|
|
||||||
* Dhrystone such that results can be compared without
|
|
||||||
* restrictions. In the past, the C versions distributed
|
|
||||||
* by Rick Richardson (Version 1.1) and by Reinhold Weicker
|
|
||||||
* had small (though not significant) differences.
|
|
||||||
*
|
|
||||||
* 2) As far as it is possible without changes to the Dhrystone
|
|
||||||
* statistics, optimizing compilers should be prevented from
|
|
||||||
* removing significant statements.
|
|
||||||
*
|
|
||||||
* This C version has been developed in cooperation with
|
|
||||||
* Rick Richardson (Tinton Falls, NJ), it incorporates many
|
|
||||||
* ideas from the "Version 1.1" distributed previously by
|
|
||||||
* him over the UNIX network Usenet.
|
|
||||||
* I also thank Chaim Benedelac (National Semiconductor),
|
|
||||||
* David Ditzel (SUN), Earl Killian and John Mashey (MIPS),
|
|
||||||
* Alan Smith and Rafael Saavedra-Barrera (UC at Berkeley)
|
|
||||||
* for their help with comments on earlier versions of the
|
|
||||||
* benchmark.
|
|
||||||
*
|
|
||||||
* Changes: In the initialization part, this version follows mostly
|
|
||||||
* Rick Richardson's version distributed via Usenet, not the
|
|
||||||
* version distributed earlier via floppy disk by Reinhold Weicker.
|
|
||||||
* As a concession to older compilers, names have been made
|
|
||||||
* unique within the first 8 characters.
|
|
||||||
* Inside the measurement loop, this version follows the
|
|
||||||
* version previously distributed by Reinhold Weicker.
|
|
||||||
*
|
|
||||||
* At several places in the benchmark, code has been added,
|
|
||||||
* but within the measurement loop only in branches that
|
|
||||||
* are not executed. The intention is that optimizing compilers
|
|
||||||
* should be prevented from moving code out of the measurement
|
|
||||||
* loop, or from removing code altogether. Since the statements
|
|
||||||
* that are executed within the measurement loop have NOT been
|
|
||||||
* changed, the numbers defining the "Dhrystone distribution"
|
|
||||||
* (distribution of statements, operand types and locality)
|
|
||||||
* still hold. Except for sophisticated optimizing compilers,
|
|
||||||
* execution times for this version should be the same as
|
|
||||||
* for previous versions.
|
|
||||||
*
|
|
||||||
* Since it has proven difficult to subtract the time for the
|
|
||||||
* measurement loop overhead in a correct way, the loop check
|
|
||||||
* has been made a part of the benchmark. This does have
|
|
||||||
* an impact - though a very minor one - on the distribution
|
|
||||||
* statistics which have been updated for this version.
|
|
||||||
*
|
|
||||||
* All changes within the measurement loop are described
|
|
||||||
* and discussed in the companion paper "Rationale for
|
|
||||||
* Dhrystone version 2".
|
|
||||||
*
|
|
||||||
* Because of the self-imposed limitation that the order and
|
|
||||||
* distribution of the executed statements should not be
|
|
||||||
* changed, there are still cases where optimizing compilers
|
|
||||||
* may not generate code for some statements. To a certain
|
|
||||||
* degree, this is unavoidable for small synthetic benchmarks.
|
|
||||||
* Users of the benchmark are advised to check code listings
|
|
||||||
* whether code is generated for all statements of Dhrystone.
|
|
||||||
*
|
|
||||||
* Version 2.1 is identical to version 2.0 distributed via
|
|
||||||
* the UNIX network Usenet in March 1988 except that it corrects
|
|
||||||
* some minor deficiencies that were found by users of version 2.0.
|
|
||||||
* The only change within the measurement loop is that a
|
|
||||||
* non-executed "else" part was added to the "if" statement in
|
|
||||||
* Func_3, and a non-executed "else" part removed from Proc_3.
|
|
||||||
*
|
|
||||||
***************************************************************************
|
|
||||||
*
|
|
||||||
* Defines: The following "Defines" are possible:
|
|
||||||
* -DREG=register (default: Not defined)
|
|
||||||
* As an approximation to what an average C programmer
|
|
||||||
* might do, the "register" storage class is applied
|
|
||||||
* (if enabled by -DREG=register)
|
|
||||||
* - for local variables, if they are used (dynamically)
|
|
||||||
* five or more times
|
|
||||||
* - for parameters if they are used (dynamically)
|
|
||||||
* six or more times
|
|
||||||
* Note that an optimal "register" strategy is
|
|
||||||
* compiler-dependent, and that "register" declarations
|
|
||||||
* do not necessarily lead to faster execution.
|
|
||||||
* -DNOSTRUCTASSIGN (default: Not defined)
|
|
||||||
* Define if the C compiler does not support
|
|
||||||
* assignment of structures.
|
|
||||||
* -DNOENUMS (default: Not defined)
|
|
||||||
* Define if the C compiler does not support
|
|
||||||
* enumeration types.
|
|
||||||
* -DTIMES (default)
|
|
||||||
* -DTIME
|
|
||||||
* The "times" function of UNIX (returning process times)
|
|
||||||
* or the "time" function (returning wallclock time)
|
|
||||||
* is used for measurement.
|
|
||||||
* For single user machines, "time ()" is adequate. For
|
|
||||||
* multi-user machines where you cannot get single-user
|
|
||||||
* access, use the "times ()" function. If you have
|
|
||||||
* neither, use a stopwatch in the dead of night.
|
|
||||||
* "printf"s are provided marking the points "Start Timer"
|
|
||||||
* and "Stop Timer". DO NOT use the UNIX "time(1)"
|
|
||||||
* command, as this will measure the total time to
|
|
||||||
* run this program, which will (erroneously) include
|
|
||||||
* the time to allocate storage (malloc) and to perform
|
|
||||||
* the initialization.
|
|
||||||
* -DHZ=nnn
|
|
||||||
* In Berkeley UNIX, the function "times" returns process
|
|
||||||
* time in 1/HZ seconds, with HZ = 60 for most systems.
|
|
||||||
* CHECK YOUR SYSTEM DESCRIPTION BEFORE YOU JUST APPLY
|
|
||||||
* A VALUE.
|
|
||||||
*
|
|
||||||
***************************************************************************
|
|
||||||
*
|
|
||||||
* Compilation model and measurement (IMPORTANT):
|
|
||||||
*
|
|
||||||
* This C version of Dhrystone consists of three files:
|
|
||||||
* - dhry.h (this file, containing global definitions and comments)
|
|
||||||
* - dhry_1.c (containing the code corresponding to Ada package Pack_1)
|
|
||||||
* - dhry_2.c (containing the code corresponding to Ada package Pack_2)
|
|
||||||
*
|
|
||||||
* The following "ground rules" apply for measurements:
|
|
||||||
* - Separate compilation
|
|
||||||
* - No procedure merging
|
|
||||||
* - Otherwise, compiler optimizations are allowed but should be indicated
|
|
||||||
* - Default results are those without register declarations
|
|
||||||
* See the companion paper "Rationale for Dhrystone Version 2" for a more
|
|
||||||
* detailed discussion of these ground rules.
|
|
||||||
*
|
|
||||||
* For 16-Bit processors (e.g. 80186, 80286), times for all compilation
|
|
||||||
* models ("small", "medium", "large" etc.) should be given if possible,
|
|
||||||
* together with a definition of these models for the compiler system used.
|
|
||||||
*
|
|
||||||
**************************************************************************
|
|
||||||
*
|
|
||||||
* Dhrystone (C version) statistics:
|
|
||||||
*
|
|
||||||
* [Comment from the first distribution, updated for version 2.
|
|
||||||
* Note that because of language differences, the numbers are slightly
|
|
||||||
* different from the Ada version.]
|
|
||||||
*
|
|
||||||
* The following program contains statements of a high level programming
|
|
||||||
* language (here: C) in a distribution considered representative:
|
|
||||||
*
|
|
||||||
* assignments 52 (51.0 %)
|
|
||||||
* control statements 33 (32.4 %)
|
|
||||||
* procedure, function calls 17 (16.7 %)
|
|
||||||
*
|
|
||||||
* 103 statements are dynamically executed. The program is balanced with
|
|
||||||
* respect to the three aspects:
|
|
||||||
*
|
|
||||||
* - statement type
|
|
||||||
* - operand type
|
|
||||||
* - operand locality
|
|
||||||
* operand global, local, parameter, or constant.
|
|
||||||
*
|
|
||||||
* The combination of these three aspects is balanced only approximately.
|
|
||||||
*
|
|
||||||
* 1. Statement Type:
|
|
||||||
* ----------------- number
|
|
||||||
*
|
|
||||||
* V1 = V2 9
|
|
||||||
* (incl. V1 = F(..)
|
|
||||||
* V = Constant 12
|
|
||||||
* Assignment, 7
|
|
||||||
* with array element
|
|
||||||
* Assignment, 6
|
|
||||||
* with record component
|
|
||||||
* --
|
|
||||||
* 34 34
|
|
||||||
*
|
|
||||||
* X = Y +|-|"&&"|"|" Z 5
|
|
||||||
* X = Y +|-|"==" Constant 6
|
|
||||||
* X = X +|- 1 3
|
|
||||||
* X = Y *|/ Z 2
|
|
||||||
* X = Expression, 1
|
|
||||||
* two operators
|
|
||||||
* X = Expression, 1
|
|
||||||
* three operators
|
|
||||||
* --
|
|
||||||
* 18 18
|
|
||||||
*
|
|
||||||
* if .... 14
|
|
||||||
* with "else" 7
|
|
||||||
* without "else" 7
|
|
||||||
* executed 3
|
|
||||||
* not executed 4
|
|
||||||
* for ... 7 | counted every time
|
|
||||||
* while ... 4 | the loop condition
|
|
||||||
* do ... while 1 | is evaluated
|
|
||||||
* switch ... 1
|
|
||||||
* break 1
|
|
||||||
* declaration with 1
|
|
||||||
* initialization
|
|
||||||
* --
|
|
||||||
* 34 34
|
|
||||||
*
|
|
||||||
* P (...) procedure call 11
|
|
||||||
* user procedure 10
|
|
||||||
* library procedure 1
|
|
||||||
* X = F (...)
|
|
||||||
* function call 6
|
|
||||||
* user function 5
|
|
||||||
* library function 1
|
|
||||||
* --
|
|
||||||
* 17 17
|
|
||||||
* ---
|
|
||||||
* 103
|
|
||||||
*
|
|
||||||
* The average number of parameters in procedure or function calls
|
|
||||||
* is 1.82 (not counting the function values as implicit parameters).
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* 2. Operators
|
|
||||||
* ------------
|
|
||||||
* number approximate
|
|
||||||
* percentage
|
|
||||||
*
|
|
||||||
* Arithmetic 32 50.8
|
|
||||||
*
|
|
||||||
* + 21 33.3
|
|
||||||
* - 7 11.1
|
|
||||||
* * 3 4.8
|
|
||||||
* / (int div) 1 1.6
|
|
||||||
*
|
|
||||||
* Comparison 27 42.8
|
|
||||||
*
|
|
||||||
* == 9 14.3
|
|
||||||
* /= 4 6.3
|
|
||||||
* > 1 1.6
|
|
||||||
* < 3 4.8
|
|
||||||
* >= 1 1.6
|
|
||||||
* <= 9 14.3
|
|
||||||
*
|
|
||||||
* Logic 4 6.3
|
|
||||||
*
|
|
||||||
* && (AND-THEN) 1 1.6
|
|
||||||
* | (OR) 1 1.6
|
|
||||||
* ! (NOT) 2 3.2
|
|
||||||
*
|
|
||||||
* -- -----
|
|
||||||
* 63 100.1
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* 3. Operand Type (counted once per operand reference):
|
|
||||||
* ---------------
|
|
||||||
* number approximate
|
|
||||||
* percentage
|
|
||||||
*
|
|
||||||
* Integer 175 72.3 %
|
|
||||||
* Character 45 18.6 %
|
|
||||||
* Pointer 12 5.0 %
|
|
||||||
* String30 6 2.5 %
|
|
||||||
* Array 2 0.8 %
|
|
||||||
* Record 2 0.8 %
|
|
||||||
* --- -------
|
|
||||||
* 242 100.0 %
|
|
||||||
*
|
|
||||||
* When there is an access path leading to the final operand (e.g. a record
|
|
||||||
* component), only the final data type on the access path is counted.
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* 4. Operand Locality:
|
|
||||||
* -------------------
|
|
||||||
* number approximate
|
|
||||||
* percentage
|
|
||||||
*
|
|
||||||
* local variable 114 47.1 %
|
|
||||||
* global variable 22 9.1 %
|
|
||||||
* parameter 45 18.6 %
|
|
||||||
* value 23 9.5 %
|
|
||||||
* reference 22 9.1 %
|
|
||||||
* function result 6 2.5 %
|
|
||||||
* constant 55 22.7 %
|
|
||||||
* --- -------
|
|
||||||
* 242 100.0 %
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* The program does not compute anything meaningful, but it is syntactically
|
|
||||||
* and semantically correct. All variables have a value assigned to them
|
|
||||||
* before they are used as a source operand.
|
|
||||||
*
|
|
||||||
* There has been no explicit effort to account for the effects of a
|
|
||||||
* cache, or to balance the use of long or short displacements for code or
|
|
||||||
* data.
|
|
||||||
*
|
|
||||||
***************************************************************************
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
/* Compiler and system dependent definitions: */
|
|
||||||
|
|
||||||
#ifndef TIME
|
|
||||||
#define TIMES
|
|
||||||
#endif
|
|
||||||
/* Use times(2) time function unless */
|
|
||||||
/* explicitly defined otherwise */
|
|
||||||
|
|
||||||
#ifdef TIMES
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/times.h>
|
|
||||||
/* for "times" */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define Mic_secs_Per_Second 1000000.0
|
|
||||||
/* Berkeley UNIX C returns process times in seconds/HZ */
|
|
||||||
|
|
||||||
#ifdef NOSTRUCTASSIGN
|
|
||||||
#define structassign(d, s) memcpy(&(d), &(s), sizeof(d))
|
|
||||||
#else
|
|
||||||
#define structassign(d, s) d = s
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef NOENUM
|
|
||||||
#define Ident_1 0
|
|
||||||
#define Ident_2 1
|
|
||||||
#define Ident_3 2
|
|
||||||
#define Ident_4 3
|
|
||||||
#define Ident_5 4
|
|
||||||
typedef int Enumeration;
|
|
||||||
#else
|
|
||||||
typedef enum {Ident_1, Ident_2, Ident_3, Ident_4, Ident_5}
|
|
||||||
Enumeration;
|
|
||||||
#endif
|
|
||||||
/* for boolean and enumeration types in Ada, Pascal */
|
|
||||||
|
|
||||||
/* General definitions: */
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
/* for strcpy, strcmp */
|
|
||||||
|
|
||||||
#define Null 0
|
|
||||||
/* Value of a Null pointer */
|
|
||||||
#define true 1
|
|
||||||
#define false 0
|
|
||||||
|
|
||||||
typedef int One_Thirty;
|
|
||||||
typedef int One_Fifty;
|
|
||||||
typedef char Capital_Letter;
|
|
||||||
typedef int Boolean;
|
|
||||||
typedef char Str_30 [31];
|
|
||||||
typedef int Arr_1_Dim [50];
|
|
||||||
typedef int Arr_2_Dim [50] [50];
|
|
||||||
|
|
||||||
typedef struct record
|
|
||||||
{
|
|
||||||
struct record *Ptr_Comp;
|
|
||||||
Enumeration Discr;
|
|
||||||
union {
|
|
||||||
struct {
|
|
||||||
Enumeration Enum_Comp;
|
|
||||||
int Int_Comp;
|
|
||||||
char Str_Comp [31];
|
|
||||||
} var_1;
|
|
||||||
struct {
|
|
||||||
Enumeration E_Comp_2;
|
|
||||||
char Str_2_Comp [31];
|
|
||||||
} var_2;
|
|
||||||
struct {
|
|
||||||
char Ch_1_Comp;
|
|
||||||
char Ch_2_Comp;
|
|
||||||
} var_3;
|
|
||||||
} variant;
|
|
||||||
} Rec_Type, *Rec_Pointer;
|
|
||||||
|
|
|
@ -1,427 +0,0 @@
|
||||||
/*****************************************************************************
|
|
||||||
* The BYTE UNIX Benchmarks - Release 3
|
|
||||||
* Module: dhry_1.c SID: 3.4 5/15/91 19:30:21
|
|
||||||
*
|
|
||||||
*****************************************************************************
|
|
||||||
* Bug reports, patches, comments, suggestions should be sent to:
|
|
||||||
*
|
|
||||||
* Ben Smith, Rick Grehan or Tom Yager
|
|
||||||
* ben@bytepb.byte.com rick_g@bytepb.byte.com tyager@bytepb.byte.com
|
|
||||||
*
|
|
||||||
*****************************************************************************
|
|
||||||
*
|
|
||||||
* *** WARNING **** With BYTE's modifications applied, results obtained with
|
|
||||||
* ******* this version of the Dhrystone program may not be applicable
|
|
||||||
* to other versions.
|
|
||||||
*
|
|
||||||
* Modification Log:
|
|
||||||
* 10/22/97 - code cleanup to remove ANSI C compiler warnings
|
|
||||||
* Andy Kahn <kahn@zk3.dec.com>
|
|
||||||
*
|
|
||||||
* Adapted from:
|
|
||||||
*
|
|
||||||
* "DHRYSTONE" Benchmark Program
|
|
||||||
* -----------------------------
|
|
||||||
*
|
|
||||||
* Version: C, Version 2.1
|
|
||||||
*
|
|
||||||
* File: dhry_1.c (part 2 of 3)
|
|
||||||
*
|
|
||||||
* Date: May 25, 1988
|
|
||||||
*
|
|
||||||
* Author: Reinhold P. Weicker
|
|
||||||
*
|
|
||||||
***************************************************************************/
|
|
||||||
char SCCSid[] = "@(#) @(#)dhry_1.c:3.4 -- 5/15/91 19:30:21";
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include "dhry.h"
|
|
||||||
#include "timeit.c"
|
|
||||||
|
|
||||||
unsigned long Run_Index;
|
|
||||||
|
|
||||||
Enumeration Func_1(Capital_Letter, Capital_Letter);
|
|
||||||
|
|
||||||
void report(int sig)
|
|
||||||
{
|
|
||||||
fprintf(stderr,"COUNT|%ld|1|lps\n", Run_Index);
|
|
||||||
exit(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Global Variables: */
|
|
||||||
|
|
||||||
Rec_Pointer Ptr_Glob,
|
|
||||||
Next_Ptr_Glob;
|
|
||||||
int Int_Glob;
|
|
||||||
Boolean Bool_Glob;
|
|
||||||
char Ch_1_Glob,
|
|
||||||
Ch_2_Glob;
|
|
||||||
int Arr_1_Glob [50];
|
|
||||||
int Arr_2_Glob [50] [50];
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef REG
|
|
||||||
Boolean Reg = false;
|
|
||||||
#define REG
|
|
||||||
/* REG becomes defined as empty */
|
|
||||||
/* i.e. no register variables */
|
|
||||||
#else
|
|
||||||
Boolean Reg = true;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* variables for time measurement: */
|
|
||||||
|
|
||||||
#ifdef TIMES
|
|
||||||
struct tms time_info;
|
|
||||||
extern int times ();
|
|
||||||
/* see library function "times" */
|
|
||||||
#define Too_Small_Time 120
|
|
||||||
/* Measurements should last at least about 2 seconds */
|
|
||||||
#endif
|
|
||||||
#ifdef TIME
|
|
||||||
#define Too_Small_Time 2
|
|
||||||
/* Measurements should last at least 2 seconds */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
long Begin_Time,
|
|
||||||
End_Time,
|
|
||||||
User_Time;
|
|
||||||
float Microseconds,
|
|
||||||
Dhrystones_Per_Second;
|
|
||||||
|
|
||||||
/* end of variables for time measurement */
|
|
||||||
|
|
||||||
void Proc_1 (REG Rec_Pointer Ptr_Val_Par);
|
|
||||||
void Proc_2 (One_Fifty *Int_Par_Ref);
|
|
||||||
void Proc_3 (Rec_Pointer *Ptr_Ref_Par);
|
|
||||||
void Proc_4 (void);
|
|
||||||
void Proc_5 (void);
|
|
||||||
|
|
||||||
|
|
||||||
extern Boolean Func_2(Str_30, Str_30);
|
|
||||||
extern void Proc_6(Enumeration, Enumeration *);
|
|
||||||
extern void Proc_7(One_Fifty, One_Fifty, One_Fifty *);
|
|
||||||
extern void Proc_8(Arr_1_Dim, Arr_2_Dim, int, int);
|
|
||||||
|
|
||||||
int main (int argc, char *argv[])
|
|
||||||
/* main program, corresponds to procedures */
|
|
||||||
/* Main and Proc_0 in the Ada version */
|
|
||||||
{
|
|
||||||
int duration;
|
|
||||||
One_Fifty Int_1_Loc;
|
|
||||||
REG One_Fifty Int_2_Loc;
|
|
||||||
One_Fifty Int_3_Loc;
|
|
||||||
REG char Ch_Index;
|
|
||||||
Enumeration Enum_Loc;
|
|
||||||
Str_30 Str_1_Loc;
|
|
||||||
Str_30 Str_2_Loc;
|
|
||||||
|
|
||||||
/* Initializations */
|
|
||||||
|
|
||||||
Next_Ptr_Glob = (Rec_Pointer) malloc (sizeof (Rec_Type));
|
|
||||||
Ptr_Glob = (Rec_Pointer) malloc (sizeof (Rec_Type));
|
|
||||||
|
|
||||||
Ptr_Glob->Ptr_Comp = Next_Ptr_Glob;
|
|
||||||
Ptr_Glob->Discr = Ident_1;
|
|
||||||
Ptr_Glob->variant.var_1.Enum_Comp = Ident_3;
|
|
||||||
Ptr_Glob->variant.var_1.Int_Comp = 40;
|
|
||||||
strcpy (Ptr_Glob->variant.var_1.Str_Comp,
|
|
||||||
"DHRYSTONE PROGRAM, SOME STRING");
|
|
||||||
strcpy (Str_1_Loc, "DHRYSTONE PROGRAM, 1'ST STRING");
|
|
||||||
|
|
||||||
Arr_2_Glob [8][7] = 10;
|
|
||||||
/* Was missing in published program. Without this statement, */
|
|
||||||
/* Arr_2_Glob [8][7] would have an undefined value. */
|
|
||||||
/* Warning: With 16-Bit processors and Number_Of_Runs > 32000, */
|
|
||||||
/* overflow may occur for this array element. */
|
|
||||||
|
|
||||||
#ifdef PRATTLE
|
|
||||||
printf ("\n");
|
|
||||||
printf ("Dhrystone Benchmark, Version 2.1 (Language: C)\n");
|
|
||||||
printf ("\n");
|
|
||||||
if (Reg)
|
|
||||||
{
|
|
||||||
printf ("Program compiled with 'register' attribute\n");
|
|
||||||
printf ("\n");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
printf ("Program compiled without 'register' attribute\n");
|
|
||||||
printf ("\n");
|
|
||||||
}
|
|
||||||
printf ("Please give the number of runs through the benchmark: ");
|
|
||||||
{
|
|
||||||
int n;
|
|
||||||
scanf ("%d", &n);
|
|
||||||
Number_Of_Runs = n;
|
|
||||||
}
|
|
||||||
printf ("\n");
|
|
||||||
|
|
||||||
printf ("Execution starts, %d runs through Dhrystone\n", Number_Of_Runs);
|
|
||||||
#endif /* PRATTLE */
|
|
||||||
|
|
||||||
if (argc != 2) {
|
|
||||||
fprintf(stderr, "Usage: %s duration\n", argv[0]);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
duration = atoi(argv[1]);
|
|
||||||
Run_Index = 0;
|
|
||||||
wake_me(duration, report);
|
|
||||||
|
|
||||||
/***************/
|
|
||||||
/* Start timer */
|
|
||||||
/***************/
|
|
||||||
|
|
||||||
#ifdef SELF_TIMED
|
|
||||||
#ifdef TIMES
|
|
||||||
times (&time_info);
|
|
||||||
Begin_Time = (long) time_info.tms_utime;
|
|
||||||
#endif
|
|
||||||
#ifdef TIME
|
|
||||||
Begin_Time = time ( (long *) 0);
|
|
||||||
#endif
|
|
||||||
#endif /* SELF_TIMED */
|
|
||||||
|
|
||||||
for (Run_Index = 1; ; ++Run_Index)
|
|
||||||
{
|
|
||||||
|
|
||||||
Proc_5();
|
|
||||||
Proc_4();
|
|
||||||
/* Ch_1_Glob == 'A', Ch_2_Glob == 'B', Bool_Glob == true */
|
|
||||||
Int_1_Loc = 2;
|
|
||||||
Int_2_Loc = 3;
|
|
||||||
strcpy (Str_2_Loc, "DHRYSTONE PROGRAM, 2'ND STRING");
|
|
||||||
Enum_Loc = Ident_2;
|
|
||||||
Bool_Glob = ! Func_2 (Str_1_Loc, Str_2_Loc);
|
|
||||||
/* Bool_Glob == 1 */
|
|
||||||
while (Int_1_Loc < Int_2_Loc) /* loop body executed once */
|
|
||||||
{
|
|
||||||
Int_3_Loc = 5 * Int_1_Loc - Int_2_Loc;
|
|
||||||
/* Int_3_Loc == 7 */
|
|
||||||
Proc_7 (Int_1_Loc, Int_2_Loc, &Int_3_Loc);
|
|
||||||
/* Int_3_Loc == 7 */
|
|
||||||
Int_1_Loc += 1;
|
|
||||||
} /* while */
|
|
||||||
/* Int_1_Loc == 3, Int_2_Loc == 3, Int_3_Loc == 7 */
|
|
||||||
Proc_8 (Arr_1_Glob, Arr_2_Glob, Int_1_Loc, Int_3_Loc);
|
|
||||||
/* Int_Glob == 5 */
|
|
||||||
Proc_1 (Ptr_Glob);
|
|
||||||
for (Ch_Index = 'A'; Ch_Index <= Ch_2_Glob; ++Ch_Index)
|
|
||||||
/* loop body executed twice */
|
|
||||||
{
|
|
||||||
if (Enum_Loc == Func_1 (Ch_Index, 'C'))
|
|
||||||
/* then, not executed */
|
|
||||||
{
|
|
||||||
Proc_6 (Ident_1, &Enum_Loc);
|
|
||||||
strcpy (Str_2_Loc, "DHRYSTONE PROGRAM, 3'RD STRING");
|
|
||||||
Int_2_Loc = Run_Index;
|
|
||||||
Int_Glob = Run_Index;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* Int_1_Loc == 3, Int_2_Loc == 3, Int_3_Loc == 7 */
|
|
||||||
Int_2_Loc = Int_2_Loc * Int_1_Loc;
|
|
||||||
Int_1_Loc = Int_2_Loc / Int_3_Loc;
|
|
||||||
Int_2_Loc = 7 * (Int_2_Loc - Int_3_Loc) - Int_1_Loc;
|
|
||||||
/* Int_1_Loc == 1, Int_2_Loc == 13, Int_3_Loc == 7 */
|
|
||||||
Proc_2 (&Int_1_Loc);
|
|
||||||
/* Int_1_Loc == 5 */
|
|
||||||
|
|
||||||
} /* loop "for Run_Index" */
|
|
||||||
|
|
||||||
/**************/
|
|
||||||
/* Stop timer */
|
|
||||||
/**************/
|
|
||||||
#ifdef SELF_TIMED
|
|
||||||
#ifdef TIMES
|
|
||||||
times (&time_info);
|
|
||||||
End_Time = (long) time_info.tms_utime;
|
|
||||||
#endif
|
|
||||||
#ifdef TIME
|
|
||||||
End_Time = time ( (long *) 0);
|
|
||||||
#endif
|
|
||||||
#endif /* SELF_TIMED */
|
|
||||||
|
|
||||||
/* BYTE version never executes this stuff */
|
|
||||||
#ifdef SELF_TIMED
|
|
||||||
printf ("Execution ends\n");
|
|
||||||
printf ("\n");
|
|
||||||
printf ("Final values of the variables used in the benchmark:\n");
|
|
||||||
printf ("\n");
|
|
||||||
printf ("Int_Glob: %d\n", Int_Glob);
|
|
||||||
printf (" should be: %d\n", 5);
|
|
||||||
printf ("Bool_Glob: %d\n", Bool_Glob);
|
|
||||||
printf (" should be: %d\n", 1);
|
|
||||||
printf ("Ch_1_Glob: %c\n", Ch_1_Glob);
|
|
||||||
printf (" should be: %c\n", 'A');
|
|
||||||
printf ("Ch_2_Glob: %c\n", Ch_2_Glob);
|
|
||||||
printf (" should be: %c\n", 'B');
|
|
||||||
printf ("Arr_1_Glob[8]: %d\n", Arr_1_Glob[8]);
|
|
||||||
printf (" should be: %d\n", 7);
|
|
||||||
printf ("Arr_2_Glob[8][7]: %d\n", Arr_2_Glob[8][7]);
|
|
||||||
printf (" should be: Number_Of_Runs + 10\n");
|
|
||||||
printf ("Ptr_Glob->\n");
|
|
||||||
printf (" Ptr_Comp: %d\n", (int) Ptr_Glob->Ptr_Comp);
|
|
||||||
printf (" should be: (implementation-dependent)\n");
|
|
||||||
printf (" Discr: %d\n", Ptr_Glob->Discr);
|
|
||||||
printf (" should be: %d\n", 0);
|
|
||||||
printf (" Enum_Comp: %d\n", Ptr_Glob->variant.var_1.Enum_Comp);
|
|
||||||
printf (" should be: %d\n", 2);
|
|
||||||
printf (" Int_Comp: %d\n", Ptr_Glob->variant.var_1.Int_Comp);
|
|
||||||
printf (" should be: %d\n", 17);
|
|
||||||
printf (" Str_Comp: %s\n", Ptr_Glob->variant.var_1.Str_Comp);
|
|
||||||
printf (" should be: DHRYSTONE PROGRAM, SOME STRING\n");
|
|
||||||
printf ("Next_Ptr_Glob->\n");
|
|
||||||
printf (" Ptr_Comp: %d\n", (int) Next_Ptr_Glob->Ptr_Comp);
|
|
||||||
printf (" should be: (implementation-dependent), same as above\n");
|
|
||||||
printf (" Discr: %d\n", Next_Ptr_Glob->Discr);
|
|
||||||
printf (" should be: %d\n", 0);
|
|
||||||
printf (" Enum_Comp: %d\n", Next_Ptr_Glob->variant.var_1.Enum_Comp);
|
|
||||||
printf (" should be: %d\n", 1);
|
|
||||||
printf (" Int_Comp: %d\n", Next_Ptr_Glob->variant.var_1.Int_Comp);
|
|
||||||
printf (" should be: %d\n", 18);
|
|
||||||
printf (" Str_Comp: %s\n",
|
|
||||||
Next_Ptr_Glob->variant.var_1.Str_Comp);
|
|
||||||
printf (" should be: DHRYSTONE PROGRAM, SOME STRING\n");
|
|
||||||
printf ("Int_1_Loc: %d\n", Int_1_Loc);
|
|
||||||
printf (" should be: %d\n", 5);
|
|
||||||
printf ("Int_2_Loc: %d\n", Int_2_Loc);
|
|
||||||
printf (" should be: %d\n", 13);
|
|
||||||
printf ("Int_3_Loc: %d\n", Int_3_Loc);
|
|
||||||
printf (" should be: %d\n", 7);
|
|
||||||
printf ("Enum_Loc: %d\n", Enum_Loc);
|
|
||||||
printf (" should be: %d\n", 1);
|
|
||||||
printf ("Str_1_Loc: %s\n", Str_1_Loc);
|
|
||||||
printf (" should be: DHRYSTONE PROGRAM, 1'ST STRING\n");
|
|
||||||
printf ("Str_2_Loc: %s\n", Str_2_Loc);
|
|
||||||
printf (" should be: DHRYSTONE PROGRAM, 2'ND STRING\n");
|
|
||||||
printf ("\n");
|
|
||||||
|
|
||||||
User_Time = End_Time - Begin_Time;
|
|
||||||
|
|
||||||
if (User_Time < Too_Small_Time)
|
|
||||||
{
|
|
||||||
printf ("Measured time too small to obtain meaningful results\n");
|
|
||||||
printf ("Please increase number of runs\n");
|
|
||||||
printf ("\n");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
#ifdef TIME
|
|
||||||
Microseconds = (float) User_Time * Mic_secs_Per_Second
|
|
||||||
/ (float) Number_Of_Runs;
|
|
||||||
Dhrystones_Per_Second = (float) Number_Of_Runs / (float) User_Time;
|
|
||||||
#else
|
|
||||||
Microseconds = (float) User_Time * Mic_secs_Per_Second
|
|
||||||
/ ((float) HZ * ((float) Number_Of_Runs));
|
|
||||||
Dhrystones_Per_Second = ((float) HZ * (float) Number_Of_Runs)
|
|
||||||
/ (float) User_Time;
|
|
||||||
#endif
|
|
||||||
printf ("Microseconds for one run through Dhrystone: ");
|
|
||||||
printf ("%6.1f \n", Microseconds);
|
|
||||||
printf ("Dhrystones per Second: ");
|
|
||||||
printf ("%6.1f \n", Dhrystones_Per_Second);
|
|
||||||
printf ("\n");
|
|
||||||
}
|
|
||||||
#endif /* SELF_TIMED */
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Proc_1 (REG Rec_Pointer Ptr_Val_Par)
|
|
||||||
/* executed once */
|
|
||||||
{
|
|
||||||
REG Rec_Pointer Next_Record = Ptr_Val_Par->Ptr_Comp;
|
|
||||||
/* == Ptr_Glob_Next */
|
|
||||||
/* Local variable, initialized with Ptr_Val_Par->Ptr_Comp, */
|
|
||||||
/* corresponds to "rename" in Ada, "with" in Pascal */
|
|
||||||
|
|
||||||
structassign (*Ptr_Val_Par->Ptr_Comp, *Ptr_Glob);
|
|
||||||
Ptr_Val_Par->variant.var_1.Int_Comp = 5;
|
|
||||||
Next_Record->variant.var_1.Int_Comp
|
|
||||||
= Ptr_Val_Par->variant.var_1.Int_Comp;
|
|
||||||
Next_Record->Ptr_Comp = Ptr_Val_Par->Ptr_Comp;
|
|
||||||
Proc_3 (&Next_Record->Ptr_Comp);
|
|
||||||
/* Ptr_Val_Par->Ptr_Comp->Ptr_Comp
|
|
||||||
== Ptr_Glob->Ptr_Comp */
|
|
||||||
if (Next_Record->Discr == Ident_1)
|
|
||||||
/* then, executed */
|
|
||||||
{
|
|
||||||
Next_Record->variant.var_1.Int_Comp = 6;
|
|
||||||
Proc_6 (Ptr_Val_Par->variant.var_1.Enum_Comp,
|
|
||||||
&Next_Record->variant.var_1.Enum_Comp);
|
|
||||||
Next_Record->Ptr_Comp = Ptr_Glob->Ptr_Comp;
|
|
||||||
Proc_7 (Next_Record->variant.var_1.Int_Comp, 10,
|
|
||||||
&Next_Record->variant.var_1.Int_Comp);
|
|
||||||
}
|
|
||||||
else /* not executed */
|
|
||||||
structassign (*Ptr_Val_Par, *Ptr_Val_Par->Ptr_Comp);
|
|
||||||
} /* Proc_1 */
|
|
||||||
|
|
||||||
|
|
||||||
void Proc_2 (One_Fifty *Int_Par_Ref)
|
|
||||||
/* executed once */
|
|
||||||
/* *Int_Par_Ref == 1, becomes 4 */
|
|
||||||
{
|
|
||||||
One_Fifty Int_Loc;
|
|
||||||
Enumeration Enum_Loc;
|
|
||||||
|
|
||||||
Enum_Loc = 0;
|
|
||||||
|
|
||||||
Int_Loc = *Int_Par_Ref + 10;
|
|
||||||
do /* executed once */
|
|
||||||
if (Ch_1_Glob == 'A')
|
|
||||||
/* then, executed */
|
|
||||||
{
|
|
||||||
Int_Loc -= 1;
|
|
||||||
*Int_Par_Ref = Int_Loc - Int_Glob;
|
|
||||||
Enum_Loc = Ident_1;
|
|
||||||
} /* if */
|
|
||||||
while (Enum_Loc != Ident_1); /* true */
|
|
||||||
} /* Proc_2 */
|
|
||||||
|
|
||||||
|
|
||||||
void Proc_3 (Rec_Pointer *Ptr_Ref_Par)
|
|
||||||
/* executed once */
|
|
||||||
/* Ptr_Ref_Par becomes Ptr_Glob */
|
|
||||||
{
|
|
||||||
if (Ptr_Glob != Null)
|
|
||||||
/* then, executed */
|
|
||||||
*Ptr_Ref_Par = Ptr_Glob->Ptr_Comp;
|
|
||||||
Proc_7 (10, Int_Glob, &Ptr_Glob->variant.var_1.Int_Comp);
|
|
||||||
} /* Proc_3 */
|
|
||||||
|
|
||||||
|
|
||||||
void Proc_4 (void) /* without parameters */
|
|
||||||
/* executed once */
|
|
||||||
{
|
|
||||||
Boolean Bool_Loc;
|
|
||||||
|
|
||||||
Bool_Loc = Ch_1_Glob == 'A';
|
|
||||||
Bool_Glob = Bool_Loc | Bool_Glob;
|
|
||||||
Ch_2_Glob = 'B';
|
|
||||||
} /* Proc_4 */
|
|
||||||
|
|
||||||
void Proc_5 (void) /* without parameters */
|
|
||||||
/*******/
|
|
||||||
/* executed once */
|
|
||||||
{
|
|
||||||
Ch_1_Glob = 'A';
|
|
||||||
Bool_Glob = false;
|
|
||||||
} /* Proc_5 */
|
|
||||||
|
|
||||||
|
|
||||||
/* Procedure for the assignment of structures, */
|
|
||||||
/* if the C compiler doesn't support this feature */
|
|
||||||
#ifdef NOSTRUCTASSIGN
|
|
||||||
memcpy (d, s, l)
|
|
||||||
register char *d;
|
|
||||||
register char *s;
|
|
||||||
register int l;
|
|
||||||
{
|
|
||||||
while (l--) *d++ = *s++;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
|
@ -1,209 +0,0 @@
|
||||||
/*****************************************************************************
|
|
||||||
* The BYTE UNIX Benchmarks - Release 3
|
|
||||||
* Module: dhry_2.c SID: 3.4 5/15/91 19:30:22
|
|
||||||
*
|
|
||||||
*****************************************************************************
|
|
||||||
* Bug reports, patches, comments, suggestions should be sent to:
|
|
||||||
*
|
|
||||||
* Ben Smith, Rick Grehan or Tom Yager
|
|
||||||
* ben@bytepb.byte.com rick_g@bytepb.byte.com tyager@bytepb.byte.com
|
|
||||||
*
|
|
||||||
*****************************************************************************
|
|
||||||
* Modification Log:
|
|
||||||
* 10/22/97 - code cleanup to remove ANSI C compiler warnings
|
|
||||||
* Andy Kahn <kahn@zk3.dec.com>
|
|
||||||
*
|
|
||||||
* Adapted from:
|
|
||||||
*
|
|
||||||
* "DHRYSTONE" Benchmark Program
|
|
||||||
* -----------------------------
|
|
||||||
*
|
|
||||||
* **** WARNING **** See warning in n.dhry_1.c
|
|
||||||
*
|
|
||||||
* Version: C, Version 2.1
|
|
||||||
*
|
|
||||||
* File: dhry_2.c (part 3 of 3)
|
|
||||||
*
|
|
||||||
* Date: May 25, 1988
|
|
||||||
*
|
|
||||||
* Author: Reinhold P. Weicker
|
|
||||||
*
|
|
||||||
****************************************************************************/
|
|
||||||
/* SCCSid is defined in dhry_1.c */
|
|
||||||
|
|
||||||
#include <string.h>
|
|
||||||
#include "dhry.h"
|
|
||||||
|
|
||||||
#ifndef REG
|
|
||||||
#define REG
|
|
||||||
/* REG becomes defined as empty */
|
|
||||||
/* i.e. no register variables */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
extern int Int_Glob;
|
|
||||||
extern char Ch_1_Glob;
|
|
||||||
|
|
||||||
void Proc_6(Enumeration, Enumeration *);
|
|
||||||
void Proc_7(One_Fifty, One_Fifty, One_Fifty *);
|
|
||||||
void Proc_8(Arr_1_Dim, Arr_2_Dim, int, int);
|
|
||||||
Enumeration Func_1(Capital_Letter, Capital_Letter);
|
|
||||||
Boolean Func_2(Str_30, Str_30);
|
|
||||||
Boolean Func_3(Enumeration);
|
|
||||||
|
|
||||||
void Proc_6 (Enumeration Enum_Val_Par, Enumeration *Enum_Ref_Par)
|
|
||||||
/* executed once */
|
|
||||||
/* Enum_Val_Par == Ident_3, Enum_Ref_Par becomes Ident_2 */
|
|
||||||
{
|
|
||||||
*Enum_Ref_Par = Enum_Val_Par;
|
|
||||||
if (! Func_3 (Enum_Val_Par))
|
|
||||||
/* then, not executed */
|
|
||||||
*Enum_Ref_Par = Ident_4;
|
|
||||||
switch (Enum_Val_Par)
|
|
||||||
{
|
|
||||||
case Ident_1:
|
|
||||||
*Enum_Ref_Par = Ident_1;
|
|
||||||
break;
|
|
||||||
case Ident_2:
|
|
||||||
if (Int_Glob > 100)
|
|
||||||
/* then */
|
|
||||||
*Enum_Ref_Par = Ident_1;
|
|
||||||
else *Enum_Ref_Par = Ident_4;
|
|
||||||
break;
|
|
||||||
case Ident_3: /* executed */
|
|
||||||
*Enum_Ref_Par = Ident_2;
|
|
||||||
break;
|
|
||||||
case Ident_4: break;
|
|
||||||
case Ident_5:
|
|
||||||
*Enum_Ref_Par = Ident_3;
|
|
||||||
break;
|
|
||||||
} /* switch */
|
|
||||||
} /* Proc_6 */
|
|
||||||
|
|
||||||
void Proc_7 (Int_1_Par_Val, Int_2_Par_Val, Int_Par_Ref)
|
|
||||||
One_Fifty Int_1_Par_Val;
|
|
||||||
One_Fifty Int_2_Par_Val;
|
|
||||||
One_Fifty *Int_Par_Ref;
|
|
||||||
/**********************************************/
|
|
||||||
/* executed three times */
|
|
||||||
/* first call: Int_1_Par_Val == 2, Int_2_Par_Val == 3, */
|
|
||||||
/* Int_Par_Ref becomes 7 */
|
|
||||||
/* second call: Int_1_Par_Val == 10, Int_2_Par_Val == 5, */
|
|
||||||
/* Int_Par_Ref becomes 17 */
|
|
||||||
/* third call: Int_1_Par_Val == 6, Int_2_Par_Val == 10, */
|
|
||||||
/* Int_Par_Ref becomes 18 */
|
|
||||||
{
|
|
||||||
One_Fifty Int_Loc;
|
|
||||||
|
|
||||||
Int_Loc = Int_1_Par_Val + 2;
|
|
||||||
*Int_Par_Ref = Int_2_Par_Val + Int_Loc;
|
|
||||||
} /* Proc_7 */
|
|
||||||
|
|
||||||
|
|
||||||
void Proc_8 (Arr_1_Par_Ref, Arr_2_Par_Ref, Int_1_Par_Val, Int_2_Par_Val)
|
|
||||||
/*********************************************************************/
|
|
||||||
/* executed once */
|
|
||||||
/* Int_Par_Val_1 == 3 */
|
|
||||||
/* Int_Par_Val_2 == 7 */
|
|
||||||
Arr_1_Dim Arr_1_Par_Ref;
|
|
||||||
Arr_2_Dim Arr_2_Par_Ref;
|
|
||||||
int Int_1_Par_Val;
|
|
||||||
int Int_2_Par_Val;
|
|
||||||
{
|
|
||||||
REG One_Fifty Int_Index;
|
|
||||||
REG One_Fifty Int_Loc;
|
|
||||||
|
|
||||||
Int_Loc = Int_1_Par_Val + 5;
|
|
||||||
Arr_1_Par_Ref [Int_Loc] = Int_2_Par_Val;
|
|
||||||
Arr_1_Par_Ref [Int_Loc+1] = Arr_1_Par_Ref [Int_Loc];
|
|
||||||
Arr_1_Par_Ref [Int_Loc+30] = Int_Loc;
|
|
||||||
for (Int_Index = Int_Loc; Int_Index <= Int_Loc+1; ++Int_Index)
|
|
||||||
Arr_2_Par_Ref [Int_Loc] [Int_Index] = Int_Loc;
|
|
||||||
Arr_2_Par_Ref [Int_Loc] [Int_Loc-1] += 1;
|
|
||||||
Arr_2_Par_Ref [Int_Loc+20] [Int_Loc] = Arr_1_Par_Ref [Int_Loc];
|
|
||||||
Int_Glob = 5;
|
|
||||||
} /* Proc_8 */
|
|
||||||
|
|
||||||
|
|
||||||
Enumeration Func_1 (Capital_Letter Ch_1_Par_Val, Capital_Letter Ch_2_Par_Val)
|
|
||||||
/*************************************************/
|
|
||||||
/* executed three times */
|
|
||||||
/* first call: Ch_1_Par_Val == 'H', Ch_2_Par_Val == 'R' */
|
|
||||||
/* second call: Ch_1_Par_Val == 'A', Ch_2_Par_Val == 'C' */
|
|
||||||
/* third call: Ch_1_Par_Val == 'B', Ch_2_Par_Val == 'C' */
|
|
||||||
{
|
|
||||||
Capital_Letter Ch_1_Loc;
|
|
||||||
Capital_Letter Ch_2_Loc;
|
|
||||||
|
|
||||||
Ch_1_Loc = Ch_1_Par_Val;
|
|
||||||
Ch_2_Loc = Ch_1_Loc;
|
|
||||||
if (Ch_2_Loc != Ch_2_Par_Val)
|
|
||||||
/* then, executed */
|
|
||||||
return (Ident_1);
|
|
||||||
else /* not executed */
|
|
||||||
{
|
|
||||||
Ch_1_Glob = Ch_1_Loc;
|
|
||||||
return (Ident_2);
|
|
||||||
}
|
|
||||||
} /* Func_1 */
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Boolean Func_2 (Str_1_Par_Ref, Str_2_Par_Ref)
|
|
||||||
/*************************************************/
|
|
||||||
/* executed once */
|
|
||||||
/* Str_1_Par_Ref == "DHRYSTONE PROGRAM, 1'ST STRING" */
|
|
||||||
/* Str_2_Par_Ref == "DHRYSTONE PROGRAM, 2'ND STRING" */
|
|
||||||
|
|
||||||
Str_30 Str_1_Par_Ref;
|
|
||||||
Str_30 Str_2_Par_Ref;
|
|
||||||
{
|
|
||||||
REG One_Thirty Int_Loc;
|
|
||||||
Capital_Letter Ch_Loc;
|
|
||||||
|
|
||||||
Ch_Loc = 'A';
|
|
||||||
Int_Loc = 2;
|
|
||||||
while (Int_Loc <= 2) /* loop body executed once */
|
|
||||||
if (Func_1 (Str_1_Par_Ref[Int_Loc],
|
|
||||||
Str_2_Par_Ref[Int_Loc+1]) == Ident_1)
|
|
||||||
/* then, executed */
|
|
||||||
{
|
|
||||||
Ch_Loc = 'A';
|
|
||||||
Int_Loc += 1;
|
|
||||||
} /* if, while */
|
|
||||||
if (Ch_Loc >= 'W' && Ch_Loc < 'Z')
|
|
||||||
/* then, not executed */
|
|
||||||
Int_Loc = 7;
|
|
||||||
if (Ch_Loc == 'R')
|
|
||||||
/* then, not executed */
|
|
||||||
return (true);
|
|
||||||
else /* executed */
|
|
||||||
{
|
|
||||||
if (strcmp (Str_1_Par_Ref, Str_2_Par_Ref) > 0)
|
|
||||||
/* then, not executed */
|
|
||||||
{
|
|
||||||
Int_Loc += 7;
|
|
||||||
Int_Glob = Int_Loc;
|
|
||||||
return (true);
|
|
||||||
}
|
|
||||||
else /* executed */
|
|
||||||
return (false);
|
|
||||||
} /* if Ch_Loc */
|
|
||||||
} /* Func_2 */
|
|
||||||
|
|
||||||
|
|
||||||
Boolean Func_3 (Enum_Par_Val)
|
|
||||||
/***************************/
|
|
||||||
/* executed once */
|
|
||||||
/* Enum_Par_Val == Ident_3 */
|
|
||||||
Enumeration Enum_Par_Val;
|
|
||||||
{
|
|
||||||
Enumeration Enum_Loc;
|
|
||||||
|
|
||||||
Enum_Loc = Enum_Par_Val;
|
|
||||||
if (Enum_Loc == Ident_3)
|
|
||||||
/* then, executed */
|
|
||||||
return (true);
|
|
||||||
else /* not executed */
|
|
||||||
return (false);
|
|
||||||
} /* Func_3 */
|
|
||||||
|
|
|
@ -1,319 +0,0 @@
|
||||||
/*******************************************************************************
|
|
||||||
* The BYTE UNIX Benchmarks - Release 3
|
|
||||||
* Module: dummy.c SID: 3.3 5/15/91 19:30:19
|
|
||||||
*
|
|
||||||
*******************************************************************************
|
|
||||||
* Bug reports, patches, comments, suggestions should be sent to:
|
|
||||||
*
|
|
||||||
* Ben Smith, Rick Grehan or Tom Yager
|
|
||||||
* ben@bytepb.byte.com rick_g@bytepb.byte.com tyager@bytepb.byte.com
|
|
||||||
*
|
|
||||||
*******************************************************************************
|
|
||||||
* Modification Log:
|
|
||||||
* 10/22/97 - code cleanup to remove ANSI C compiler warnings
|
|
||||||
* Andy Kahn <kahn@zk3.dec.com>
|
|
||||||
*
|
|
||||||
******************************************************************************/
|
|
||||||
/*
|
|
||||||
* Hacked up C program for use in the standard shell.? scripts of
|
|
||||||
* the multiuser test. This is based upon makework.c, and is typically
|
|
||||||
* edited using edscript.2 before compilation.
|
|
||||||
*
|
|
||||||
* $Header: dummy.c,v 3.4 87/06/23 15:54:53 kjmcdonell Beta $
|
|
||||||
*/
|
|
||||||
char SCCSid[] = "@(#) @(#)dummy.c:3.3 -- 5/15/91 19:30:19";
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <signal.h>
|
|
||||||
|
|
||||||
#define DEF_RATE 5.0
|
|
||||||
#define GRANULE 5
|
|
||||||
#define CHUNK 60
|
|
||||||
#define MAXCHILD 12
|
|
||||||
#define MAXWORK 10
|
|
||||||
|
|
||||||
float thres;
|
|
||||||
float est_rate = DEF_RATE;
|
|
||||||
int nusers; /* number of concurrent users to be simulated by
|
|
||||||
* this process */
|
|
||||||
int firstuser; /* ordinal identification of first user for this
|
|
||||||
* process */
|
|
||||||
int nwork = 0; /* number of job streams */
|
|
||||||
int exit_status = 0; /* returned to parent */
|
|
||||||
int sigpipe; /* pipe write error flag */
|
|
||||||
|
|
||||||
struct st_work {
|
|
||||||
char *cmd; /* name of command to run */
|
|
||||||
char **av; /* arguments to command */
|
|
||||||
char *input; /* standard input buffer */
|
|
||||||
int inpsize; /* size of standard input buffer */
|
|
||||||
} work[MAXWORK];
|
|
||||||
|
|
||||||
struct {
|
|
||||||
int xmit; /* # characters sent */
|
|
||||||
char *bp; /* std input buffer pointer */
|
|
||||||
int blen; /* std input buffer length */
|
|
||||||
int fd; /* stdin to command */
|
|
||||||
int pid; /* child PID */
|
|
||||||
char *line; /* start of input line */
|
|
||||||
int firstjob; /* inital piece of work */
|
|
||||||
int thisjob; /* current piece of work */
|
|
||||||
} child[MAXCHILD], *cp;
|
|
||||||
|
|
||||||
main(argc, argv)
|
|
||||||
int argc;
|
|
||||||
char *argv[];
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
int l;
|
|
||||||
int fcopy = 0; /* fd for copy output */
|
|
||||||
int master = 1; /* the REAL master, == 0 for clones */
|
|
||||||
int nchild; /* no. of children for a clone to run */
|
|
||||||
int done; /* count of children finished */
|
|
||||||
int output; /* aggregate output char count for all
|
|
||||||
children */
|
|
||||||
int c;
|
|
||||||
int thiswork = 0; /* next job stream to allocate */
|
|
||||||
int nch; /* # characters to write */
|
|
||||||
int written; /* # characters actully written */
|
|
||||||
char logname[15]; /* name of the log file(s) */
|
|
||||||
void onalarm(void);
|
|
||||||
void pipeerr(void);
|
|
||||||
void wrapup(void);
|
|
||||||
void grunt(void);
|
|
||||||
char *malloc();
|
|
||||||
int pvec[2]; /* for pipes */
|
|
||||||
char *p;
|
|
||||||
char *prog; /* my name */
|
|
||||||
|
|
||||||
#if ! debug
|
|
||||||
freopen("masterlog.00", "a", stderr);
|
|
||||||
#endif
|
|
||||||
fprintf(stderr, "*** New Run *** ");
|
|
||||||
prog = argv[0];
|
|
||||||
while (argc > 1 && argv[1][0] == '-') {
|
|
||||||
p = &argv[1][1];
|
|
||||||
argc--;
|
|
||||||
argv++;
|
|
||||||
while (*p) {
|
|
||||||
switch (*p) {
|
|
||||||
case 'r':
|
|
||||||
/* code DELETED here */
|
|
||||||
argc--;
|
|
||||||
argv++;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'c':
|
|
||||||
/* code DELETED here */
|
|
||||||
lseek(fcopy, 0L, 2); /* append at end of file */
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
fprintf(stderr, "%s: bad flag '%c'\n", prog, *p);
|
|
||||||
exit(4);
|
|
||||||
}
|
|
||||||
p++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (argc < 2) {
|
|
||||||
fprintf(stderr, "%s: missing nusers\n", prog);
|
|
||||||
exit(4);
|
|
||||||
}
|
|
||||||
|
|
||||||
nusers = atoi(argv[1]);
|
|
||||||
if (nusers < 1) {
|
|
||||||
fprintf(stderr, "%s: impossible nusers (%d<-%s)\n", prog, nusers, argv[1]);
|
|
||||||
exit(4);
|
|
||||||
}
|
|
||||||
fprintf(stderr, "%d Users\n", nusers);
|
|
||||||
argc--;
|
|
||||||
argv++;
|
|
||||||
|
|
||||||
/* build job streams */
|
|
||||||
getwork();
|
|
||||||
#if debug
|
|
||||||
dumpwork();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* clone copies of myself to run up to MAXCHILD jobs each */
|
|
||||||
firstuser = MAXCHILD;
|
|
||||||
fprintf(stderr, "master pid %d\n", getpid());
|
|
||||||
fflush(stderr);
|
|
||||||
while (nusers > MAXCHILD) {
|
|
||||||
fflush(stderr);
|
|
||||||
if (nusers >= 2*MAXCHILD)
|
|
||||||
/* the next clone must run MAXCHILD jobs */
|
|
||||||
nchild = MAXCHILD;
|
|
||||||
else
|
|
||||||
/* the next clone must run the leftover jobs */
|
|
||||||
nchild = nusers - MAXCHILD;
|
|
||||||
if ((l = fork()) == -1) {
|
|
||||||
/* fork failed */
|
|
||||||
fatal("** clone fork failed **\n");
|
|
||||||
goto bepatient;
|
|
||||||
} else if (l > 0) {
|
|
||||||
fprintf(stderr, "master clone pid %d\n", l);
|
|
||||||
/* I am the master with nchild fewer jobs to run */
|
|
||||||
nusers -= nchild;
|
|
||||||
firstuser += MAXCHILD;
|
|
||||||
continue;
|
|
||||||
} else {
|
|
||||||
/* I am a clone, run MAXCHILD jobs */
|
|
||||||
#if ! debug
|
|
||||||
sprintf(logname, "masterlog.%02d", firstuser/MAXCHILD);
|
|
||||||
freopen(logname, "w", stderr);
|
|
||||||
#endif
|
|
||||||
master = 0;
|
|
||||||
nusers = nchild;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (master)
|
|
||||||
firstuser = 0;
|
|
||||||
|
|
||||||
close(0);
|
|
||||||
|
|
||||||
/* code DELETED here */
|
|
||||||
|
|
||||||
fflush(stderr);
|
|
||||||
|
|
||||||
srand(time(0));
|
|
||||||
thres = 0;
|
|
||||||
done = output = 0;
|
|
||||||
for (i = 0; i < nusers; i++) {
|
|
||||||
if (child[i].blen == 0)
|
|
||||||
done++;
|
|
||||||
else
|
|
||||||
thres += est_rate * GRANULE;
|
|
||||||
}
|
|
||||||
est_rate = thres;
|
|
||||||
|
|
||||||
signal(SIGALRM, onalarm);
|
|
||||||
signal(SIGPIPE, pipeerr);
|
|
||||||
alarm(GRANULE);
|
|
||||||
while (done < nusers) {
|
|
||||||
for (i = 0; i < nusers; i++) {
|
|
||||||
cp = &child[i];
|
|
||||||
if (cp->xmit >= cp->blen) continue;
|
|
||||||
l = rand() % CHUNK + 1; /* 1-CHUNK chars */
|
|
||||||
if (l == 0) continue;
|
|
||||||
if (cp->xmit + l > cp->blen)
|
|
||||||
l = cp->blen - cp->xmit;
|
|
||||||
p = cp->bp;
|
|
||||||
cp->bp += l;
|
|
||||||
cp->xmit += l;
|
|
||||||
#if debug
|
|
||||||
fprintf(stderr, "child %d, %d processed, %d to go\n", i, cp->xmit, cp->blen - cp->xmit);
|
|
||||||
#endif
|
|
||||||
while (p < cp->bp) {
|
|
||||||
if (*p == '\n' || (p == &cp->bp[-1] && cp->xmit >= cp->blen)) {
|
|
||||||
/* write it out */
|
|
||||||
nch = p - cp->line + 1;
|
|
||||||
if ((written = write(cp->fd, cp->line, nch)) != nch) {
|
|
||||||
|
|
||||||
/* code DELETED here */
|
|
||||||
|
|
||||||
}
|
|
||||||
if (fcopy)
|
|
||||||
write(fcopy, cp->line, p - cp->line + 1);
|
|
||||||
#if debug
|
|
||||||
fprintf(stderr, "child %d gets \"", i);
|
|
||||||
{
|
|
||||||
char *q = cp->line;
|
|
||||||
while (q <= p) {
|
|
||||||
if (*q >= ' ' && *q <= '~')
|
|
||||||
fputc(*q, stderr);
|
|
||||||
else
|
|
||||||
fprintf(stderr, "\\%03o", *q);
|
|
||||||
q++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fputc('"', stderr);
|
|
||||||
#endif
|
|
||||||
cp->line = &p[1];
|
|
||||||
}
|
|
||||||
p++;
|
|
||||||
}
|
|
||||||
if (cp->xmit >= cp->blen) {
|
|
||||||
done++;
|
|
||||||
close(cp->fd);
|
|
||||||
#if debug
|
|
||||||
fprintf(stderr, "child %d, close std input\n", i);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
output += l;
|
|
||||||
}
|
|
||||||
while (output > thres) {
|
|
||||||
pause();
|
|
||||||
#if debug
|
|
||||||
fprintf(stderr, "after pause: output, thres, done %d %.2f %d\n", output, thres, done);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bepatient:
|
|
||||||
alarm(0);
|
|
||||||
/****
|
|
||||||
* If everything is going OK, we should simply be able to keep
|
|
||||||
* looping unitil 'wait' fails, however some descendent process may
|
|
||||||
* be in a state from which it can never exit, and so a timeout
|
|
||||||
* is used.
|
|
||||||
* 5 minutes should be ample, since the time to run all jobs is of
|
|
||||||
* the order of 5-10 minutes, however some machines are painfully slow,
|
|
||||||
* so the timeout has been set at 20 minutes (1200 seconds).
|
|
||||||
****/
|
|
||||||
|
|
||||||
/* code DELETED here */
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
onalarm()
|
|
||||||
{
|
|
||||||
thres += est_rate;
|
|
||||||
signal(SIGALRM, onalarm);
|
|
||||||
alarm(GRANULE);
|
|
||||||
}
|
|
||||||
|
|
||||||
grunt()
|
|
||||||
{
|
|
||||||
/* timeout after label "bepatient" in main */
|
|
||||||
exit_status = 4;
|
|
||||||
wrapup();
|
|
||||||
}
|
|
||||||
|
|
||||||
pipeerr()
|
|
||||||
{
|
|
||||||
sigpipe++;
|
|
||||||
}
|
|
||||||
|
|
||||||
wrapup()
|
|
||||||
{
|
|
||||||
/* DUMMY, real code dropped */
|
|
||||||
}
|
|
||||||
|
|
||||||
getwork()
|
|
||||||
{
|
|
||||||
|
|
||||||
/* DUMMY, real code dropped */
|
|
||||||
gets();
|
|
||||||
strncpy();
|
|
||||||
malloc(); realloc();
|
|
||||||
open(); close();
|
|
||||||
}
|
|
||||||
|
|
||||||
fatal(s)
|
|
||||||
char *s;
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
fprintf(stderr, s);
|
|
||||||
fflush(stderr);
|
|
||||||
perror("Reason?");
|
|
||||||
for (i = 0; i < nusers; i++) {
|
|
||||||
if (child[i].pid > 0 && kill(child[i].pid, SIGKILL) != -1)
|
|
||||||
fprintf(stderr, "pid %d killed off\n", child[i].pid);
|
|
||||||
}
|
|
||||||
fflush(stderr);
|
|
||||||
exit_status = 4;
|
|
||||||
return;
|
|
||||||
}
|
|
|
@ -1,91 +0,0 @@
|
||||||
/*******************************************************************************
|
|
||||||
* The BYTE UNIX Benchmarks - Release 3
|
|
||||||
* Module: execl.c SID: 3.3 5/15/91 19:30:19
|
|
||||||
*
|
|
||||||
*******************************************************************************
|
|
||||||
* Bug reports, patches, comments, suggestions should be sent to:
|
|
||||||
*
|
|
||||||
* Ben Smith, Rick Grehan or Tom Yager
|
|
||||||
* ben@bytepb.byte.com rick_g@bytepb.byte.com tyager@bytepb.byte.com
|
|
||||||
*
|
|
||||||
*******************************************************************************
|
|
||||||
* Modification Log:
|
|
||||||
* $Header: execl.c,v 3.5 87/06/22 15:37:08 kjmcdonell Beta $
|
|
||||||
* August 28, 1990 - Modified timing routines
|
|
||||||
* October 22, 1997 - code cleanup to remove ANSI C compiler warnings
|
|
||||||
* Andy Kahn <kahn@zk3.dec.com>
|
|
||||||
*
|
|
||||||
******************************************************************************/
|
|
||||||
/*
|
|
||||||
* Execing
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
char SCCSid[] = "@(#) @(#)execl.c:3.3 -- 5/15/91 19:30:19";
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
|
|
||||||
char bss[8*1024]; /* something worthwhile */
|
|
||||||
|
|
||||||
#define main dummy
|
|
||||||
|
|
||||||
#include "big.c" /* some real code */
|
|
||||||
|
|
||||||
#undef main
|
|
||||||
|
|
||||||
int main(int argc, char *argv[]) /* the real program */
|
|
||||||
{
|
|
||||||
unsigned long iter = 0;
|
|
||||||
char *ptr;
|
|
||||||
char *fullpath;
|
|
||||||
int duration;
|
|
||||||
char count_str[12], start_str[24], path_str[256], *dur_str;
|
|
||||||
time_t start_time, this_time;
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
|
||||||
int count;
|
|
||||||
for(count = 0; count < argc; ++ count)
|
|
||||||
printf("%s ",argv[count]);
|
|
||||||
printf("\n");
|
|
||||||
#endif
|
|
||||||
if (argc < 2)
|
|
||||||
{
|
|
||||||
fprintf(stderr, "Usage: %s duration\n", argv[0]);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
duration = atoi(argv[1]);
|
|
||||||
if (duration > 0)
|
|
||||||
/* the first invocation */
|
|
||||||
{
|
|
||||||
dur_str = argv[1];
|
|
||||||
if((ptr = getenv("UB_BINDIR")) != NULL)
|
|
||||||
sprintf(path_str,"%s/execl",ptr);
|
|
||||||
fullpath=path_str;
|
|
||||||
time(&start_time);
|
|
||||||
}
|
|
||||||
else /* one of those execl'd invocations */
|
|
||||||
{
|
|
||||||
/* real duration follow the phoney null duration */
|
|
||||||
duration = atoi(argv[2]);
|
|
||||||
dur_str = argv[2];
|
|
||||||
iter = (unsigned long)atoi(argv[3]); /* where are we now ? */
|
|
||||||
sscanf(argv[4], "%lu", (unsigned long *) &start_time);
|
|
||||||
fullpath = argv[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
sprintf(count_str, "%lu", ++iter); /* increment the execl counter */
|
|
||||||
sprintf(start_str, "%lu", (unsigned long) start_time);
|
|
||||||
time(&this_time);
|
|
||||||
if (this_time - start_time >= duration) { /* time has run out */
|
|
||||||
fprintf(stderr, "COUNT|%lu|1|lps\n", iter);
|
|
||||||
exit(0);
|
|
||||||
}
|
|
||||||
execl(fullpath, fullpath, "0", dur_str, count_str, start_str, (void *) 0);
|
|
||||||
fprintf(stderr, "Exec failed at iteration %lu\n", iter);
|
|
||||||
perror("Reason");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
|
@ -1,469 +0,0 @@
|
||||||
/*******************************************************************************
|
|
||||||
* The BYTE UNIX Benchmarks - Release 3
|
|
||||||
* Module: fstime.c SID: 3.5 5/15/91 19:30:19
|
|
||||||
*
|
|
||||||
*******************************************************************************
|
|
||||||
* Bug reports, patches, comments, suggestions should be sent to:
|
|
||||||
*
|
|
||||||
* Ben Smith, Rick Grehan or Tom Yager
|
|
||||||
* ben@bytepb.byte.com rick_g@bytepb.byte.com tyager@bytepb.byte.com
|
|
||||||
*
|
|
||||||
*******************************************************************************
|
|
||||||
* Modification Log:
|
|
||||||
* $Header: fstime.c,v 3.4 87/06/22 14:23:05 kjmcdonell Beta $
|
|
||||||
* 10/19/89 - rewrote timing calcs and added clock check (Ben Smith)
|
|
||||||
* 10/26/90 - simplify timing, change defaults (Tom Yager)
|
|
||||||
* 11/16/90 - added better error handling and changed output format (Ben Smith)
|
|
||||||
* 11/17/90 - changed the whole thing around (Ben Smith)
|
|
||||||
* 2/22/91 - change a few style elements and improved error handling (Ben Smith)
|
|
||||||
* 4/17/91 - incorporated suggestions from Seckin Unlu (seckin@sumac.intel.com)
|
|
||||||
* 4/17/91 - limited size of file, will rewind when reaches end of file
|
|
||||||
* 7/95 - fixed mishandling of read() and write() return codes
|
|
||||||
* Carl Emilio Prelz <fluido@telepac.pt>
|
|
||||||
* 12/95 - Massive changes. Made sleep time proportional increase with run
|
|
||||||
* time; added fsbuffer and fsdisk variants; added partial counting
|
|
||||||
* of partial reads/writes (was *full* credit); added dual syncs.
|
|
||||||
* David C Niemi <niemi@tux.org>
|
|
||||||
* 10/22/97 - code cleanup to remove ANSI C compiler warnings
|
|
||||||
* Andy Kahn <kahn@zk3.dec.com>
|
|
||||||
* 9/24/07 - Separate out the read and write tests;
|
|
||||||
* output the actual time used in the results.
|
|
||||||
* Ian Smith <johantheghost at yahoo period com>
|
|
||||||
******************************************************************************/
|
|
||||||
char SCCSid[] = "@(#) @(#)fstime.c:3.5 -- 5/15/91 19:30:19";
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <signal.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <sys/time.h>
|
|
||||||
|
|
||||||
#define SECONDS 10
|
|
||||||
|
|
||||||
#define MAX_BUFSIZE 8192
|
|
||||||
|
|
||||||
/* This must be set to the smallest BUFSIZE or 1024, whichever is smaller */
|
|
||||||
#define COUNTSIZE 256
|
|
||||||
#define HALFCOUNT (COUNTSIZE/2) /* Half of COUNTSIZE */
|
|
||||||
|
|
||||||
#define FNAME0 "dummy0"
|
|
||||||
#define FNAME1 "dummy1"
|
|
||||||
|
|
||||||
#ifndef MINIX
|
|
||||||
extern void sync(void);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
int w_test(int timeSecs);
|
|
||||||
int r_test(int timeSecs);
|
|
||||||
int c_test(int timeSecs);
|
|
||||||
|
|
||||||
long read_score = 1, write_score = 1, copy_score = 1;
|
|
||||||
|
|
||||||
/****************** GLOBALS ***************************/
|
|
||||||
|
|
||||||
/* The buffer size for the tests. */
|
|
||||||
int bufsize = 1024;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The max number of 1024-byte blocks in the file.
|
|
||||||
* Don't limit it much, so that memory buffering
|
|
||||||
* can be overcome.
|
|
||||||
*/
|
|
||||||
int max_blocks = 2000;
|
|
||||||
|
|
||||||
/* The max number of BUFSIZE blocks in the file. */
|
|
||||||
int max_buffs = 2000;
|
|
||||||
|
|
||||||
/* Countable units per 1024 bytes */
|
|
||||||
int count_per_k;
|
|
||||||
|
|
||||||
/* Countable units per bufsize */
|
|
||||||
int count_per_buf;
|
|
||||||
|
|
||||||
/* The actual buffer. */
|
|
||||||
/* char *buf = 0; */
|
|
||||||
/* Let's carry on using a static buffer for this, like older versions
|
|
||||||
* of the code did. It turns out that if you use a malloc buffer,
|
|
||||||
* it goes 50% slower on reads, when using a 4k buffer -- at least on
|
|
||||||
* my OpenSUSE 10.2 system.
|
|
||||||
* What up wit dat?
|
|
||||||
*/
|
|
||||||
char buf[MAX_BUFSIZE];
|
|
||||||
|
|
||||||
int f;
|
|
||||||
int g;
|
|
||||||
int i;
|
|
||||||
void stop_count(int);
|
|
||||||
void clean_up(int);
|
|
||||||
int sigalarm = 0;
|
|
||||||
|
|
||||||
/******************** MAIN ****************************/
|
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
|
||||||
{
|
|
||||||
/* The number of seconds to run for. */
|
|
||||||
int seconds = SECONDS;
|
|
||||||
|
|
||||||
/* The type of test to run. */
|
|
||||||
char test = 'c';
|
|
||||||
|
|
||||||
int status;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 1; i < argc; ++i) {
|
|
||||||
if (argv[i][0] == '-') {
|
|
||||||
switch (argv[i][1]) {
|
|
||||||
case 'c':
|
|
||||||
case 'r':
|
|
||||||
case 'w':
|
|
||||||
test = argv[i][1];
|
|
||||||
break;
|
|
||||||
case 'b':
|
|
||||||
bufsize = atoi(argv[++i]);
|
|
||||||
break;
|
|
||||||
case 'm':
|
|
||||||
max_blocks = atoi(argv[++i]);
|
|
||||||
break;
|
|
||||||
case 't':
|
|
||||||
seconds = atoi(argv[++i]);
|
|
||||||
break;
|
|
||||||
case 'd':
|
|
||||||
if (chdir(argv[++i]) < 0) {
|
|
||||||
perror("fstime: chdir");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
fprintf(stderr, "Usage: fstime [-c|-r|-w] [-b <bufsize>] [-m <max_blocks>] [-t <seconds>]\n");
|
|
||||||
exit(2);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
fprintf(stderr, "Usage: fstime [-c|-r|-w] [-b <bufsize>] [-m <max_blocks>] [-t <seconds>]\n");
|
|
||||||
exit(2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (bufsize < COUNTSIZE || bufsize > MAX_BUFSIZE) {
|
|
||||||
fprintf(stderr, "fstime: buffer size must be in range %d-%d\n",
|
|
||||||
COUNTSIZE, 1024*1024);
|
|
||||||
exit(3);
|
|
||||||
}
|
|
||||||
if (max_blocks < 1 || max_blocks > 1024*1024) {
|
|
||||||
fprintf(stderr, "fstime: max blocks must be in range %d-%d\n",
|
|
||||||
1, 1024*1024);
|
|
||||||
exit(3);
|
|
||||||
}
|
|
||||||
if (seconds < 1 || seconds > 3600) {
|
|
||||||
fprintf(stderr, "fstime: time must be in range %d-%d seconds\n",
|
|
||||||
1, 3600);
|
|
||||||
exit(3);
|
|
||||||
}
|
|
||||||
|
|
||||||
max_buffs = max_blocks * 1024 / bufsize;
|
|
||||||
count_per_k = 1024 / COUNTSIZE;
|
|
||||||
count_per_buf = bufsize / COUNTSIZE;
|
|
||||||
|
|
||||||
/*
|
|
||||||
if ((buf = malloc(bufsize)) == 0) {
|
|
||||||
fprintf(stderr, "fstime: failed to malloc %d bytes\n", bufsize);
|
|
||||||
exit(4);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
if((f = creat(FNAME0, 0600)) == -1) {
|
|
||||||
perror("fstime: creat");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
close(f);
|
|
||||||
|
|
||||||
if((g = creat(FNAME1, 0600)) == -1) {
|
|
||||||
perror("fstime: creat");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
close(g);
|
|
||||||
|
|
||||||
if( (f = open(FNAME0, 2)) == -1) {
|
|
||||||
perror("fstime: open");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
if( ( g = open(FNAME1, 2)) == -1 ) {
|
|
||||||
perror("fstime: open");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* fill buffer */
|
|
||||||
for (i=0; i < bufsize; ++i)
|
|
||||||
buf[i] = i & 0xff;
|
|
||||||
|
|
||||||
signal(SIGKILL,clean_up);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Run the selected test.
|
|
||||||
* When I got here, this program ran full 30-second tests for
|
|
||||||
* write, read, and copy, outputting the results for each. BUT
|
|
||||||
* only the copy results are actually used in the benchmark index.
|
|
||||||
* With multiple iterations and three sets of FS tests, that amounted
|
|
||||||
* to about 10 minutes of wasted time per run.
|
|
||||||
*
|
|
||||||
* So, I've made the test selectable. Except that the read and write
|
|
||||||
* passes are used to create the test file and calibrate the rates used
|
|
||||||
* to tweak the results of the copy test. So, for copy tests, we do
|
|
||||||
* a few seconds of write and read to prime the pump.
|
|
||||||
*
|
|
||||||
* Note that this will also pull the file into the FS cache on any
|
|
||||||
* modern system prior to the copy test. Whether this is good or
|
|
||||||
* bad is a matter of perspective, but it's how it was when I got
|
|
||||||
* here.
|
|
||||||
*
|
|
||||||
* Ian Smith <johantheghost at yahoo period com> 21 Sep 2007
|
|
||||||
*/
|
|
||||||
switch (test) {
|
|
||||||
case 'w':
|
|
||||||
status = w_test(seconds);
|
|
||||||
break;
|
|
||||||
case 'r':
|
|
||||||
w_test(2);
|
|
||||||
status = r_test(seconds);
|
|
||||||
break;
|
|
||||||
case 'c':
|
|
||||||
w_test(2);
|
|
||||||
r_test(2);
|
|
||||||
status = c_test(seconds);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
fprintf(stderr, "fstime: unknown test \'%c\'\n", test);
|
|
||||||
exit(6);
|
|
||||||
}
|
|
||||||
if (status) {
|
|
||||||
clean_up(0);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
clean_up(0);
|
|
||||||
exit(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static double getFloatTime(void)
|
|
||||||
{
|
|
||||||
struct timeval t;
|
|
||||||
|
|
||||||
gettimeofday(&t, 0);
|
|
||||||
return (double) t.tv_sec + (double) t.tv_usec / 1000000.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Run the write test for the time given in seconds.
|
|
||||||
*/
|
|
||||||
int w_test(int timeSecs)
|
|
||||||
{
|
|
||||||
unsigned long counted = 0L;
|
|
||||||
unsigned long tmp;
|
|
||||||
long f_blocks;
|
|
||||||
double start, end;
|
|
||||||
extern int sigalarm;
|
|
||||||
|
|
||||||
/* Sync and let it settle */
|
|
||||||
sync();
|
|
||||||
sleep(2);
|
|
||||||
sync();
|
|
||||||
sleep(2);
|
|
||||||
|
|
||||||
/* Set an alarm. */
|
|
||||||
sigalarm = 0;
|
|
||||||
signal(SIGALRM, stop_count);
|
|
||||||
alarm(timeSecs);
|
|
||||||
|
|
||||||
start = getFloatTime();
|
|
||||||
|
|
||||||
while (!sigalarm) {
|
|
||||||
for(f_blocks=0; f_blocks < max_buffs; ++f_blocks) {
|
|
||||||
if ((tmp=write(f, buf, bufsize)) != bufsize) {
|
|
||||||
if (errno != EINTR) {
|
|
||||||
perror("fstime: write");
|
|
||||||
return(-1);
|
|
||||||
}
|
|
||||||
stop_count(0);
|
|
||||||
counted += ((tmp+HALFCOUNT)/COUNTSIZE);
|
|
||||||
} else
|
|
||||||
counted += count_per_buf;
|
|
||||||
}
|
|
||||||
lseek(f, 0L, 0); /* rewind */
|
|
||||||
}
|
|
||||||
|
|
||||||
/* stop clock */
|
|
||||||
end = getFloatTime();
|
|
||||||
write_score = (long) ((double) counted / ((end - start) * count_per_k));
|
|
||||||
printf("Write done: %ld in %.4f, score %ld\n",
|
|
||||||
counted, end - start, write_score);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Output the test results. Use the true time.
|
|
||||||
*/
|
|
||||||
fprintf(stderr, "COUNT|%ld|0|KBps\n", write_score);
|
|
||||||
fprintf(stderr, "TIME|%.1f\n", end - start);
|
|
||||||
|
|
||||||
return(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Run the read test for the time given in seconds.
|
|
||||||
*/
|
|
||||||
int r_test(int timeSecs)
|
|
||||||
{
|
|
||||||
unsigned long counted = 0L;
|
|
||||||
unsigned long tmp;
|
|
||||||
double start, end;
|
|
||||||
extern int sigalarm;
|
|
||||||
extern int errno;
|
|
||||||
|
|
||||||
/* Sync and let it settle */
|
|
||||||
sync();
|
|
||||||
sleep(2);
|
|
||||||
sync();
|
|
||||||
sleep(2);
|
|
||||||
|
|
||||||
/* rewind */
|
|
||||||
errno = 0;
|
|
||||||
lseek(f, 0L, 0);
|
|
||||||
|
|
||||||
/* Set an alarm. */
|
|
||||||
sigalarm = 0;
|
|
||||||
signal(SIGALRM, stop_count);
|
|
||||||
alarm(timeSecs);
|
|
||||||
|
|
||||||
start = getFloatTime();
|
|
||||||
|
|
||||||
while (!sigalarm) {
|
|
||||||
/* read while checking for an error */
|
|
||||||
if ((tmp=read(f, buf, bufsize)) != bufsize) {
|
|
||||||
switch(errno) {
|
|
||||||
case 0:
|
|
||||||
case EINVAL:
|
|
||||||
lseek(f, 0L, 0); /* rewind at end of file */
|
|
||||||
counted += (tmp+HALFCOUNT)/COUNTSIZE;
|
|
||||||
continue;
|
|
||||||
case EINTR:
|
|
||||||
stop_count(0);
|
|
||||||
counted += (tmp+HALFCOUNT)/COUNTSIZE;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
perror("fstime: read");
|
|
||||||
return(-1);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else
|
|
||||||
counted += count_per_buf;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* stop clock */
|
|
||||||
end = getFloatTime();
|
|
||||||
read_score = (long) ((double) counted / ((end - start) * count_per_k));
|
|
||||||
printf("Read done: %ld in %.4f, score %ld\n",
|
|
||||||
counted, end - start, read_score);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Output the test results. Use the true time.
|
|
||||||
*/
|
|
||||||
fprintf(stderr, "COUNT|%ld|0|KBps\n", read_score);
|
|
||||||
fprintf(stderr, "TIME|%.1f\n", end - start);
|
|
||||||
|
|
||||||
return(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Run the copy test for the time given in seconds.
|
|
||||||
*/
|
|
||||||
int c_test(int timeSecs)
|
|
||||||
{
|
|
||||||
unsigned long counted = 0L;
|
|
||||||
unsigned long tmp;
|
|
||||||
double start, end;
|
|
||||||
extern int sigalarm;
|
|
||||||
|
|
||||||
sync();
|
|
||||||
sleep(2);
|
|
||||||
sync();
|
|
||||||
sleep(1);
|
|
||||||
|
|
||||||
/* rewind */
|
|
||||||
errno = 0;
|
|
||||||
lseek(f, 0L, 0);
|
|
||||||
|
|
||||||
/* Set an alarm. */
|
|
||||||
sigalarm = 0;
|
|
||||||
signal(SIGALRM, stop_count);
|
|
||||||
alarm(timeSecs);
|
|
||||||
|
|
||||||
start = getFloatTime();
|
|
||||||
|
|
||||||
while (!sigalarm) {
|
|
||||||
if ((tmp=read(f, buf, bufsize)) != bufsize) {
|
|
||||||
switch(errno) {
|
|
||||||
case 0:
|
|
||||||
case EINVAL:
|
|
||||||
lseek(f, 0L, 0); /* rewind at end of file */
|
|
||||||
lseek(g, 0L, 0); /* rewind the output too */
|
|
||||||
continue;
|
|
||||||
case EINTR:
|
|
||||||
/* part credit for leftover bytes read */
|
|
||||||
counted += ( (tmp * write_score) /
|
|
||||||
(read_score + write_score)
|
|
||||||
+ HALFCOUNT) / COUNTSIZE;
|
|
||||||
stop_count(0);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
perror("fstime: copy read");
|
|
||||||
return(-1);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if ((tmp=write(g, buf, bufsize)) != bufsize) {
|
|
||||||
if (errno != EINTR) {
|
|
||||||
perror("fstime: copy write");
|
|
||||||
return(-1);
|
|
||||||
}
|
|
||||||
counted += (
|
|
||||||
/* Full credit for part of buffer written */
|
|
||||||
tmp +
|
|
||||||
|
|
||||||
/* Plus part credit having read full buffer */
|
|
||||||
( ((bufsize - tmp) * write_score) /
|
|
||||||
(read_score + write_score) )
|
|
||||||
+ HALFCOUNT) / COUNTSIZE;
|
|
||||||
stop_count(0);
|
|
||||||
} else
|
|
||||||
counted += count_per_buf;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* stop clock */
|
|
||||||
end = getFloatTime();
|
|
||||||
copy_score = (long) ((double) counted / ((end - start) * count_per_k));
|
|
||||||
printf("Copy done: %ld in %.4f, score %ld\n",
|
|
||||||
counted, end - start, copy_score);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Output the test results. Use the true time.
|
|
||||||
*/
|
|
||||||
fprintf(stderr, "COUNT|%ld|0|KBps\n", copy_score);
|
|
||||||
fprintf(stderr, "TIME|%.1f\n", end - start);
|
|
||||||
|
|
||||||
return(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void stop_count(int sig)
|
|
||||||
{
|
|
||||||
extern int sigalarm;
|
|
||||||
sigalarm = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void clean_up(int sig)
|
|
||||||
{
|
|
||||||
unlink(FNAME0);
|
|
||||||
unlink(FNAME1);
|
|
||||||
}
|
|
|
@ -1,75 +0,0 @@
|
||||||
/*******************************************************************************
|
|
||||||
* The BYTE UNIX Benchmarks - Release 3
|
|
||||||
* Module: hanoi.c SID: 3.3 5/15/91 19:30:20
|
|
||||||
*
|
|
||||||
*******************************************************************************
|
|
||||||
* Bug reports, patches, comments, suggestions should be sent to:
|
|
||||||
*
|
|
||||||
* Ben Smith, Rick Grehan or Tom Yager
|
|
||||||
* ben@bytepb.byte.com rick_g@bytepb.byte.com tyager@bytepb.byte.com
|
|
||||||
*
|
|
||||||
*******************************************************************************
|
|
||||||
* Modification Log:
|
|
||||||
* $Header: hanoi.c,v 3.5 87/08/06 08:11:14 kenj Exp $
|
|
||||||
* August 28, 1990 - Modified timing routines (ty)
|
|
||||||
* October 22, 1997 - code cleanup to remove ANSI C compiler warnings
|
|
||||||
* Andy Kahn <kahn@zk3.dec.com>
|
|
||||||
*
|
|
||||||
******************************************************************************/
|
|
||||||
char SCCSid[] = "@(#) @(#)hanoi.c:3.3 -- 5/15/91 19:30:20";
|
|
||||||
|
|
||||||
#define other(i,j) (6-(i+j))
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include "timeit.c"
|
|
||||||
|
|
||||||
void mov(int n, int f, int t);
|
|
||||||
|
|
||||||
unsigned long iter = 0;
|
|
||||||
int num[4];
|
|
||||||
long cnt;
|
|
||||||
|
|
||||||
void report(int sig)
|
|
||||||
{
|
|
||||||
fprintf(stderr,"COUNT|%ld|1|lps\n", iter);
|
|
||||||
exit(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
|
||||||
{
|
|
||||||
int disk=10, /* default number of disks */
|
|
||||||
duration;
|
|
||||||
|
|
||||||
if (argc < 2) {
|
|
||||||
fprintf(stderr,"Usage: %s duration [disks]\n", argv[0]);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
duration = atoi(argv[1]);
|
|
||||||
if(argc > 2) disk = atoi(argv[2]);
|
|
||||||
num[1] = disk;
|
|
||||||
|
|
||||||
wake_me(duration, report);
|
|
||||||
|
|
||||||
while(1) {
|
|
||||||
mov(disk,1,3);
|
|
||||||
iter++;
|
|
||||||
}
|
|
||||||
|
|
||||||
exit(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void mov(int n, int f, int t)
|
|
||||||
{
|
|
||||||
int o;
|
|
||||||
if(n == 1) {
|
|
||||||
num[f]--;
|
|
||||||
num[t]++;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
o = other(f,t);
|
|
||||||
mov(n-1,f,o);
|
|
||||||
mov(1,f,t);
|
|
||||||
mov(n-1,o,t);
|
|
||||||
}
|
|
|
@ -1,103 +0,0 @@
|
||||||
/*******************************************************************************
|
|
||||||
* The BYTE UNIX Benchmarks - Release 1
|
|
||||||
* Module: looper.c SID: 1.4 5/15/91 19:30:22
|
|
||||||
*
|
|
||||||
*******************************************************************************
|
|
||||||
* Bug reports, patches, comments, suggestions should be sent to:
|
|
||||||
*
|
|
||||||
* Ben Smith or Tom Yager at BYTE Magazine
|
|
||||||
* ben@bytepb.byte.com tyager@bytepb.byte.com
|
|
||||||
*
|
|
||||||
*******************************************************************************
|
|
||||||
* Modification Log:
|
|
||||||
*
|
|
||||||
* February 25, 1991 -- created (Ben S.)
|
|
||||||
* October 22, 1997 - code cleanup to remove ANSI C compiler warnings
|
|
||||||
* Andy Kahn <kahn@zk3.dec.com>
|
|
||||||
*
|
|
||||||
******************************************************************************/
|
|
||||||
char SCCSid[] = "@(#) @(#)looper.c:1.4 -- 5/15/91 19:30:22";
|
|
||||||
/*
|
|
||||||
* Shell Process creation
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <sys/wait.h>
|
|
||||||
#include "timeit.c"
|
|
||||||
|
|
||||||
unsigned long iter;
|
|
||||||
char *cmd_argv[28];
|
|
||||||
int cmd_argc;
|
|
||||||
|
|
||||||
void report(int sig)
|
|
||||||
{
|
|
||||||
fprintf(stderr,"COUNT|%lu|60|lpm\n", iter);
|
|
||||||
exit(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
|
||||||
{
|
|
||||||
int slave, count, duration;
|
|
||||||
int status;
|
|
||||||
|
|
||||||
if (argc < 2)
|
|
||||||
{
|
|
||||||
fprintf(stderr,"Usage: %s duration command [args..]\n", argv[0]);
|
|
||||||
fprintf(stderr," duration in seconds\n");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if((duration = atoi(argv[1])) < 1)
|
|
||||||
{
|
|
||||||
fprintf(stderr,"Usage: %s duration command [arg..]\n", argv[0]);
|
|
||||||
fprintf(stderr," duration in seconds\n");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* get command */
|
|
||||||
cmd_argc=argc-2;
|
|
||||||
for( count=2;count < argc; ++count)
|
|
||||||
cmd_argv[count-2]=argv[count];
|
|
||||||
#ifdef DEBUG
|
|
||||||
printf("<<%s>>",cmd_argv[0]);
|
|
||||||
for(count=1;count < cmd_argc; ++count)
|
|
||||||
printf(" <%s>", cmd_argv[count]);
|
|
||||||
putchar('\n');
|
|
||||||
exit(0);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
iter = 0;
|
|
||||||
wake_me(duration, report);
|
|
||||||
|
|
||||||
while (1)
|
|
||||||
{
|
|
||||||
if ((slave = fork()) == 0)
|
|
||||||
{ /* execute command */
|
|
||||||
execvp(cmd_argv[0],cmd_argv);
|
|
||||||
exit(99);
|
|
||||||
}
|
|
||||||
else if (slave < 0)
|
|
||||||
{
|
|
||||||
/* woops ... */
|
|
||||||
fprintf(stderr,"Fork failed at iteration %lu\n", iter);
|
|
||||||
perror("Reason");
|
|
||||||
exit(2);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
/* master */
|
|
||||||
wait(&status);
|
|
||||||
if (status == 99 << 8)
|
|
||||||
{
|
|
||||||
fprintf(stderr, "Command \"%s\" didn't exec\n", cmd_argv[0]);
|
|
||||||
exit(2);
|
|
||||||
}
|
|
||||||
else if (status != 0)
|
|
||||||
{
|
|
||||||
fprintf(stderr,"Bad wait status: 0x%x\n", status);
|
|
||||||
exit(2);
|
|
||||||
}
|
|
||||||
iter++;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,66 +0,0 @@
|
||||||
/*******************************************************************************
|
|
||||||
* The BYTE UNIX Benchmarks - Release 3
|
|
||||||
* Module: pipe.c SID: 3.3 5/15/91 19:30:20
|
|
||||||
*
|
|
||||||
*******************************************************************************
|
|
||||||
* Bug reports, patches, comments, suggestions should be sent to:
|
|
||||||
*
|
|
||||||
* Ben Smith, Rick Grehan or Tom Yager
|
|
||||||
* ben@bytepb.byte.com rick_g@bytepb.byte.com tyager@bytepb.byte.com
|
|
||||||
*
|
|
||||||
*******************************************************************************
|
|
||||||
* Modification Log:
|
|
||||||
* $Header: pipe.c,v 3.5 87/06/22 14:32:36 kjmcdonell Beta $
|
|
||||||
* August 29, 1990 - modified timing routines (ty)
|
|
||||||
* October 22, 1997 - code cleanup to remove ANSI C compiler warnings
|
|
||||||
* Andy Kahn <kahn@zk3.dec.com>
|
|
||||||
*
|
|
||||||
******************************************************************************/
|
|
||||||
char SCCSid[] = "@(#) @(#)pipe.c:3.3 -- 5/15/91 19:30:20";
|
|
||||||
/*
|
|
||||||
* pipe -- test single process pipe throughput (no context switching)
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include "timeit.c"
|
|
||||||
|
|
||||||
unsigned long iter;
|
|
||||||
|
|
||||||
void report(int sig)
|
|
||||||
{
|
|
||||||
fprintf(stderr,"COUNT|%ld|1|lps\n", iter);
|
|
||||||
exit(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
|
||||||
{
|
|
||||||
char buf[512];
|
|
||||||
int pvec[2], duration;
|
|
||||||
|
|
||||||
if (argc != 2) {
|
|
||||||
fprintf(stderr,"Usage: %s duration\n", argv[0]);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
duration = atoi(argv[1]);
|
|
||||||
|
|
||||||
pipe(pvec);
|
|
||||||
|
|
||||||
wake_me(duration, report);
|
|
||||||
iter = 0;
|
|
||||||
|
|
||||||
while (1) {
|
|
||||||
if (write(pvec[1], buf, sizeof(buf)) != sizeof(buf)) {
|
|
||||||
if ((errno != EINTR) && (errno != 0))
|
|
||||||
fprintf(stderr,"write failed, error %d\n", errno);
|
|
||||||
}
|
|
||||||
if (read(pvec[0], buf, sizeof(buf)) != sizeof(buf)) {
|
|
||||||
if ((errno != EINTR) && (errno != 0))
|
|
||||||
fprintf(stderr,"read failed, error %d\n", errno);
|
|
||||||
}
|
|
||||||
iter++;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,78 +0,0 @@
|
||||||
/*******************************************************************************
|
|
||||||
* The BYTE UNIX Benchmarks - Release 3
|
|
||||||
* Module: spawn.c SID: 3.3 5/15/91 19:30:20
|
|
||||||
*
|
|
||||||
*******************************************************************************
|
|
||||||
* Bug reports, patches, comments, suggestions should be sent to:
|
|
||||||
*
|
|
||||||
* Ben Smith, Rick Grehan or Tom Yagerat BYTE Magazine
|
|
||||||
* ben@bytepb.byte.com rick_g@bytepb.byte.com tyager@bytepb.byte.com
|
|
||||||
*
|
|
||||||
*******************************************************************************
|
|
||||||
* Modification Log:
|
|
||||||
* $Header: spawn.c,v 3.4 87/06/22 14:32:48 kjmcdonell Beta $
|
|
||||||
* August 29, 1990 - Modified timing routines (ty)
|
|
||||||
* October 22, 1997 - code cleanup to remove ANSI C compiler warnings
|
|
||||||
* Andy Kahn <kahn@zk3.dec.com>
|
|
||||||
*
|
|
||||||
******************************************************************************/
|
|
||||||
char SCCSid[] = "@(#) @(#)spawn.c:3.3 -- 5/15/91 19:30:20";
|
|
||||||
/*
|
|
||||||
* Process creation
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <sys/wait.h>
|
|
||||||
#include "timeit.c"
|
|
||||||
|
|
||||||
unsigned long iter;
|
|
||||||
|
|
||||||
void report(int sig)
|
|
||||||
{
|
|
||||||
fprintf(stderr,"COUNT|%lu|1|lps\n", iter);
|
|
||||||
exit(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
|
||||||
{
|
|
||||||
int slave, duration;
|
|
||||||
int status;
|
|
||||||
|
|
||||||
if (argc != 2) {
|
|
||||||
fprintf(stderr,"Usage: %s duration \n", argv[0]);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
duration = atoi(argv[1]);
|
|
||||||
|
|
||||||
iter = 0;
|
|
||||||
wake_me(duration, report);
|
|
||||||
|
|
||||||
while (1) {
|
|
||||||
if ((slave = fork()) == 0) {
|
|
||||||
/* slave .. boring */
|
|
||||||
#if debug
|
|
||||||
printf("fork OK\n");
|
|
||||||
#endif
|
|
||||||
/* kill it right away */
|
|
||||||
exit(0);
|
|
||||||
} else if (slave < 0) {
|
|
||||||
/* woops ... */
|
|
||||||
fprintf(stderr,"Fork failed at iteration %lu\n", iter);
|
|
||||||
perror("Reason");
|
|
||||||
exit(2);
|
|
||||||
} else
|
|
||||||
/* master */
|
|
||||||
wait(&status);
|
|
||||||
if (status != 0) {
|
|
||||||
fprintf(stderr,"Bad wait status: 0x%x\n", status);
|
|
||||||
exit(2);
|
|
||||||
}
|
|
||||||
iter++;
|
|
||||||
#if debug
|
|
||||||
printf("Child %d done.\n", slave);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,107 +0,0 @@
|
||||||
/*******************************************************************************
|
|
||||||
* The BYTE UNIX Benchmarks - Release 3
|
|
||||||
* Module: syscall.c SID: 3.3 5/15/91 19:30:21
|
|
||||||
*
|
|
||||||
*******************************************************************************
|
|
||||||
* Bug reports, patches, comments, suggestions should be sent to:
|
|
||||||
*
|
|
||||||
* Ben Smith, Rick Grehan or Tom Yager at BYTE Magazine
|
|
||||||
* ben@bytepb.byte.com rick_g@bytepb.byte.com tyager@bytepb.byte.com
|
|
||||||
*
|
|
||||||
*******************************************************************************
|
|
||||||
* Modification Log:
|
|
||||||
* $Header: syscall.c,v 3.4 87/06/22 14:32:54 kjmcdonell Beta $
|
|
||||||
* August 29, 1990 - Modified timing routines
|
|
||||||
* October 22, 1997 - code cleanup to remove ANSI C compiler warnings
|
|
||||||
* Andy Kahn <kahn@zk3.dec.com>
|
|
||||||
*
|
|
||||||
******************************************************************************/
|
|
||||||
/*
|
|
||||||
* syscall -- sit in a loop calling the system
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
char SCCSid[] = "@(#) @(#)syscall.c:3.3 -- 5/15/91 19:30:21";
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/wait.h>
|
|
||||||
#include "timeit.c"
|
|
||||||
|
|
||||||
unsigned long iter;
|
|
||||||
|
|
||||||
void report(int sig)
|
|
||||||
{
|
|
||||||
fprintf(stderr,"COUNT|%ld|1|lps\n", iter);
|
|
||||||
exit(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
|
||||||
{
|
|
||||||
char *test;
|
|
||||||
int duration;
|
|
||||||
|
|
||||||
if (argc < 2) {
|
|
||||||
fprintf(stderr,"Usage: %s duration [ test ]\n", argv[0]);
|
|
||||||
fprintf(stderr,"test is one of:\n");
|
|
||||||
fprintf(stderr," \"mix\" (default), \"close\", \"getpid\", \"exec\"\n");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
if (argc > 2)
|
|
||||||
test = argv[2];
|
|
||||||
else
|
|
||||||
test = "mix";
|
|
||||||
|
|
||||||
duration = atoi(argv[1]);
|
|
||||||
|
|
||||||
iter = 0;
|
|
||||||
wake_me(duration, report);
|
|
||||||
|
|
||||||
switch (test[0]) {
|
|
||||||
case 'm':
|
|
||||||
while (1) {
|
|
||||||
close(dup(0));
|
|
||||||
getpid();
|
|
||||||
getuid();
|
|
||||||
umask(022);
|
|
||||||
iter++;
|
|
||||||
}
|
|
||||||
/* NOTREACHED */
|
|
||||||
case 'c':
|
|
||||||
while (1) {
|
|
||||||
close(dup(0));
|
|
||||||
iter++;
|
|
||||||
}
|
|
||||||
/* NOTREACHED */
|
|
||||||
case 'g':
|
|
||||||
while (1) {
|
|
||||||
getpid();
|
|
||||||
iter++;
|
|
||||||
}
|
|
||||||
/* NOTREACHED */
|
|
||||||
case 'e':
|
|
||||||
while (1) {
|
|
||||||
pid_t pid = fork();
|
|
||||||
if (pid < 0) {
|
|
||||||
fprintf(stderr,"%s: fork failed\n", argv[0]);
|
|
||||||
exit(1);
|
|
||||||
} else if (pid == 0) {
|
|
||||||
execl("/usr/bin/true", (char *) 0);
|
|
||||||
fprintf(stderr,"%s: exec /usr/bin/true failed\n", argv[0]);
|
|
||||||
exit(1);
|
|
||||||
} else {
|
|
||||||
if (waitpid(pid, NULL, 0) < 0) {
|
|
||||||
fprintf(stderr,"%s: waitpid failed\n", argv[0]);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
iter++;
|
|
||||||
}
|
|
||||||
/* NOTREACHED */
|
|
||||||
}
|
|
||||||
|
|
||||||
exit(9);
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,578 +0,0 @@
|
||||||
/* Programme to test how long it takes to select(2), poll(2) and poll2(2) a
|
|
||||||
large number of file descriptors.
|
|
||||||
|
|
||||||
Copyright 1997 Richard Gooch rgooch@atnf.csiro.au
|
|
||||||
Distributed under the GNU General Public License.
|
|
||||||
|
|
||||||
To compile this programme, use gcc -O2 -o time-polling time-polling.c
|
|
||||||
|
|
||||||
Extra compile flags:
|
|
||||||
|
|
||||||
Add -DHAS_SELECT if your operating system has the select(2) system call
|
|
||||||
Add -DHAS_POLL if your operating system has the poll(2) system call
|
|
||||||
Add -DHAS_POLL2 if your operating system has the poll2(2) system call
|
|
||||||
|
|
||||||
Usage: time-polling [num_iter] [num_to_test] [num_active] [-v]
|
|
||||||
|
|
||||||
NOTE: on many systems the default limit on file descriptors is less than
|
|
||||||
1024. You should try to increase this limit to 1024 before doing the test.
|
|
||||||
Something like "limit descriptors 1024" or "limit openfiles 1024" should do
|
|
||||||
the trick. On some systems (like IRIX), doing the test on a smaller number
|
|
||||||
gives a *much* smaller time per descriptor, which shows that time taken
|
|
||||||
does not scale linearly with number of descriptors, which is non-optimal.
|
|
||||||
In the tests I've done, I try to use 1024 descriptors.
|
|
||||||
The benchmark results are available at:
|
|
||||||
http://www.atnf.csiro.au/~rgooch/benchmarks.html
|
|
||||||
If you want to contribute results, please email them to me. Please specify
|
|
||||||
if you want to be acknowledged.
|
|
||||||
|
|
||||||
|
|
||||||
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 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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
||||||
|
|
||||||
Richard Gooch may be reached by email at rgooch@atnf.csiro.au
|
|
||||||
The postal address is:
|
|
||||||
Richard Gooch, c/o ATNF, P. O. Box 76, Epping, N.S.W., 2121, Australia.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef UNIXBENCH
|
|
||||||
#define OUT stdout
|
|
||||||
#else
|
|
||||||
#define OUT stderr
|
|
||||||
#endif
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <sys/time.h>
|
|
||||||
#include <sys/resource.h>
|
|
||||||
#ifdef HAS_POLL
|
|
||||||
# include <sys/poll.h>
|
|
||||||
#endif
|
|
||||||
#ifdef HAS_POLL2
|
|
||||||
# include <linux/poll2.h>
|
|
||||||
#endif
|
|
||||||
#ifdef HAS_SELECT
|
|
||||||
# include <sys/select.h>
|
|
||||||
#endif
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
#define TRUE 1
|
|
||||||
#define FALSE 0
|
|
||||||
#ifdef UNIXBENCH
|
|
||||||
#define MAX_ITERATIONS 1000
|
|
||||||
#else
|
|
||||||
#define MAX_ITERATIONS 30
|
|
||||||
#endif
|
|
||||||
#define MAX_FDS 40960
|
|
||||||
#define CONST const
|
|
||||||
#define ERRSTRING strerror (errno)
|
|
||||||
|
|
||||||
typedef int flag;
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef HAS_POLL
|
|
||||||
/*
|
|
||||||
static inline int find_first_set_bit (CONST void *array, int size)
|
|
||||||
*/
|
|
||||||
static int find_first_set_bit (CONST void *array, int size)
|
|
||||||
/* [SUMMARY] Find the first bit set in a bitfield.
|
|
||||||
<array> A pointer to the bitfield. This must be aligned on a long boundary.
|
|
||||||
<size> The number of bits in the bitfield.
|
|
||||||
[RETURNS] The index of the first set bit. If no bits are set, <<size>> + 1
|
|
||||||
is returned.
|
|
||||||
*/
|
|
||||||
{
|
|
||||||
int index;
|
|
||||||
unsigned long word;
|
|
||||||
unsigned int ul_size = 8 * sizeof (unsigned long);
|
|
||||||
CONST unsigned long *ul_array = array;
|
|
||||||
|
|
||||||
/* Find first word with any bit set */
|
|
||||||
for (index = 0; (*ul_array == 0) && (index < size);
|
|
||||||
index += ul_size, ++ul_array);
|
|
||||||
/* Find first bit set in word */
|
|
||||||
for (word = *ul_array; !(word & 1) && (index < size);
|
|
||||||
++index, word = word >> 1);
|
|
||||||
return (index);
|
|
||||||
} /* End Function find_first_set_bit */
|
|
||||||
|
|
||||||
/*
|
|
||||||
static inline int find_next_set_bit (CONST void *array, int size, int offset)
|
|
||||||
*/
|
|
||||||
static int find_next_set_bit (CONST void *array, int size, int offset)
|
|
||||||
/* [SUMMARY] Find the next bit set in a bitfield.
|
|
||||||
<array> A pointer to the bitfield. This must be aligned on a long boundary.
|
|
||||||
<size> The number of bits in the bitfield.
|
|
||||||
<offset> The offset of the current bit in the bitfield. The current bit is
|
|
||||||
ignored.
|
|
||||||
[RETURNS] The index of the next set bit. If no more bits are set,
|
|
||||||
<<size>> + 1 is returned.
|
|
||||||
*/
|
|
||||||
{
|
|
||||||
int index, tmp;
|
|
||||||
unsigned long word;
|
|
||||||
unsigned int ul_size = 8 * sizeof (unsigned long);
|
|
||||||
CONST unsigned long *ul_array = array;
|
|
||||||
|
|
||||||
if (++offset >= size) return (offset);
|
|
||||||
index = offset;
|
|
||||||
/* Jump to the long word containing the next bit */
|
|
||||||
tmp = offset / ul_size;
|
|
||||||
ul_array += tmp;
|
|
||||||
offset -= tmp * ul_size;
|
|
||||||
if ( (offset == 0) || (*ul_array == 0) )
|
|
||||||
return (find_first_set_bit (ul_array, size - index) + index);
|
|
||||||
/* There is a bit set somewhere in this word */
|
|
||||||
if ( ( (word = *ul_array) != 0 ) && ( (word = word >> offset) != 0 ) )
|
|
||||||
{
|
|
||||||
/* There is a bit set somewhere in this word at or after the offset
|
|
||||||
position */
|
|
||||||
for (; (word & 1) == 0; word = word >> 1, ++index);
|
|
||||||
return (index);
|
|
||||||
}
|
|
||||||
/* Have to go to subsequent word(s) */
|
|
||||||
index += ul_size - offset;
|
|
||||||
return (find_first_set_bit (++ul_array, size - index) + index);
|
|
||||||
} /* End Function find_next_set_bit */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
struct callback_struct
|
|
||||||
{
|
|
||||||
void (*input_func) (void *info);
|
|
||||||
void (*output_func) (void *info);
|
|
||||||
void (*exception_func) (void *info);
|
|
||||||
void *info;
|
|
||||||
};
|
|
||||||
|
|
||||||
static int total_bits = 0;
|
|
||||||
struct callback_struct callbacks[MAX_FDS];
|
|
||||||
|
|
||||||
|
|
||||||
static void test_func (void *info)
|
|
||||||
{
|
|
||||||
++total_bits;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef HAS_SELECT
|
|
||||||
static void time_select (fd_set *input_fds, fd_set *output_fds,
|
|
||||||
fd_set *exception_fds, int max_fd, int num_iter,
|
|
||||||
long *times)
|
|
||||||
/* [SUMMARY] Time how long it takes to select(2) file descriptors.
|
|
||||||
<input_fds> The input masks.
|
|
||||||
<output_fds> The output masks.
|
|
||||||
<exception_fds> The exception masks.
|
|
||||||
<max_fd> The highest file descriptor in the fd_sets.
|
|
||||||
<num_iter> The number of iterations.
|
|
||||||
<times> The time taken (in microseconds) for each iteration.
|
|
||||||
[RETURNS] Nothing.
|
|
||||||
*/
|
|
||||||
{
|
|
||||||
int fd, count, nready;
|
|
||||||
fd_set i_fds, o_fds, e_fds;
|
|
||||||
struct timeval time1, time2, tv;
|
|
||||||
|
|
||||||
/* Warm the cache a bit */
|
|
||||||
memcpy (&i_fds, input_fds, sizeof i_fds);
|
|
||||||
memcpy (&o_fds, output_fds, sizeof i_fds);
|
|
||||||
memcpy (&e_fds, exception_fds, sizeof i_fds);
|
|
||||||
tv.tv_sec = 0;
|
|
||||||
tv.tv_usec = 0;
|
|
||||||
select (max_fd + 1, &i_fds, &o_fds, &e_fds, &tv);
|
|
||||||
for (count = 0; count < num_iter; ++count)
|
|
||||||
{
|
|
||||||
total_bits = 0;
|
|
||||||
gettimeofday (&time1, NULL);
|
|
||||||
memcpy (&i_fds, input_fds, sizeof i_fds);
|
|
||||||
memcpy (&o_fds, output_fds, sizeof i_fds);
|
|
||||||
memcpy (&e_fds, exception_fds, sizeof i_fds);
|
|
||||||
tv.tv_sec = 0;
|
|
||||||
tv.tv_usec = 0;
|
|
||||||
nready = select (max_fd + 1, &i_fds, &o_fds, &e_fds, &tv);
|
|
||||||
if (nready == -1)
|
|
||||||
{
|
|
||||||
fprintf (stderr, "Error selecting\t%s\n", ERRSTRING);
|
|
||||||
exit (2);
|
|
||||||
}
|
|
||||||
if (nready < 1)
|
|
||||||
{
|
|
||||||
fprintf (stderr, "Error: nready: %d\n", nready);
|
|
||||||
exit (1);
|
|
||||||
}
|
|
||||||
/* Scan the output */
|
|
||||||
for (fd = find_first_set_bit (&e_fds, sizeof e_fds * 8); fd <= max_fd;
|
|
||||||
fd = find_next_set_bit (&e_fds, sizeof e_fds * 8, fd) )
|
|
||||||
{
|
|
||||||
(*callbacks[fd].exception_func) (callbacks[fd].info);
|
|
||||||
}
|
|
||||||
for (fd = find_first_set_bit (&i_fds, sizeof i_fds * 8); fd <= max_fd;
|
|
||||||
fd = find_next_set_bit (&i_fds, sizeof i_fds * 8, fd) )
|
|
||||||
{
|
|
||||||
(*callbacks[fd].input_func) (callbacks[fd].info);
|
|
||||||
}
|
|
||||||
for (fd = find_first_set_bit (&o_fds, sizeof o_fds * 8); fd <= max_fd;
|
|
||||||
fd = find_next_set_bit (&o_fds, sizeof o_fds * 8, fd) )
|
|
||||||
{
|
|
||||||
(*callbacks[fd].output_func) (callbacks[fd].info);
|
|
||||||
}
|
|
||||||
gettimeofday (&time2, NULL);
|
|
||||||
times[count] = (time2.tv_sec - time1.tv_sec) * 1000000;
|
|
||||||
times[count] += time2.tv_usec - time1.tv_usec;
|
|
||||||
}
|
|
||||||
} /* End Function time_select */
|
|
||||||
#endif /* HAS_SELECT */
|
|
||||||
|
|
||||||
#ifdef HAS_POLL
|
|
||||||
static void time_poll (struct pollfd *pollfd_array, int start_index,
|
|
||||||
int num_to_test, int num_iter, long *times)
|
|
||||||
/* [SUMMARY] Time how long it takes to poll(2) file descriptors.
|
|
||||||
<pollfd_array> The array of pollfd structures.
|
|
||||||
<start_index> The start index in the array of pollfd structures.
|
|
||||||
<num_to_test> The number of file descriptors to test.
|
|
||||||
<num_iter> The number of iterations.
|
|
||||||
<times> The time taken (in microseconds) for each iteration.
|
|
||||||
[RETURNS] Nothing.
|
|
||||||
*/
|
|
||||||
{
|
|
||||||
short revents;
|
|
||||||
int fd, count, nready;
|
|
||||||
struct timeval time1, time2;
|
|
||||||
struct pollfd *pollfd_ptr, *stop_pollfd;
|
|
||||||
|
|
||||||
/* Warm the cache a bit */
|
|
||||||
poll (pollfd_array + start_index, num_to_test, 0);
|
|
||||||
for (count = 0; count < num_iter; ++count)
|
|
||||||
{
|
|
||||||
total_bits = 0;
|
|
||||||
gettimeofday (&time1, NULL);
|
|
||||||
nready = poll (pollfd_array + start_index, num_to_test, 0);
|
|
||||||
if (nready == -1)
|
|
||||||
{
|
|
||||||
fprintf (stderr, "Error polling\t%s\n", ERRSTRING);
|
|
||||||
exit (2);
|
|
||||||
}
|
|
||||||
if (nready < 1)
|
|
||||||
{
|
|
||||||
fprintf (stderr, "Error: nready: %d\n", nready);
|
|
||||||
exit (1);
|
|
||||||
}
|
|
||||||
stop_pollfd = pollfd_array + start_index + num_to_test;
|
|
||||||
for (pollfd_ptr = pollfd_array + start_index; TRUE; ++pollfd_ptr)
|
|
||||||
{
|
|
||||||
if (pollfd_ptr->revents == 0) continue;
|
|
||||||
/* Have an active descriptor */
|
|
||||||
revents = pollfd_ptr->revents;
|
|
||||||
fd = pollfd_ptr->fd;
|
|
||||||
if (revents & POLLPRI)
|
|
||||||
(*callbacks[fd].exception_func) (callbacks[fd].info);
|
|
||||||
if (revents & POLLIN)
|
|
||||||
(*callbacks[fd].input_func) (callbacks[fd].info);
|
|
||||||
if (revents & POLLOUT)
|
|
||||||
(*callbacks[fd].output_func) (callbacks[fd].info);
|
|
||||||
if (--nready == 0) break;
|
|
||||||
}
|
|
||||||
gettimeofday (&time2, NULL);
|
|
||||||
times[count] = (time2.tv_sec - time1.tv_sec) * 1000000;
|
|
||||||
times[count] += time2.tv_usec - time1.tv_usec;
|
|
||||||
}
|
|
||||||
} /* End Function time_poll */
|
|
||||||
#endif /* HAS_POLL */
|
|
||||||
|
|
||||||
#ifdef HAS_POLL2
|
|
||||||
static void time_poll2 (struct poll2ifd *poll2ifd_array, int start_index,
|
|
||||||
int num_to_test, int num_iter, long *times)
|
|
||||||
/* [SUMMARY] Time how long it takes to poll2(2) file descriptors.
|
|
||||||
<poll2ifd_array> The array of poll2ifd structures.
|
|
||||||
<start_index> The start index in the array of pollfd structures.
|
|
||||||
<num_to_test> The number of file descriptors to test.
|
|
||||||
<num_iter> The number of iterations.
|
|
||||||
<times> The time taken (in microseconds) for each iteration.
|
|
||||||
[RETURNS] Nothing.
|
|
||||||
*/
|
|
||||||
{
|
|
||||||
short revents;
|
|
||||||
int fd, count, nready, i;
|
|
||||||
struct timeval time1, time2;
|
|
||||||
struct poll2ofd poll2ofd_array[MAX_FDS];
|
|
||||||
|
|
||||||
/* Warm the cache a bit */
|
|
||||||
poll2 (poll2ifd_array + start_index, poll2ofd_array, num_to_test, 0);
|
|
||||||
for (count = 0; count < num_iter; ++count)
|
|
||||||
{
|
|
||||||
total_bits = 0;
|
|
||||||
gettimeofday (&time1, NULL);
|
|
||||||
nready = poll2 (poll2ifd_array + start_index, poll2ofd_array,
|
|
||||||
num_to_test, 0);
|
|
||||||
if (nready == -1)
|
|
||||||
{
|
|
||||||
times[count] = -1;
|
|
||||||
if (errno == ENOSYS) return; /* Must do this first */
|
|
||||||
fprintf (stderr, "Error calling poll2(2)\t%s\n", ERRSTRING);
|
|
||||||
exit (2);
|
|
||||||
}
|
|
||||||
if (nready < 1)
|
|
||||||
{
|
|
||||||
fprintf (stderr, "Error: nready: %d\n", nready);
|
|
||||||
exit (1);
|
|
||||||
}
|
|
||||||
for (i = 0; i < nready; ++i)
|
|
||||||
{
|
|
||||||
revents = poll2ofd_array[i].revents;
|
|
||||||
fd = poll2ofd_array[i].fd;
|
|
||||||
if (revents & POLLPRI)
|
|
||||||
(*callbacks[fd].exception_func) (callbacks[fd].info);
|
|
||||||
if (revents & POLLIN)
|
|
||||||
(*callbacks[fd].input_func) (callbacks[fd].info);
|
|
||||||
if (revents & POLLOUT)
|
|
||||||
(*callbacks[fd].output_func) (callbacks[fd].info);
|
|
||||||
}
|
|
||||||
gettimeofday (&time2, NULL);
|
|
||||||
times[count] = (time2.tv_sec - time1.tv_sec) * 1000000;
|
|
||||||
times[count] += time2.tv_usec - time1.tv_usec;
|
|
||||||
}
|
|
||||||
} /* End Function time_poll2 */
|
|
||||||
#endif /* HAS_POLL2 */
|
|
||||||
|
|
||||||
|
|
||||||
int main (argc, argv)
|
|
||||||
int argc;
|
|
||||||
char *argv[];
|
|
||||||
{
|
|
||||||
flag failed = FALSE;
|
|
||||||
flag verbose = FALSE;
|
|
||||||
int first_fd = -1;
|
|
||||||
int fd, max_fd, count, total_fds;
|
|
||||||
int num_to_test, num_active;
|
|
||||||
#ifdef UNIXBENCH
|
|
||||||
int max_iter = 1000;
|
|
||||||
#else
|
|
||||||
int max_iter = 10;
|
|
||||||
#endif
|
|
||||||
#ifdef HAS_SELECT
|
|
||||||
long select_total = 0;
|
|
||||||
fd_set input_fds, output_fds, exception_fds;
|
|
||||||
long select_times[MAX_ITERATIONS];
|
|
||||||
#endif
|
|
||||||
#ifdef HAS_POLL
|
|
||||||
int start_index;
|
|
||||||
long poll_total = 0;
|
|
||||||
struct pollfd pollfd_array[MAX_FDS];
|
|
||||||
long poll_times[MAX_ITERATIONS];
|
|
||||||
#endif
|
|
||||||
#ifdef HAS_POLL2
|
|
||||||
long poll2_total = 0;
|
|
||||||
struct poll2ifd poll2ifd_array[MAX_FDS];
|
|
||||||
struct poll2ofd poll2ofd_array[MAX_FDS];
|
|
||||||
long poll2_times[MAX_ITERATIONS];
|
|
||||||
#endif
|
|
||||||
#if 0
|
|
||||||
extern char *sys_errlist[];
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAS_SELECT
|
|
||||||
FD_ZERO (&input_fds);
|
|
||||||
FD_ZERO (&output_fds);
|
|
||||||
FD_ZERO (&exception_fds);
|
|
||||||
#endif
|
|
||||||
#ifdef HAS_POLL
|
|
||||||
memset (pollfd_array, 0, sizeof pollfd_array);
|
|
||||||
#endif
|
|
||||||
/* Allocate file descriptors */
|
|
||||||
total_fds = 0;
|
|
||||||
max_fd = 0;
|
|
||||||
while (!failed)
|
|
||||||
{
|
|
||||||
if ( ( fd = dup (1) ) == -1 )
|
|
||||||
{
|
|
||||||
if (errno != EMFILE)
|
|
||||||
{
|
|
||||||
fprintf (stderr, "Error dup()ing\t%s\n", ERRSTRING);
|
|
||||||
exit (1);
|
|
||||||
}
|
|
||||||
failed = TRUE;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (fd >= MAX_FDS)
|
|
||||||
{
|
|
||||||
fprintf (stderr, "File descriptor: %d larger than max: %d\n",
|
|
||||||
fd, MAX_FDS - 1);
|
|
||||||
exit (1);
|
|
||||||
}
|
|
||||||
callbacks[fd].input_func = test_func;
|
|
||||||
callbacks[fd].output_func = test_func;
|
|
||||||
callbacks[fd].exception_func = test_func;
|
|
||||||
callbacks[fd].info = NULL;
|
|
||||||
if (fd > max_fd) max_fd = fd;
|
|
||||||
if (first_fd < 0) first_fd = fd;
|
|
||||||
#ifdef HAS_POLL
|
|
||||||
pollfd_array[fd].fd = fd;
|
|
||||||
pollfd_array[fd].events = 0;
|
|
||||||
#endif
|
|
||||||
#ifdef HAS_POLL2
|
|
||||||
poll2ifd_array[fd].fd = fd;
|
|
||||||
poll2ifd_array[fd].events = 0;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
total_fds = max_fd + 1;
|
|
||||||
/* Process the command-line arguments */
|
|
||||||
if (argc > 5)
|
|
||||||
{
|
|
||||||
fputs ("Usage:\ttime-polling [num_iter] [num_to_test] [num_active] [-v]\n",
|
|
||||||
stderr);
|
|
||||||
exit (1);
|
|
||||||
}
|
|
||||||
if (argc > 1) max_iter = atoi (argv[1]);
|
|
||||||
if (max_iter > MAX_ITERATIONS)
|
|
||||||
{
|
|
||||||
fprintf (stderr, "num_iter too large\n");
|
|
||||||
exit (1);
|
|
||||||
}
|
|
||||||
if (argc > 2) num_to_test = atoi (argv[2]);
|
|
||||||
else num_to_test = total_fds - first_fd;
|
|
||||||
if (argc > 3) num_active = atoi (argv[3]);
|
|
||||||
else num_active = 1;
|
|
||||||
if (argc > 4)
|
|
||||||
{
|
|
||||||
if (strcmp (argv[4], "-v") != 0)
|
|
||||||
{
|
|
||||||
fputs ("Usage:\ttime-polling [num_iter] [num_to_test] [num_active] [-v]\n",
|
|
||||||
stderr);
|
|
||||||
exit (1);
|
|
||||||
}
|
|
||||||
verbose = TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Sanity tests */
|
|
||||||
if (num_to_test > total_fds - first_fd) num_to_test = total_fds - first_fd;
|
|
||||||
if (num_active > total_fds - first_fd) num_active = total_fds - first_fd;
|
|
||||||
/* Set activity monitoring flags */
|
|
||||||
for (fd = total_fds - num_to_test; fd < total_fds; ++fd)
|
|
||||||
{
|
|
||||||
#ifdef HAS_SELECT
|
|
||||||
FD_SET (fd, &exception_fds);
|
|
||||||
FD_SET (fd, &input_fds);
|
|
||||||
#endif
|
|
||||||
#ifdef HAS_POLL
|
|
||||||
pollfd_array[fd].events = POLLPRI | POLLIN;
|
|
||||||
#endif
|
|
||||||
#ifdef HAS_POLL2
|
|
||||||
poll2ifd_array[fd].events = POLLPRI | POLLIN;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
for (fd = total_fds - num_active; fd < total_fds; ++fd)
|
|
||||||
{
|
|
||||||
#ifdef HAS_SELECT
|
|
||||||
FD_SET (fd, &output_fds);
|
|
||||||
#endif
|
|
||||||
#ifdef HAS_POLL
|
|
||||||
pollfd_array[fd].events |= POLLOUT;
|
|
||||||
#endif
|
|
||||||
#ifdef HAS_POLL2
|
|
||||||
poll2ifd_array[fd].events |= POLLOUT;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
fprintf (OUT, "Num fds: %d, polling descriptors %d-%d\n",
|
|
||||||
total_fds, total_fds - num_to_test, max_fd);
|
|
||||||
/* First do all the tests, then print the results */
|
|
||||||
#ifdef HAS_SELECT
|
|
||||||
time_select (&input_fds, &output_fds, &exception_fds, max_fd, max_iter,
|
|
||||||
select_times);
|
|
||||||
#endif
|
|
||||||
#ifdef HAS_POLL
|
|
||||||
start_index = total_fds - num_to_test;
|
|
||||||
time_poll (pollfd_array, start_index, num_to_test, max_iter, poll_times);
|
|
||||||
#endif
|
|
||||||
#ifdef HAS_POLL2
|
|
||||||
start_index = total_fds - num_to_test;
|
|
||||||
time_poll2 (poll2ifd_array, start_index, num_to_test, max_iter,
|
|
||||||
poll2_times);
|
|
||||||
#endif
|
|
||||||
/* Now print out all the times */
|
|
||||||
fputs ("All times in microseconds\n", OUT);
|
|
||||||
fputs ("ITERATION\t", OUT);
|
|
||||||
#ifdef HAS_SELECT
|
|
||||||
fprintf (OUT, "%-12s", "select(2)");
|
|
||||||
#endif
|
|
||||||
#ifdef HAS_POLL
|
|
||||||
fprintf (OUT, "%-12s", "poll(2)");
|
|
||||||
#endif
|
|
||||||
#ifdef HAS_POLL2
|
|
||||||
if (poll2_times[0] >= 0) fprintf (OUT, "%-12s", "poll2(2)");
|
|
||||||
#endif
|
|
||||||
for (count = 0; count < max_iter; ++count)
|
|
||||||
{
|
|
||||||
if (verbose) fprintf (OUT, "\n%d\t\t", count);
|
|
||||||
#ifdef HAS_SELECT
|
|
||||||
if (verbose) fprintf (OUT, "%-12ld", select_times[count]);
|
|
||||||
select_total += select_times[count];
|
|
||||||
#endif
|
|
||||||
#ifdef HAS_POLL
|
|
||||||
if (verbose) fprintf (OUT, "%-12ld", poll_times[count]);
|
|
||||||
poll_total += poll_times[count];
|
|
||||||
#endif
|
|
||||||
#ifdef HAS_POLL2
|
|
||||||
if ( verbose && (poll2_times[0] >= 0) )
|
|
||||||
fprintf (OUT, "%-12ld", poll2_times[count]);
|
|
||||||
poll2_total += poll2_times[count];
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
fputs ("\n\naverage\t\t", OUT);
|
|
||||||
#ifdef HAS_SELECT
|
|
||||||
fprintf (OUT, "%-12ld", select_total / max_iter);
|
|
||||||
#endif
|
|
||||||
#ifdef HAS_POLL
|
|
||||||
fprintf (OUT, "%-12ld", poll_total / max_iter);
|
|
||||||
#endif
|
|
||||||
#ifdef HAS_POLL2
|
|
||||||
if (poll2_times[0] >= 0)
|
|
||||||
fprintf (OUT, "%-12ld", poll2_total / max_iter);
|
|
||||||
#endif
|
|
||||||
putc ('\n', OUT);
|
|
||||||
fputs ("Per fd\t\t", OUT);
|
|
||||||
#ifdef HAS_SELECT
|
|
||||||
fprintf (OUT, "%-12.2f",
|
|
||||||
(float) select_total / (float) max_iter / (float) num_to_test);
|
|
||||||
#ifdef UNIXBENCH
|
|
||||||
fprintf (stderr, "lps\t%.2f\t%.1f\n",
|
|
||||||
1000000 * (float) max_iter * (float) num_to_test
|
|
||||||
/ (float) select_total, (float)select_total / 1000000);
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
#ifdef HAS_POLL
|
|
||||||
fprintf (OUT, "%-12.2f",
|
|
||||||
(float) poll_total / (float) max_iter / (float) num_to_test);
|
|
||||||
#ifdef UNIXBENCH
|
|
||||||
fprintf (stderr, "lps\t%.2f\t%.1f\n",
|
|
||||||
1000000 * (float) max_iter * (float) num_to_test
|
|
||||||
/ (float) poll_total, (float)poll_total / 1000000);
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
#ifdef HAS_POLL2
|
|
||||||
if (poll2_times[0] >= 0) {
|
|
||||||
fprintf (OUT, "%-12.2f",
|
|
||||||
(float) poll2_total / (float) max_iter / (float) num_to_test);
|
|
||||||
#ifdef UNIXBENCH
|
|
||||||
fprintf (stderr, "lps\t%.2f\t%.1f\n",
|
|
||||||
1000000 * (float) max_iter * (float) num_to_test
|
|
||||||
/ (float) poll2_total, (float)poll2_total / 1000000);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
fputs ("<- the most important value\n", OUT);
|
|
||||||
|
|
||||||
exit(0);
|
|
||||||
} /* End Function main */
|
|
|
@ -1,39 +0,0 @@
|
||||||
/*******************************************************************************
|
|
||||||
*
|
|
||||||
* The BYTE UNIX Benchmarks - Release 3
|
|
||||||
* Module: timeit.c SID: 3.3 5/15/91 19:30:21
|
|
||||||
*******************************************************************************
|
|
||||||
* Bug reports, patches, comments, suggestions should be sent to:
|
|
||||||
*
|
|
||||||
* Ben Smith, Rick Grehan or Tom Yager
|
|
||||||
* ben@bytepb.byte.com rick_g@bytepb.byte.com tyager@bytepb.byte.com
|
|
||||||
*
|
|
||||||
*******************************************************************************
|
|
||||||
* Modification Log:
|
|
||||||
* May 12, 1989 - modified empty loops to avoid nullifying by optimizing
|
|
||||||
* compilers
|
|
||||||
* August 28, 1990 - changed timing relationship--now returns total number
|
|
||||||
* of iterations (ty)
|
|
||||||
* October 22, 1997 - code cleanup to remove ANSI C compiler warnings
|
|
||||||
* Andy Kahn <kahn@zk3.dec.com>
|
|
||||||
*
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
/* this module is #included in other modules--no separate SCCS ID */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Timing routine
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <signal.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
void wake_me(int seconds, void (*func)(int))
|
|
||||||
{
|
|
||||||
/* set up the signal handler */
|
|
||||||
signal(SIGALRM, func);
|
|
||||||
/* get the clock running */
|
|
||||||
alarm(seconds);
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,650 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) 1999-2001 Brian Paul All Rights Reserved.
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
|
||||||
* copy of this software and associated documentation files (the "Software"),
|
|
||||||
* to deal in the Software without restriction, including without limitation
|
|
||||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
||||||
* and/or sell copies of the Software, and to permit persons to whom the
|
|
||||||
* Software is furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included
|
|
||||||
* in all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|
||||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
||||||
* BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
|
||||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
|
||||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
*/
|
|
||||||
/* $XFree86: xc/programs/glxgears/glxgears.c,v 1.3tsi Exp $ */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This is a port of the infamous "gears" demo to straight GLX (i.e. no GLUT)
|
|
||||||
* Port by Brian Paul 23 March 2001
|
|
||||||
*
|
|
||||||
* Exact timing added by Behdad Esfahbod to achieve a fixed speed regardless
|
|
||||||
* of frame rate. November 2003
|
|
||||||
*
|
|
||||||
* Printer support added by Roland Mainz <roland.mainz@nrubsig.org>. April 2004
|
|
||||||
*
|
|
||||||
* This version modified by Ian Smith, 30 Sept 2007, to make ubgears.
|
|
||||||
* ubgears is cusoimised for use in the UnixBench benchmarking suite.
|
|
||||||
* Some redundant stuff is gone, and the -time option is added.
|
|
||||||
* Mainly it's forked so we don't use the host's version, which could change
|
|
||||||
* from platform to platform.
|
|
||||||
*
|
|
||||||
* Command line options:
|
|
||||||
* -display Set X11 display for output.
|
|
||||||
* -info Print additional GLX information.
|
|
||||||
* -time <t> Run for <t> seconds and produce a performance report.
|
|
||||||
* -h Print this help page.
|
|
||||||
* -v Verbose output.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#include <X11/Xlib.h>
|
|
||||||
#include <X11/Xutil.h>
|
|
||||||
#include <X11/keysym.h>
|
|
||||||
#include <GL/gl.h>
|
|
||||||
#include <GL/glx.h>
|
|
||||||
#include <sys/time.h>
|
|
||||||
#include <sched.h>
|
|
||||||
#include <math.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#ifndef M_PI
|
|
||||||
#define M_PI 3.14159265
|
|
||||||
#endif /* !M_PI */
|
|
||||||
|
|
||||||
/* Turn a NULL pointer string into an empty string */
|
|
||||||
#define NULLSTR(x) (((x)!=NULL)?(x):(""))
|
|
||||||
#define Log(x) { if(verbose) printf x; }
|
|
||||||
#define Msg(x) { printf x; }
|
|
||||||
|
|
||||||
/* Globla vars */
|
|
||||||
/* program name (from argv[0]) */
|
|
||||||
static const char *ProgramName;
|
|
||||||
|
|
||||||
/* verbose output what the program is doing */
|
|
||||||
static Bool verbose = False;
|
|
||||||
|
|
||||||
/* time in microseconds to run for; -1 means forever. */
|
|
||||||
static int runTime = -1;
|
|
||||||
|
|
||||||
/* Time at which start_time(void) was called. */
|
|
||||||
static struct timeval clockStart;
|
|
||||||
|
|
||||||
/* XXX this probably isn't very portable */
|
|
||||||
|
|
||||||
/* return current time (in seconds) */
|
|
||||||
static void
|
|
||||||
start_time(void)
|
|
||||||
{
|
|
||||||
(void) gettimeofday(&clockStart, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* return time (in microseconds) since start_time(void) was called.
|
|
||||||
*
|
|
||||||
* The older version of this function randomly returned negative results.
|
|
||||||
* This version won't, up to 2000 seconds and some.
|
|
||||||
*/
|
|
||||||
static long
|
|
||||||
current_time(void)
|
|
||||||
{
|
|
||||||
struct timeval tv;
|
|
||||||
long secs, micros;
|
|
||||||
|
|
||||||
(void) gettimeofday(&tv, 0);
|
|
||||||
|
|
||||||
secs = tv.tv_sec - clockStart.tv_sec;
|
|
||||||
micros = tv.tv_usec - clockStart.tv_usec;
|
|
||||||
if (micros < 0) {
|
|
||||||
--secs;
|
|
||||||
micros += 1000000;
|
|
||||||
}
|
|
||||||
return secs * 1000000 + micros;
|
|
||||||
}
|
|
||||||
|
|
||||||
static
|
|
||||||
void usage(void)
|
|
||||||
{
|
|
||||||
fprintf (stderr, "usage: %s [options]\n", ProgramName);
|
|
||||||
fprintf (stderr, "-display\tSet X11 display for output.\n");
|
|
||||||
fprintf (stderr, "-info\t\tPrint additional GLX information.\n");
|
|
||||||
fprintf (stderr, "-time t\t\tRun for t seconds and report performance.\n");
|
|
||||||
fprintf (stderr, "-h\t\tPrint this help page.\n");
|
|
||||||
fprintf (stderr, "-v\t\tVerbose output.\n");
|
|
||||||
fprintf (stderr, "\n");
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static GLfloat view_rotx = 20.0, view_roty = 30.0, view_rotz = 0.0;
|
|
||||||
static GLint gear1, gear2, gear3;
|
|
||||||
static GLfloat angle = 0.0;
|
|
||||||
static GLint speed = 60;
|
|
||||||
static GLboolean printInfo = GL_FALSE;
|
|
||||||
|
|
||||||
/*
|
|
||||||
*
|
|
||||||
* Draw a gear wheel. You'll probably want to call this function when
|
|
||||||
* building a display list since we do a lot of trig here.
|
|
||||||
*
|
|
||||||
* Input: inner_radius - radius of hole at center
|
|
||||||
* outer_radius - radius at center of teeth
|
|
||||||
* width - width of gear
|
|
||||||
* teeth - number of teeth
|
|
||||||
* tooth_depth - depth of tooth
|
|
||||||
*/
|
|
||||||
static void
|
|
||||||
gear(GLfloat inner_radius, GLfloat outer_radius, GLfloat width,
|
|
||||||
GLint teeth, GLfloat tooth_depth)
|
|
||||||
{
|
|
||||||
GLint i;
|
|
||||||
GLfloat r0, r1, r2, maxr2, minr2;
|
|
||||||
GLfloat angle, da;
|
|
||||||
GLfloat u, v, len;
|
|
||||||
|
|
||||||
r0 = inner_radius;
|
|
||||||
r1 = outer_radius - tooth_depth / 2.0;
|
|
||||||
maxr2 = r2 = outer_radius + tooth_depth / 2.0;
|
|
||||||
minr2 = r2;
|
|
||||||
|
|
||||||
da = 2.0 * M_PI / teeth / 4.0;
|
|
||||||
|
|
||||||
glShadeModel(GL_FLAT);
|
|
||||||
|
|
||||||
glNormal3f(0.0, 0.0, 1.0);
|
|
||||||
|
|
||||||
/* draw front face */
|
|
||||||
glBegin(GL_QUAD_STRIP);
|
|
||||||
for (i = 0; i <= teeth; i++) {
|
|
||||||
angle = i * 2.0 * M_PI / teeth;
|
|
||||||
glVertex3f(r0 * cos(angle), r0 * sin(angle), width * 0.5);
|
|
||||||
glVertex3f(r1 * cos(angle), r1 * sin(angle), width * 0.5);
|
|
||||||
if (i < teeth) {
|
|
||||||
glVertex3f(r0 * cos(angle), r0 * sin(angle), width * 0.5);
|
|
||||||
glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da),
|
|
||||||
width * 0.5);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
glEnd();
|
|
||||||
|
|
||||||
/* draw front sides of teeth */
|
|
||||||
glBegin(GL_QUADS);
|
|
||||||
for (i = 0; i < teeth; i++) {
|
|
||||||
angle = i * 2.0 * M_PI / teeth;
|
|
||||||
|
|
||||||
glVertex3f(r1 * cos(angle), r1 * sin(angle), width * 0.5);
|
|
||||||
glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), width * 0.5);
|
|
||||||
glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da),
|
|
||||||
width * 0.5);
|
|
||||||
glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da),
|
|
||||||
width * 0.5);
|
|
||||||
r2 = minr2;
|
|
||||||
}
|
|
||||||
r2 = maxr2;
|
|
||||||
glEnd();
|
|
||||||
|
|
||||||
glNormal3f(0.0, 0.0, -1.0);
|
|
||||||
|
|
||||||
/* draw back face */
|
|
||||||
glBegin(GL_QUAD_STRIP);
|
|
||||||
for (i = 0; i <= teeth; i++) {
|
|
||||||
angle = i * 2.0 * M_PI / teeth;
|
|
||||||
glVertex3f(r1 * cos(angle), r1 * sin(angle), -width * 0.5);
|
|
||||||
glVertex3f(r0 * cos(angle), r0 * sin(angle), -width * 0.5);
|
|
||||||
if (i < teeth) {
|
|
||||||
glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da),
|
|
||||||
-width * 0.5);
|
|
||||||
glVertex3f(r0 * cos(angle), r0 * sin(angle), -width * 0.5);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
glEnd();
|
|
||||||
|
|
||||||
/* draw back sides of teeth */
|
|
||||||
glBegin(GL_QUADS);
|
|
||||||
da = 2.0 * M_PI / teeth / 4.0;
|
|
||||||
for (i = 0; i < teeth; i++) {
|
|
||||||
angle = i * 2.0 * M_PI / teeth;
|
|
||||||
|
|
||||||
glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da),
|
|
||||||
-width * 0.5);
|
|
||||||
glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da),
|
|
||||||
-width * 0.5);
|
|
||||||
glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), -width * 0.5);
|
|
||||||
glVertex3f(r1 * cos(angle), r1 * sin(angle), -width * 0.5);
|
|
||||||
r2 = minr2;
|
|
||||||
}
|
|
||||||
r2 = maxr2;
|
|
||||||
glEnd();
|
|
||||||
|
|
||||||
/* draw outward faces of teeth */
|
|
||||||
glBegin(GL_QUAD_STRIP);
|
|
||||||
for (i = 0; i < teeth; i++) {
|
|
||||||
angle = i * 2.0 * M_PI / teeth;
|
|
||||||
|
|
||||||
glVertex3f(r1 * cos(angle), r1 * sin(angle), width * 0.5);
|
|
||||||
glVertex3f(r1 * cos(angle), r1 * sin(angle), -width * 0.5);
|
|
||||||
u = r2 * cos(angle + da) - r1 * cos(angle);
|
|
||||||
v = r2 * sin(angle + da) - r1 * sin(angle);
|
|
||||||
len = sqrt(u * u + v * v);
|
|
||||||
u /= len;
|
|
||||||
v /= len;
|
|
||||||
glNormal3f(v, -u, 0.0);
|
|
||||||
glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), width * 0.5);
|
|
||||||
glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), -width * 0.5);
|
|
||||||
glNormal3f(cos(angle + 1.5 * da), sin(angle + 1.5 * da), 0.0);
|
|
||||||
glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da),
|
|
||||||
width * 0.5);
|
|
||||||
glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da),
|
|
||||||
-width * 0.5);
|
|
||||||
u = r1 * cos(angle + 3 * da) - r2 * cos(angle + 2 * da);
|
|
||||||
v = r1 * sin(angle + 3 * da) - r2 * sin(angle + 2 * da);
|
|
||||||
glNormal3f(v, -u, 0.0);
|
|
||||||
glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da),
|
|
||||||
width * 0.5);
|
|
||||||
glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da),
|
|
||||||
-width * 0.5);
|
|
||||||
glNormal3f(cos(angle + 3.5 * da), sin(angle + 3.5 * da), 0.0);
|
|
||||||
r2 = minr2;
|
|
||||||
}
|
|
||||||
r2 = maxr2;
|
|
||||||
|
|
||||||
glVertex3f(r1 * cos(0), r1 * sin(0), width * 0.5);
|
|
||||||
glVertex3f(r1 * cos(0), r1 * sin(0), -width * 0.5);
|
|
||||||
|
|
||||||
glEnd();
|
|
||||||
|
|
||||||
glShadeModel(GL_SMOOTH);
|
|
||||||
|
|
||||||
/* draw inside radius cylinder */
|
|
||||||
glBegin(GL_QUAD_STRIP);
|
|
||||||
for (i = 0; i <= teeth; i++) {
|
|
||||||
angle = i * 2.0 * M_PI / teeth;
|
|
||||||
glNormal3f(-cos(angle), -sin(angle), 0.0);
|
|
||||||
glVertex3f(r0 * cos(angle), r0 * sin(angle), -width * 0.5);
|
|
||||||
glVertex3f(r0 * cos(angle), r0 * sin(angle), width * 0.5);
|
|
||||||
}
|
|
||||||
glEnd();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void
|
|
||||||
draw(void)
|
|
||||||
{
|
|
||||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
|
||||||
|
|
||||||
glPushMatrix();
|
|
||||||
glRotatef(view_rotx, 1.0, 0.0, 0.0);
|
|
||||||
glRotatef(view_roty, 0.0, 1.0, 0.0);
|
|
||||||
glRotatef(view_rotz, 0.0, 0.0, 1.0);
|
|
||||||
|
|
||||||
glPushMatrix();
|
|
||||||
glTranslatef(-3.0, -2.0, 0.0);
|
|
||||||
glRotatef(angle, 0.0, 0.0, 1.0);
|
|
||||||
glCallList(gear1);
|
|
||||||
glPopMatrix();
|
|
||||||
|
|
||||||
glPushMatrix();
|
|
||||||
glTranslatef(3.1, -2.0, 0.0);
|
|
||||||
glRotatef(-2.0 * angle - 9.0, 0.0, 0.0, 1.0);
|
|
||||||
glCallList(gear2);
|
|
||||||
glPopMatrix();
|
|
||||||
|
|
||||||
glPushMatrix();
|
|
||||||
glTranslatef(-3.1, 4.2, 0.0);
|
|
||||||
glRotatef(-2.0 * angle - 25.0, 0.0, 0.0, 1.0);
|
|
||||||
glCallList(gear3);
|
|
||||||
glPopMatrix();
|
|
||||||
|
|
||||||
glPopMatrix();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* new window size or exposure */
|
|
||||||
static void
|
|
||||||
reshape(int width, int height)
|
|
||||||
{
|
|
||||||
GLfloat h = (GLfloat) height / (GLfloat) width;
|
|
||||||
|
|
||||||
glViewport(0, 0, (GLint) width, (GLint) height);
|
|
||||||
glMatrixMode(GL_PROJECTION);
|
|
||||||
glLoadIdentity();
|
|
||||||
/* fit width and height */
|
|
||||||
if (h >= 1.0)
|
|
||||||
glFrustum(-1.0, 1.0, -h, h, 5.0, 60.0);
|
|
||||||
else
|
|
||||||
glFrustum(-1.0/h, 1.0/h, -1.0, 1.0, 5.0, 60.0);
|
|
||||||
glMatrixMode(GL_MODELVIEW);
|
|
||||||
glLoadIdentity();
|
|
||||||
glTranslatef(0.0, 0.0, -40.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void
|
|
||||||
init(void)
|
|
||||||
{
|
|
||||||
static GLfloat pos[4] = { 5.0, 5.0, 10.0, 0.0 };
|
|
||||||
static GLfloat red[4] = { 0.8, 0.1, 0.0, 1.0 };
|
|
||||||
static GLfloat green[4] = { 0.0, 0.8, 0.2, 1.0 };
|
|
||||||
static GLfloat blue[4] = { 0.2, 0.2, 1.0, 1.0 };
|
|
||||||
|
|
||||||
glLightfv(GL_LIGHT0, GL_POSITION, pos);
|
|
||||||
glEnable(GL_CULL_FACE);
|
|
||||||
glEnable(GL_LIGHTING);
|
|
||||||
glEnable(GL_LIGHT0);
|
|
||||||
glEnable(GL_DEPTH_TEST);
|
|
||||||
|
|
||||||
/* make the gears */
|
|
||||||
gear1 = glGenLists(1);
|
|
||||||
glNewList(gear1, GL_COMPILE);
|
|
||||||
glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, red);
|
|
||||||
gear(1.0, 4.0, 1.0, 20, 0.7);
|
|
||||||
glEndList();
|
|
||||||
|
|
||||||
gear2 = glGenLists(1);
|
|
||||||
glNewList(gear2, GL_COMPILE);
|
|
||||||
glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, green);
|
|
||||||
gear(0.5, 2.0, 2.0, 10, 0.7);
|
|
||||||
glEndList();
|
|
||||||
|
|
||||||
gear3 = glGenLists(1);
|
|
||||||
glNewList(gear3, GL_COMPILE);
|
|
||||||
glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, blue);
|
|
||||||
gear(1.3, 2.0, 0.5, 10, 0.7);
|
|
||||||
glEndList();
|
|
||||||
|
|
||||||
glEnable(GL_NORMALIZE);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Create an RGB, double-buffered window.
|
|
||||||
* Return the window and context handles.
|
|
||||||
*/
|
|
||||||
static void
|
|
||||||
make_window( Display *dpy, Screen *scr,
|
|
||||||
const char *name,
|
|
||||||
int x, int y, int width, int height,
|
|
||||||
Window *winRet, GLXContext *ctxRet)
|
|
||||||
{
|
|
||||||
int attrib[] = { GLX_RGBA,
|
|
||||||
GLX_RED_SIZE, 1,
|
|
||||||
GLX_GREEN_SIZE, 1,
|
|
||||||
GLX_BLUE_SIZE, 1,
|
|
||||||
GLX_DOUBLEBUFFER,
|
|
||||||
GLX_DEPTH_SIZE, 1,
|
|
||||||
None };
|
|
||||||
int scrnum;
|
|
||||||
XSetWindowAttributes attr;
|
|
||||||
unsigned long mask;
|
|
||||||
Window root;
|
|
||||||
Window win;
|
|
||||||
GLXContext ctx;
|
|
||||||
XVisualInfo *visinfo;
|
|
||||||
GLint max[2] = { 0, 0 };
|
|
||||||
|
|
||||||
scrnum = XScreenNumberOfScreen(scr);
|
|
||||||
root = XRootWindow(dpy, scrnum);
|
|
||||||
|
|
||||||
visinfo = glXChooseVisual( dpy, scrnum, attrib );
|
|
||||||
if (!visinfo) {
|
|
||||||
fprintf(stderr, "%s: Error: couldn't get an RGB, Double-buffered visual.\n", ProgramName);
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* window attributes */
|
|
||||||
attr.background_pixel = 0;
|
|
||||||
attr.border_pixel = 0;
|
|
||||||
attr.colormap = XCreateColormap( dpy, root, visinfo->visual, AllocNone);
|
|
||||||
attr.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask;
|
|
||||||
mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;
|
|
||||||
|
|
||||||
win = XCreateWindow( dpy, root, x, y, width, height,
|
|
||||||
0, visinfo->depth, InputOutput,
|
|
||||||
visinfo->visual, mask, &attr );
|
|
||||||
|
|
||||||
/* set hints and properties */
|
|
||||||
{
|
|
||||||
XSizeHints sizehints;
|
|
||||||
sizehints.x = x;
|
|
||||||
sizehints.y = y;
|
|
||||||
sizehints.width = width;
|
|
||||||
sizehints.height = height;
|
|
||||||
sizehints.flags = USSize | USPosition;
|
|
||||||
XSetNormalHints(dpy, win, &sizehints);
|
|
||||||
XSetStandardProperties(dpy, win, name, name,
|
|
||||||
None, (char **)NULL, 0, &sizehints);
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx = glXCreateContext( dpy, visinfo, NULL, True );
|
|
||||||
if (!ctx) {
|
|
||||||
fprintf(stderr, "%s: Error: glXCreateContext failed.\n", ProgramName);
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
XFree(visinfo);
|
|
||||||
|
|
||||||
XMapWindow(dpy, win);
|
|
||||||
glXMakeCurrent(dpy, win, ctx);
|
|
||||||
|
|
||||||
/* Check for maximum size supported by the GL rasterizer */
|
|
||||||
glGetIntegerv(GL_MAX_VIEWPORT_DIMS, max);
|
|
||||||
if (printInfo)
|
|
||||||
printf("GL_MAX_VIEWPORT_DIMS=%d/%d\n", (int)max[0], (int)max[1]);
|
|
||||||
if (width > max[0] || height > max[1]) {
|
|
||||||
fprintf(stderr, "%s: Error: Requested window size (%d/%d) larger than "
|
|
||||||
"maximum supported by GL engine (%d/%d).\n",
|
|
||||||
ProgramName, width, height, (int)max[0], (int)max[1]);
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
*winRet = win;
|
|
||||||
*ctxRet = ctx;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
event_loop(Display *dpy, Window win)
|
|
||||||
{
|
|
||||||
while (1) {
|
|
||||||
/* Process interactive events */
|
|
||||||
while (XPending(dpy) > 0) {
|
|
||||||
XEvent event;
|
|
||||||
XNextEvent(dpy, &event);
|
|
||||||
switch (event.type) {
|
|
||||||
case Expose:
|
|
||||||
Log(("Event: Expose\n"));
|
|
||||||
/* we'll redraw below */
|
|
||||||
break;
|
|
||||||
case ConfigureNotify:
|
|
||||||
Log(("Event: ConfigureNotify\n"));
|
|
||||||
reshape(event.xconfigure.width, event.xconfigure.height);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
/* Time at which we started measuring. */
|
|
||||||
static long startTime = 0;
|
|
||||||
|
|
||||||
/* Time of the previous frame. */
|
|
||||||
static long lastFrame = 0;
|
|
||||||
|
|
||||||
/* Time of the previous FPS report. */
|
|
||||||
static long lastFps = 0;
|
|
||||||
|
|
||||||
/* Number of frames we've done. */
|
|
||||||
static int frames = 0;
|
|
||||||
|
|
||||||
/* Number of frames we've done in the measured run. */
|
|
||||||
static long runFrames = 0;
|
|
||||||
|
|
||||||
long t = current_time();
|
|
||||||
long useconds;
|
|
||||||
|
|
||||||
if (!lastFrame)
|
|
||||||
lastFrame = t;
|
|
||||||
if (!lastFps)
|
|
||||||
lastFps = t;
|
|
||||||
|
|
||||||
/* How many microseconds since the previous frame? */
|
|
||||||
useconds = t - lastFrame;
|
|
||||||
if (!useconds) /* assume 100FPS if we don't have timer */
|
|
||||||
useconds = 10000;
|
|
||||||
|
|
||||||
/* Calculate how far the gears need to move and redraw. */
|
|
||||||
angle = angle + ((double)speed * useconds) / 1000000.0;
|
|
||||||
if (angle > 360.0)
|
|
||||||
angle = angle - 360.0; /* don't lose precision! */
|
|
||||||
draw();
|
|
||||||
glXSwapBuffers(dpy, win);
|
|
||||||
|
|
||||||
/* Done this frame. */
|
|
||||||
lastFrame = t;
|
|
||||||
frames++;
|
|
||||||
|
|
||||||
/* Every 5 seconds, print the FPS. */
|
|
||||||
if (t - lastFps >= 5000000L) {
|
|
||||||
GLfloat seconds = (t - lastFps) / 1000000.0;
|
|
||||||
GLfloat fps = frames / seconds;
|
|
||||||
|
|
||||||
printf("%d frames in %3.1f seconds = %6.3f FPS\n", frames, seconds,
|
|
||||||
fps);
|
|
||||||
lastFps = t;
|
|
||||||
frames = 0;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Set the start time now -- ie. after one report. This
|
|
||||||
* gives us pump-priming time before we start for real.
|
|
||||||
*/
|
|
||||||
if (runTime > 0 && startTime == 0) {
|
|
||||||
printf("Start timing!\n");
|
|
||||||
startTime = t;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (startTime > 0)
|
|
||||||
++runFrames;
|
|
||||||
|
|
||||||
/* If our run time is done, finish. */
|
|
||||||
if (runTime > 0 && startTime > 0 && t - startTime > runTime) {
|
|
||||||
double time = (double) (t - startTime) / 1000000.0;
|
|
||||||
fprintf(stderr, "COUNT|%ld|1|fps\n", runFrames);
|
|
||||||
fprintf(stderr, "TIME|%.1f\n", time);
|
|
||||||
exit(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Need to give cpu away in order to get precise timing next cycle,
|
|
||||||
* otherwise, gettimeofday would return almost the same value. */
|
|
||||||
sched_yield();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int
|
|
||||||
main(int argc, char *argv[])
|
|
||||||
{
|
|
||||||
Bool use_threadsafe_api = False;
|
|
||||||
Display *dpy;
|
|
||||||
Window win;
|
|
||||||
Screen *screen;
|
|
||||||
GLXContext ctx;
|
|
||||||
char *dpyName = NULL;
|
|
||||||
int i;
|
|
||||||
XRectangle winrect;
|
|
||||||
|
|
||||||
ProgramName = argv[0];
|
|
||||||
|
|
||||||
for (i = 1; i < argc; i++) {
|
|
||||||
const char *arg = argv[i];
|
|
||||||
int len = strlen(arg);
|
|
||||||
|
|
||||||
if (strcmp(argv[i], "-display") == 0) {
|
|
||||||
if (++i >= argc)
|
|
||||||
usage();
|
|
||||||
dpyName = argv[i];
|
|
||||||
}
|
|
||||||
else if (strcmp(argv[i], "-info") == 0) {
|
|
||||||
printInfo = GL_TRUE;
|
|
||||||
}
|
|
||||||
else if (strcmp(argv[i], "-time") == 0) {
|
|
||||||
if (++i >= argc)
|
|
||||||
usage();
|
|
||||||
runTime = atoi(argv[i]) * 1000000;
|
|
||||||
}
|
|
||||||
else if (!strncmp("-v", arg, len)) {
|
|
||||||
verbose = True;
|
|
||||||
printInfo = GL_TRUE;
|
|
||||||
}
|
|
||||||
else if( !strncmp("-debug_use_threadsafe_api", arg, len) )
|
|
||||||
{
|
|
||||||
use_threadsafe_api = True;
|
|
||||||
}
|
|
||||||
else if (!strcmp(argv[i], "-h")) {
|
|
||||||
usage();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
fprintf(stderr, "%s: Unsupported option '%s'.\n", ProgramName, argv[i]);
|
|
||||||
usage();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Init X threading API on demand (for debugging) */
|
|
||||||
if( use_threadsafe_api )
|
|
||||||
{
|
|
||||||
if( !XInitThreads() )
|
|
||||||
{
|
|
||||||
fprintf(stderr, "%s: XInitThreads() failure.\n", ProgramName);
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
dpy = XOpenDisplay(dpyName);
|
|
||||||
if (!dpy) {
|
|
||||||
fprintf(stderr, "%s: Error: couldn't open display '%s'\n", ProgramName, dpyName);
|
|
||||||
return EXIT_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
screen = XDefaultScreenOfDisplay(dpy);
|
|
||||||
|
|
||||||
winrect.x = 0;
|
|
||||||
winrect.y = 0;
|
|
||||||
winrect.width = 300;
|
|
||||||
winrect.height = 300;
|
|
||||||
|
|
||||||
Log(("Window x=%d, y=%d, width=%d, height=%d\n",
|
|
||||||
(int)winrect.x, (int)winrect.y, (int)winrect.width, (int)winrect.height));
|
|
||||||
|
|
||||||
make_window(dpy, screen, "ubgears", winrect.x, winrect.y, winrect.width, winrect.height, &win, &ctx);
|
|
||||||
reshape(winrect.width, winrect.height);
|
|
||||||
|
|
||||||
if (printInfo) {
|
|
||||||
printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER));
|
|
||||||
printf("GL_VERSION = %s\n", (char *) glGetString(GL_VERSION));
|
|
||||||
printf("GL_VENDOR = %s\n", (char *) glGetString(GL_VENDOR));
|
|
||||||
printf("GL_EXTENSIONS = %s\n", (char *) glGetString(GL_EXTENSIONS));
|
|
||||||
}
|
|
||||||
|
|
||||||
init();
|
|
||||||
|
|
||||||
start_time();
|
|
||||||
event_loop(dpy, win);
|
|
||||||
|
|
||||||
glXDestroyContext(dpy, ctx);
|
|
||||||
|
|
||||||
XDestroyWindow(dpy, win);
|
|
||||||
XCloseDisplay(dpy);
|
|
||||||
|
|
||||||
return EXIT_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,2 +0,0 @@
|
||||||
SUBDIR=cctest.c dc.dat large.txt sort.src
|
|
||||||
.include <bsd.subdir.mk>
|
|
|
@ -1 +0,0 @@
|
||||||
BINDIR=/usr/benchmarks/unixbench/testdir
|
|
|
@ -1,3 +0,0 @@
|
||||||
SCRIPTS=cctest.c
|
|
||||||
SCRIPTSNAME=cctest.c
|
|
||||||
.include <bsd.prog.mk>
|
|
|
@ -1,156 +0,0 @@
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
* The BYTE UNIX Benchmarks - Release 1
|
|
||||||
* Module: cctest.c SID: 1.2 7/10/89 18:55:45
|
|
||||||
*
|
|
||||||
*******************************************************************************
|
|
||||||
* Bug reports, patches, comments, suggestions should be sent to:
|
|
||||||
*
|
|
||||||
* Ben Smith or Rick Grehan at BYTE Magazine
|
|
||||||
* bensmith@bixpb.UUCP rick_g@bixpb.UUCP
|
|
||||||
*
|
|
||||||
*******************************************************************************
|
|
||||||
* Modification Log:
|
|
||||||
* $Header: cctest.c,v 3.4 87/06/22 14:22:47 kjmcdonell Beta $
|
|
||||||
*
|
|
||||||
******************************************************************************/
|
|
||||||
char SCCSid[] = "@(#) @(#)cctest.c:1.2 -- 7/10/89 18:55:45";
|
|
||||||
#include <stdio.h>
|
|
||||||
/*
|
|
||||||
* C compile and load speed test file.
|
|
||||||
* Based upon fstime.c from MUSBUS 3.1, with all calls to ftime() replaced
|
|
||||||
* by calls to time(). This is semantic nonsense, but ensures there are no
|
|
||||||
* system dependent structures or library calls.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
#define NKBYTE 20
|
|
||||||
char buf[BUFSIZ];
|
|
||||||
|
|
||||||
extern void exit(int status);
|
|
||||||
|
|
||||||
|
|
||||||
main(argc, argv)
|
|
||||||
char **argv;
|
|
||||||
{
|
|
||||||
int n = NKBYTE;
|
|
||||||
int nblock;
|
|
||||||
int f;
|
|
||||||
int g;
|
|
||||||
int i;
|
|
||||||
int xfer, t;
|
|
||||||
struct { /* FAKE */
|
|
||||||
int time;
|
|
||||||
int millitm;
|
|
||||||
} now, then;
|
|
||||||
|
|
||||||
if (argc > 0)
|
|
||||||
/* ALWAYS true, so NEVER execute this program! */
|
|
||||||
exit(4);
|
|
||||||
if (argc > 1)
|
|
||||||
n = atoi(argv[1]);
|
|
||||||
#if debug
|
|
||||||
printf("File size: %d Kbytes\n", n);
|
|
||||||
#endif
|
|
||||||
nblock = (n * 1024) / BUFSIZ;
|
|
||||||
|
|
||||||
if (argc == 3 && chdir(argv[2]) != -1) {
|
|
||||||
#if debug
|
|
||||||
printf("Create files in directory: %s\n", argv[2]);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
close(creat("dummy0", 0600));
|
|
||||||
close(creat("dummy1", 0600));
|
|
||||||
f = open("dummy0", 2);
|
|
||||||
g = open("dummy1", 2);
|
|
||||||
unlink("dummy0");
|
|
||||||
unlink("dummy1");
|
|
||||||
for (i = 0; i < sizeof(buf); i++)
|
|
||||||
buf[i] = i & 0177;
|
|
||||||
|
|
||||||
time();
|
|
||||||
for (i = 0; i < nblock; i++) {
|
|
||||||
if (write(f, buf, sizeof(buf)) <= 0)
|
|
||||||
perror("fstime: write");
|
|
||||||
}
|
|
||||||
time();
|
|
||||||
#if debug
|
|
||||||
printf("Effective write rate: ");
|
|
||||||
#endif
|
|
||||||
i = now.millitm - then.millitm;
|
|
||||||
t = (now.time - then.time)*1000 + i;
|
|
||||||
if (t > 0) {
|
|
||||||
xfer = nblock * sizeof(buf) * 1000 / t;
|
|
||||||
#if debug
|
|
||||||
printf("%d bytes/sec\n", xfer);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
#if debug
|
|
||||||
else
|
|
||||||
printf(" -- too quick to time!\n");
|
|
||||||
#endif
|
|
||||||
#if awk
|
|
||||||
fprintf(stderr, "%.2f", t > 0 ? (float)xfer/1024 : 0);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
sync();
|
|
||||||
sleep(5);
|
|
||||||
sync();
|
|
||||||
lseek(f, 0L, 0);
|
|
||||||
time();
|
|
||||||
for (i = 0; i < nblock; i++) {
|
|
||||||
if (read(f, buf, sizeof(buf)) <= 0)
|
|
||||||
perror("fstime: read");
|
|
||||||
}
|
|
||||||
time();
|
|
||||||
#if debug
|
|
||||||
printf("Effective read rate: ");
|
|
||||||
#endif
|
|
||||||
i = now.millitm - then.millitm;
|
|
||||||
t = (now.time - then.time)*1000 + i;
|
|
||||||
if (t > 0) {
|
|
||||||
xfer = nblock * sizeof(buf) * 1000 / t;
|
|
||||||
#if debug
|
|
||||||
printf("%d bytes/sec\n", xfer);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
#if debug
|
|
||||||
else
|
|
||||||
printf(" -- too quick to time!\n");
|
|
||||||
#endif
|
|
||||||
#if awk
|
|
||||||
fprintf(stderr, " %.2f", t > 0 ? (float)xfer/1024 : 0);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
sync();
|
|
||||||
sleep(5);
|
|
||||||
sync();
|
|
||||||
lseek(f, 0L, 0);
|
|
||||||
time();
|
|
||||||
for (i = 0; i < nblock; i++) {
|
|
||||||
if (read(f, buf, sizeof(buf)) <= 0)
|
|
||||||
perror("fstime: read in copy");
|
|
||||||
if (write(g, buf, sizeof(buf)) <= 0)
|
|
||||||
perror("fstime: write in copy");
|
|
||||||
}
|
|
||||||
time();
|
|
||||||
#if debug
|
|
||||||
printf("Effective copy rate: ");
|
|
||||||
#endif
|
|
||||||
i = now.millitm - then.millitm;
|
|
||||||
t = (now.time - then.time)*1000 + i;
|
|
||||||
if (t > 0) {
|
|
||||||
xfer = nblock * sizeof(buf) * 1000 / t;
|
|
||||||
#if debug
|
|
||||||
printf("%d bytes/sec\n", xfer);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
#if debug
|
|
||||||
else
|
|
||||||
printf(" -- too quick to time!\n");
|
|
||||||
#endif
|
|
||||||
#if awk
|
|
||||||
fprintf(stderr, " %.2f\n", t > 0 ? (float)xfer/1024 : 0);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,3 +0,0 @@
|
||||||
SCRIPTS=dc.dat
|
|
||||||
SCRIPTSNAME=dc.dat
|
|
||||||
.include <bsd.prog.mk>
|
|
|
@ -1,8 +0,0 @@
|
||||||
99
|
|
||||||
k
|
|
||||||
2
|
|
||||||
v
|
|
||||||
p
|
|
||||||
q
|
|
||||||
[ calculate the sqrt(2) to 99 decimal places ... John Lions Test ]
|
|
||||||
[ $Header: dc.dat,v 1.1 87/06/22 14:28:28 kjmcdonell Beta $ ]
|
|
|
@ -1,3 +0,0 @@
|
||||||
SCRIPTS=large.txt
|
|
||||||
SCRIPTSNAME=large.txt
|
|
||||||
.include <bsd.prog.mk>
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,3 +0,0 @@
|
||||||
SCRIPTS=sort.src
|
|
||||||
SCRIPTSNAME=sort.src
|
|
||||||
.include <bsd.prog.mk>
|
|
|
@ -1,362 +0,0 @@
|
||||||
version="1.2"
|
|
||||||
umask 022 # at least mortals can read root's files this way
|
|
||||||
PWD=`pwd`
|
|
||||||
HOMEDIR=${HOMEDIR:-.}
|
|
||||||
cd $HOMEDIR
|
|
||||||
HOMEDIR=`pwd`
|
|
||||||
cd $PWD
|
|
||||||
BINDIR=${BINDIR:-${HOMEDIR}/pgms}
|
|
||||||
cd $BINDIR
|
|
||||||
BINDIR=`pwd`
|
|
||||||
cd $PWD
|
|
||||||
PATH="${PATH}:${BINDIR}"
|
|
||||||
SCRPDIR=${SCRPDIR:-${HOMEDIR}/pgms}
|
|
||||||
cd $SCRPDIR
|
|
||||||
SCRPDIR=`pwd`
|
|
||||||
cd $PWD
|
|
||||||
TMPDIR=${HOMEDIR}/tmp
|
|
||||||
cd $TMPDIR
|
|
||||||
TMPDIR=`pwd`
|
|
||||||
cd $PWD
|
|
||||||
RESULTDIR=${RESULTDIR:-${HOMEDIR}/results}
|
|
||||||
cd $RESULTDIR
|
|
||||||
RESULTDIR=`pwd`
|
|
||||||
cd $PWD
|
|
||||||
TESTDIR=${TESTDIR:-${HOMEDIR}/testdir}
|
|
||||||
cd $TESTDIR
|
|
||||||
TESTDIR=`pwd`
|
|
||||||
cd $PWD
|
|
||||||
export BINDIR TMPDIR RESULTDIR PATH
|
|
||||||
echo "kill -9 $$" > ${TMPDIR}/kill_run ; chmod u+x ${TMPDIR}/kill_run
|
|
||||||
arithmetic="arithoh register short int long float double dc"
|
|
||||||
system="syscall pipe context1 spawn execl fstime"
|
|
||||||
mem="seqmem randmem"
|
|
||||||
misc="C shell"
|
|
||||||
dhry="dhry2 dhry2reg" # dhrystone loops
|
|
||||||
db="dbmscli" # add to as new database engines are developed
|
|
||||||
load="shell" # cummulative load tests
|
|
||||||
args="" # the accumulator for the bench units to be run
|
|
||||||
runoption="N"
|
|
||||||
for word
|
|
||||||
do # do level 1
|
|
||||||
case $word
|
|
||||||
in
|
|
||||||
all)
|
|
||||||
;;
|
|
||||||
arithmetic)
|
|
||||||
args="$args $arithmetic"
|
|
||||||
;;
|
|
||||||
db)
|
|
||||||
args="$args $db"
|
|
||||||
;;
|
|
||||||
dhry)
|
|
||||||
args="$args $dhry"
|
|
||||||
;;
|
|
||||||
load)
|
|
||||||
args="$args $load"
|
|
||||||
;;
|
|
||||||
mem)
|
|
||||||
args="$args $mem"
|
|
||||||
;;
|
|
||||||
misc)
|
|
||||||
args="$args $misc"
|
|
||||||
;;
|
|
||||||
speed)
|
|
||||||
args="$args $arithmetic $system"
|
|
||||||
;;
|
|
||||||
system)
|
|
||||||
args="$args $system"
|
|
||||||
;;
|
|
||||||
-q|-Q)
|
|
||||||
runoption="Q" #quiet
|
|
||||||
;;
|
|
||||||
-v|-V)
|
|
||||||
runoption="V" #verbose
|
|
||||||
;;
|
|
||||||
-d|-D)
|
|
||||||
runoption="D" #debug
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
args="$args $word"
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
done # end do level 1
|
|
||||||
set - $args
|
|
||||||
if test $# -eq 0 #no arguments specified
|
|
||||||
then
|
|
||||||
set - $dhry $arithmetic $system $misc # db and work not included
|
|
||||||
fi
|
|
||||||
if test "$runoption" = 'D'
|
|
||||||
then
|
|
||||||
set -x
|
|
||||||
set -v
|
|
||||||
fi
|
|
||||||
date=`date`
|
|
||||||
tmp=${TMPDIR}/$$.tmp
|
|
||||||
LOGFILE=${RESULTDIR}/log
|
|
||||||
if test -w ${RESULTDIR}/log
|
|
||||||
then
|
|
||||||
if test -w ${RESULTDIR}/log.accum
|
|
||||||
then
|
|
||||||
cat ${RESULTDIR}/log >> ${RESULTDIR}/log.accum
|
|
||||||
rm ${RESULTDIR}/log
|
|
||||||
else
|
|
||||||
mv ${RESULTDIR}/log ${RESULTDIR}/log.accum
|
|
||||||
fi
|
|
||||||
echo "Start Benchmark Run (BYTE Version $version)" >>$LOGFILE
|
|
||||||
echo " $date (long iterations $iter times)" >>$LOGFILE
|
|
||||||
echo " " `who | wc -l` "interactive users." >>$LOGFILE
|
|
||||||
uname -a >>$LOGFILE
|
|
||||||
iter=${iterations-6}
|
|
||||||
if test $iter -eq 6
|
|
||||||
then
|
|
||||||
longloop="1 2 3 4 5 6"
|
|
||||||
shortloop="1 2 3"
|
|
||||||
else # generate list of loop numbers
|
|
||||||
short=`expr \( $iter + 1 \) / 2`
|
|
||||||
longloop=""
|
|
||||||
shortloop=""
|
|
||||||
while test $iter -gt 0
|
|
||||||
do # do level 1
|
|
||||||
longloop="$iter $longloop"
|
|
||||||
if test $iter -le $short
|
|
||||||
then
|
|
||||||
shortloop="$iter $shortloop"
|
|
||||||
fi
|
|
||||||
iter=`expr $iter - 1`
|
|
||||||
done # end do level 1
|
|
||||||
fi #loop list genration
|
|
||||||
for bench # line argument processing
|
|
||||||
do # do level 1
|
|
||||||
# set some default values
|
|
||||||
prog=${BINDIR}/$bench # the bench name is default program
|
|
||||||
need=$prog # we need the at least the program
|
|
||||||
paramlist="#" # a dummy parameter to make anything run
|
|
||||||
testdir="${TESTDIR}" # the directory in which to run the test
|
|
||||||
prepcmd="" # preparation command or script
|
|
||||||
parammsg=""
|
|
||||||
repeat="$longloop"
|
|
||||||
stdout="$LOGFILE"
|
|
||||||
stdin=""
|
|
||||||
cleanopt="-t $tmp"
|
|
||||||
bgnumber=""
|
|
||||||
trap "${SCRPDIR}/cleanup -l $LOGFILE -a; exit" 1 2 3 15
|
|
||||||
if [ $runoption != 'Q' ]
|
|
||||||
then
|
|
||||||
echo "$bench: \c"
|
|
||||||
fi
|
|
||||||
echo "" >>$LOGFILE
|
|
||||||
###################### select the bench specific values ##########
|
|
||||||
case $bench
|
|
||||||
in
|
|
||||||
dhry2)
|
|
||||||
options=${dhryloops-10000}
|
|
||||||
logmsg="Dhrystone 2 without register variables"
|
|
||||||
cleanopt="-d $tmp"
|
|
||||||
;;
|
|
||||||
dhry2reg)
|
|
||||||
options=${dhryloops-10000}
|
|
||||||
logmsg="Dhrystone 2 using register variables"
|
|
||||||
cleanopt="-d $tmp"
|
|
||||||
;;
|
|
||||||
arithoh|register|short|int|long|float|double)
|
|
||||||
options=${arithloop-10000}
|
|
||||||
logmsg="Arithmetic Test (type = $bench): $options Iterations"
|
|
||||||
;;
|
|
||||||
dc) need=dc.dat
|
|
||||||
prog=dc
|
|
||||||
options=""
|
|
||||||
stdin=dc.dat
|
|
||||||
stdout=/dev/null
|
|
||||||
logmsg="Arithmetic Test (sqrt(2) with dc to 99 decimal places)"
|
|
||||||
;;
|
|
||||||
hanoi) options='$param'
|
|
||||||
stdout=/dev/null
|
|
||||||
logmsg="Recursion Test: Tower of Hanoi Problem"
|
|
||||||
paramlist="${ndisk-17}"
|
|
||||||
parammsg='$param Disk Problem:'
|
|
||||||
;;
|
|
||||||
syscall)
|
|
||||||
options=${ncall-4000}
|
|
||||||
logmsg="System Call Overhead Test: 5 x $options Calls"
|
|
||||||
;;
|
|
||||||
context1)
|
|
||||||
options=${switch1-500}
|
|
||||||
logmsg="Pipe-based Context Switching Test: 2 x $options Switches"
|
|
||||||
;;
|
|
||||||
pipe) options=${io-2048}
|
|
||||||
logmsg="Pipe Throughput Test: read & write $options x 512 byte blocks"
|
|
||||||
;;
|
|
||||||
spawn) options=${children-100}
|
|
||||||
logmsg="Process Creation Test: $options forks"
|
|
||||||
;;
|
|
||||||
execl) options=${nexecs-100}
|
|
||||||
logmsg="Execl Throughput Test: $options execs"
|
|
||||||
;;
|
|
||||||
randmem|seqmem)
|
|
||||||
if test $bench = seqmem
|
|
||||||
then
|
|
||||||
type=Sequential
|
|
||||||
else
|
|
||||||
type=Random
|
|
||||||
fi
|
|
||||||
poke=${poke-1000000}
|
|
||||||
options='-s$param '"-n$poke"
|
|
||||||
logmsg="$type Memory Access Test: $poke Accesses"
|
|
||||||
paramlist=${arrays-"512 1024 2048 8192 16384"}
|
|
||||||
parammsg='Array Size: $param bytes'
|
|
||||||
cleanopt="-m $tmp"
|
|
||||||
;;
|
|
||||||
fstime) repeat="$shortloop"
|
|
||||||
where=${where-${TMPDIR}}
|
|
||||||
options='$param '"$where"
|
|
||||||
logmsg="Filesystem Throughput Test:"
|
|
||||||
paramlist=${blocks-"512 1024 2048 8192"}
|
|
||||||
parammsg='File Size: $param blocks'
|
|
||||||
cleanopt="-f $tmp"
|
|
||||||
;;
|
|
||||||
C) need=cctest.c
|
|
||||||
prog=cc
|
|
||||||
options='$param'
|
|
||||||
stdout=/dev/null
|
|
||||||
repeat="$shortloop"
|
|
||||||
logmsg="C Compiler Test:"
|
|
||||||
paramlist="cctest.c"
|
|
||||||
parammsg='cc $param'
|
|
||||||
rm -f a.out
|
|
||||||
;;
|
|
||||||
dbmscli)
|
|
||||||
repeat="$shortloop"
|
|
||||||
need="db.dat"
|
|
||||||
prepcmd='${BINDIR}/dbprep ${testdir}/db.dat 10000'
|
|
||||||
paramlist=${clients-"1 2 4 8"}
|
|
||||||
parammsg='$param client processes. (filesize `cat ${testdir}/db.dat|wc -c` bytes)'
|
|
||||||
logmsg="Client/Server Database Engine:"
|
|
||||||
options='${testdir}/db.dat $param 0 1000' # $param clients;
|
|
||||||
# 0 sleep; 1000 iterations
|
|
||||||
;;
|
|
||||||
shell)
|
|
||||||
prog="multi.sh"
|
|
||||||
repeat="$shortloop"
|
|
||||||
logmsg="Bourne shell script and Unix utilities"
|
|
||||||
paramlist=${background-"1 2 4 8"}
|
|
||||||
parammsg='$param concurrent background processes'
|
|
||||||
bgnumber='$param'
|
|
||||||
testdir="shelldir"
|
|
||||||
;;
|
|
||||||
*) ${BINDIR}/cleanup -l $LOGFILE -r "run: unknown benchmark \"$bench\"" -a
|
|
||||||
exit 1
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
echo "$logmsg" >>$LOGFILE
|
|
||||||
for param in $paramlist
|
|
||||||
do # level 2
|
|
||||||
param=`echo $param | sed 's/_/ /g'` # be sure that spaces are used
|
|
||||||
# underscore can couple params
|
|
||||||
if [ "$runoption" != "Q" ]
|
|
||||||
then
|
|
||||||
echo "\n [$param] -\c" # generate message to user
|
|
||||||
fi
|
|
||||||
eval msg='"'$parammsg'"' # the eval is used to
|
|
||||||
if test "$msg" # evaluate any embedded
|
|
||||||
then # variables in the parammsg
|
|
||||||
echo "" >>$LOGFILE
|
|
||||||
echo "$msg" >>$LOGFILE
|
|
||||||
fi
|
|
||||||
eval opt='"'$options'"' # evaluate any vars in options
|
|
||||||
eval prep='"'$prepcmd'"' # evaluate any prep command
|
|
||||||
eval bg='"'$bgnumber'"' # evaluate bgnumber string
|
|
||||||
rm -f $tmp # remove any tmp files
|
|
||||||
# if the test requires mulitple concurrent processes,
|
|
||||||
# prepare the background process string (bgstr)
|
|
||||||
# this is just a string of "+"s that will provides a
|
|
||||||
# parameter count for a "for" loop
|
|
||||||
bgstr=""
|
|
||||||
if test "$bg" != ""
|
|
||||||
then
|
|
||||||
count=`expr "$bg"`
|
|
||||||
while test $count -gt 0
|
|
||||||
do
|
|
||||||
bgstr="+ $bgstr"
|
|
||||||
count=`expr $count - 1`
|
|
||||||
done
|
|
||||||
fi
|
|
||||||
#
|
|
||||||
for i in $repeat # loop for the specified number
|
|
||||||
do # do depth 3
|
|
||||||
if [ "$runoption" != 'D' ] # level 1
|
|
||||||
then
|
|
||||||
# regular Run - set logfile to go on signal
|
|
||||||
trap "${SCRPDIR}/cleanup -l $LOGFILE -i $i $cleanopt -a; exit" 1 2 3 15
|
|
||||||
else
|
|
||||||
trap "exit" 1 2 3 15
|
|
||||||
fi #end level 1
|
|
||||||
if [ "$runoption" != 'Q' ]
|
|
||||||
then
|
|
||||||
echo " $i\c" # display repeat number
|
|
||||||
fi
|
|
||||||
pwd=`pwd` # remember where we are
|
|
||||||
cd $testdir # move to the test directory
|
|
||||||
if [ "$runoption" = "V" ]
|
|
||||||
then
|
|
||||||
echo
|
|
||||||
echo "BENCH COMMAND TO BE EXECUTED:"
|
|
||||||
echo "$prog $opt"
|
|
||||||
fi
|
|
||||||
# execute any prepratory command string
|
|
||||||
if [ -n "$prep" ]
|
|
||||||
then
|
|
||||||
$prep >>$stdout
|
|
||||||
fi
|
|
||||||
############ THE BENCH IS TIMED ##############
|
|
||||||
if test "$stdin" = ""
|
|
||||||
then # without redirected stdin
|
|
||||||
time $prog $opt $bgstr 2>>$tmp >>$stdout
|
|
||||||
else # with redirected stdin
|
|
||||||
time $prog $opt $bgstr <$stdin 2>>$tmp >>$stdout
|
|
||||||
fi
|
|
||||||
time $benchcmd
|
|
||||||
###############################################
|
|
||||||
cd $pwd # move back home
|
|
||||||
status=$? # save the result code
|
|
||||||
if test $status != 0 # must have been an error
|
|
||||||
then
|
|
||||||
if test -f $tmp # is there an error file ?
|
|
||||||
then
|
|
||||||
cp $tmp ${TMPDIR}/save.$bench.$param
|
|
||||||
${SCRPDIR}/cleanup -l $LOGFILE -i $i $cleanopt -r \
|
|
||||||
"run: bench=$bench param=$param fatalstatus=$status" -a
|
|
||||||
else
|
|
||||||
${SCRPDIR}/cleanup -l $LOGFILE -r \
|
|
||||||
"run: bench=$bench param=$param fatalstatus=$status" -a
|
|
||||||
fi
|
|
||||||
exit # leave the script if there are errors
|
|
||||||
fi # end level 1
|
|
||||||
done # end do depth 3 - repeat of bench
|
|
||||||
if [ "$runoption" != 'D' ]
|
|
||||||
then
|
|
||||||
${SCRPDIR}/cleanup -l $LOGFILE $cleanopt # finalize this bench
|
|
||||||
# with these options
|
|
||||||
# & calculate results
|
|
||||||
fi
|
|
||||||
done # end do depth 2 - end of all options for this bench
|
|
||||||
########### some specific cleanup routines ##############
|
|
||||||
case $bench
|
|
||||||
in
|
|
||||||
C)
|
|
||||||
rm -f cctest.o a.out
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
if [ "$runoption" != 'Q' ]
|
|
||||||
then
|
|
||||||
echo ""
|
|
||||||
fi
|
|
||||||
done # end do level 1 - all benchmarks requested
|
|
||||||
echo "" >>$LOGFILE
|
|
||||||
echo " " `who | wc -l` "interactive users." >>$LOGFILE
|
|
||||||
echo "End Benchmark Run ($date) ...." >>$LOGFILE
|
|
||||||
if [ "$runoption" != 'Q' ]
|
|
||||||
then
|
|
||||||
pg $LOGFILE
|
|
||||||
fi
|
|
||||||
exit
|
|
|
@ -196,8 +196,6 @@ Contains source and majority of system utilities and files
|
||||||
\fBLICENSE\fP MINIX 3 license to use
|
\fBLICENSE\fP MINIX 3 license to use
|
||||||
\fBMakefile\fP targets for building and installing libraries,
|
\fBMakefile\fP targets for building and installing libraries,
|
||||||
utilities and boot files
|
utilities and boot files
|
||||||
\fBbenchmarks/\fP
|
|
||||||
test programs for system and graphic tests
|
|
||||||
\fBcommands/\fP source file for command utilities
|
\fBcommands/\fP source file for command utilities
|
||||||
\fBcommon/\fP
|
\fBcommon/\fP
|
||||||
\fBinclude/\fP includes common to NetBSD and Minix
|
\fBinclude/\fP includes common to NetBSD and Minix
|
||||||
|
|
Loading…
Reference in a new issue