Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
110a025b22 |
84
LICENSE
Normal file → Executable file
84
LICENSE
Normal file → Executable file
@@ -1,62 +1,32 @@
|
||||
Copyright (c) 1987,1997,2001 Prentice Hall
|
||||
All rights reserved.
|
||||
|
||||
License
|
||||
Redistribution and use of the MINIX operating system in source and
|
||||
binary forms, with or without modification, are permitted provided
|
||||
that the following conditions are met:
|
||||
|
||||
Copyright (c) 1987, 1997, 2006, Vrije Universiteit, Amsterdam,
|
||||
The Netherlands All rights reserved. Redistribution and use of the MINIX 3
|
||||
operating system in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following
|
||||
disclaimer in the documentation and/or other materials provided
|
||||
with the distribution.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
* Neither the name of the Vrije Universiteit nor the names of the
|
||||
software authors or contributors may be used to endorse or promote
|
||||
products derived from this software without specific prior written
|
||||
permission.
|
||||
|
||||
* Any deviations from these conditions require written permission
|
||||
from the copyright holder in advance
|
||||
|
||||
|
||||
Disclaimer
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS, AUTHORS, AND
|
||||
CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
|
||||
NO EVENT SHALL PRENTICE HALL OR ANY AUTHORS OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
|
||||
Aggregated Software
|
||||
|
||||
In addition to MINIX 3 itself, the distribution CD-ROM and this Website
|
||||
contain additional software that is not part of MINIX 3 and is not
|
||||
covered by this license. The licensing conditions for this additional
|
||||
software are stated in the various packages. In particular, some of the
|
||||
additional software falls under the GPL, and you must take care to
|
||||
observe the conditions of the GPL with respect to this software. As
|
||||
clearly stated in Article 2 of the GPL, when GPL and nonGPL software are
|
||||
distributed together on the same medium, this aggregation does not cause
|
||||
the license of either part to apply to the other part.
|
||||
|
||||
|
||||
Acknowledgements
|
||||
|
||||
This product includes software developed by the University of
|
||||
California, Berkeley and its contributors.
|
||||
|
||||
This product includes software developed by Softweyr LLC, the
|
||||
University of California, Berkeley, and its contributors.
|
||||
* Neither the name of Prentice Hall nor the names of the software
|
||||
authors or contributors may be used to endorse or promote
|
||||
products derived from this software without specific prior
|
||||
written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS, AUTHORS, AND
|
||||
CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
IN NO EVENT SHALL PRENTICE HALL OR ANY AUTHORS OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
129
Makefile
Normal file → Executable file
129
Makefile
Normal file → Executable file
@@ -1,26 +1,23 @@
|
||||
# Master Makefile to compile everything in /usr/src except the system.
|
||||
|
||||
MAKE=make
|
||||
MAKE = exec make -$(MAKEFLAGS)
|
||||
|
||||
usage:
|
||||
@echo ""
|
||||
@echo "Master Makefile for MINIX commands and utilities."
|
||||
@echo "Root privileges are required for some actions."
|
||||
@echo ""
|
||||
@echo "Usage:"
|
||||
@echo " make world # Compile everything (libraries & commands)"
|
||||
@echo " make includes # Install include files from src/"
|
||||
@echo " make libraries # Compile and install libraries"
|
||||
@echo " make commands # Compile all, commands, but don't install"
|
||||
@echo " make install # Compile and install commands"
|
||||
@echo " make depend # Generate required .depend files"
|
||||
@echo " make gnu-includes # Install include files for GCC"
|
||||
@echo " make gnu-libraries # Compile and install libraries for GCC"
|
||||
@echo " make clang-libraries # Compile and install libraries for GCC with clang"
|
||||
@echo " make clean # Remove all compiler results"
|
||||
@echo ""
|
||||
@echo "Run 'make' in tools/ to create a new MINIX configuration."
|
||||
@echo ""
|
||||
@echo "" >&2
|
||||
@echo "Master Makefile for MINIX commands and utilities." >&2
|
||||
@echo "Root privileges are required for some actions." >&2
|
||||
@echo "" >&2
|
||||
@echo "Usage:" >&2
|
||||
@echo " make world # Compile everything (libraries & commands)" >&2
|
||||
@echo " make includes # Install include files from src/" >&2
|
||||
@echo " make libraries # Compile and install libraries" >&2
|
||||
@echo " make cmds # Compile all, commands, but don't install" >&2
|
||||
@echo " make install # Compile and install commands" >&2
|
||||
@echo " make depend # Generate required .depend files" >&2
|
||||
@echo " make clean # Remove all compiler results" >&2
|
||||
@echo "" >&2
|
||||
@echo "Run 'make' in tools/ to create a new MINIX configuration." >&2; exit 0
|
||||
@echo "" >&2
|
||||
|
||||
# world has to be able to make a new system, even if there
|
||||
# is no complete old system. it has to install commands, for which
|
||||
@@ -30,73 +27,45 @@ usage:
|
||||
# 'make install' target.
|
||||
#
|
||||
# etcfiles has to be done first.
|
||||
.if ${COMPILER_TYPE} == "ack"
|
||||
world: mkfiles includes depend libraries install etcforce
|
||||
.elif ${COMPILER_TYPE} == "gnu"
|
||||
world: mkfiles includes depend gnu-libraries install etcforce
|
||||
.endif
|
||||
|
||||
mkfiles:
|
||||
make -C share/mk install
|
||||
world: includes depend libraries cmds install postinstall
|
||||
|
||||
includes:
|
||||
$(MAKE) -C include includes
|
||||
$(MAKE) -C lib includes
|
||||
cd include && $(MAKE) install
|
||||
|
||||
libraries: includes
|
||||
$(MAKE) -C lib build_ack
|
||||
libraries:
|
||||
cd lib && $(MAKE) install
|
||||
|
||||
MKHEADERS411=/usr/gnu/libexec/gcc/i386-pc-minix/4.1.1/install-tools/mkheaders
|
||||
MKHEADERS443=/usr/gnu/libexec/gcc/i686-pc-minix/4.4.3/install-tools/mkheaders
|
||||
MKHEADERS443_PKGSRC=/usr/pkg/gcc44/libexec/gcc/i686-pc-minix/4.4.3/install-tools/mkheaders
|
||||
gnu-includes: includes
|
||||
SHELL=/bin/sh; if [ -f $(MKHEADERS411) ] ; then sh -e $(MKHEADERS411) ; fi
|
||||
SHELL=/bin/sh; if [ -f $(MKHEADERS443) ] ; then sh -e $(MKHEADERS443) ; fi
|
||||
SHELL=/bin/sh; if [ -f $(MKHEADERS443_PKGSRC) ] ; then sh -e $(MKHEADERS443_PKGSRC) ; fi
|
||||
|
||||
gnu-libraries: gnu-includes
|
||||
$(MAKE) -C lib build_gnu
|
||||
|
||||
clang-libraries: includes
|
||||
$(MAKE) -C lib build_clang
|
||||
|
||||
commands: includes libraries
|
||||
$(MAKE) -C commands all
|
||||
|
||||
depend::
|
||||
$(MAKE) -C boot depend
|
||||
$(MAKE) -C commands depend
|
||||
$(MAKE) -C kernel depend
|
||||
$(MAKE) -C servers depend
|
||||
$(MAKE) -C drivers depend
|
||||
|
||||
etcfiles::
|
||||
$(MAKE) -C etc install
|
||||
|
||||
etcforce::
|
||||
$(MAKE) -C etc installforce
|
||||
|
||||
all::
|
||||
$(MAKE) -C boot all
|
||||
$(MAKE) -C commands all
|
||||
$(MAKE) -C tools all
|
||||
cmds:
|
||||
if [ -f commands/Makefile ] ; then cd commands && $(MAKE) all; fi
|
||||
|
||||
install::
|
||||
$(MAKE) -C boot install
|
||||
$(MAKE) -C man install makedb
|
||||
$(MAKE) -C commands install
|
||||
$(MAKE) -C share install
|
||||
$(MAKE) -C tools install
|
||||
if [ -f commands/Makefile ] ; then cd commands && $(MAKE) install; fi
|
||||
|
||||
depend::
|
||||
mkdep kernel
|
||||
mkdep servers
|
||||
mkdep drivers
|
||||
cd kernel && $(MAKE) $@
|
||||
cd servers && $(MAKE) $@
|
||||
cd drivers && $(MAKE) $@
|
||||
|
||||
|
||||
clean::
|
||||
$(MAKE) -C boot clean
|
||||
$(MAKE) -C commands clean
|
||||
$(MAKE) -C tools clean
|
||||
$(MAKE) -C lib clean_gnu
|
||||
$(MAKE) -C lib clean_ack
|
||||
$(MAKE) -C test clean
|
||||
cd lib && $(MAKE) $@
|
||||
test ! -f commands/Makefile || { cd commands && $(MAKE) $@; }
|
||||
|
||||
cleandepend::
|
||||
$(MAKE) -C boot cleandepend
|
||||
$(MAKE) -C commands cleandepend
|
||||
$(MAKE) -C tools cleandepend
|
||||
etcfiles::
|
||||
cd etc && $(MAKE) install
|
||||
|
||||
clean::
|
||||
cd test && $(MAKE) $@
|
||||
|
||||
all install clean::
|
||||
cd boot && $(MAKE) $@
|
||||
cd man && $(MAKE) $@ # First manpages, then commands
|
||||
test ! -f commands/Makefile || { cd commands && $(MAKE) $@; }
|
||||
cd tools && $(MAKE) $@
|
||||
cd servers && $(MAKE) $@
|
||||
|
||||
postinstall:
|
||||
cd etc && $(MAKE) $@
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
# Makefile for the benchmarks.
|
||||
|
||||
all::
|
||||
chmod 755 run
|
||||
|
||||
all clean::
|
||||
for b in *bench*; do cd $$b && $(MAKE) $@; done
|
||||
@@ -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,246 +0,0 @@
|
||||
##############################################################################
|
||||
# UnixBench v5.1.1
|
||||
# Based on The BYTE UNIX Benchmarks - Release 3
|
||||
# Module: Makefile SID: 3.9 5/15/91 19:30:15
|
||||
#
|
||||
##############################################################################
|
||||
# Bug reports, patches, comments, suggestions should be sent to:
|
||||
# David C Niemi <niemi@tux.org>
|
||||
#
|
||||
# Original Contacts at Byte Magazine:
|
||||
# Ben Smith or Tom Yager at BYTE Magazine
|
||||
# bensmith@bytepb.byte.com tyager@bytepb.byte.com
|
||||
#
|
||||
##############################################################################
|
||||
# Modification Log: 7/28/89 cleaned out workload files
|
||||
# 4/17/90 added routines for installing from shar mess
|
||||
# 7/23/90 added compile for dhrystone version 2.1
|
||||
# (this is not part of Run file. still use old)
|
||||
# removed HZ from everything but dhry.
|
||||
# HZ is read from the environment, if not
|
||||
# there, you must define it in this file
|
||||
# 10/30/90 moved new dhrystone into standard set
|
||||
# new pgms (dhry included) run for a specified
|
||||
# time rather than specified number of loops
|
||||
# 4/5/91 cleaned out files not needed for
|
||||
# release 3 -- added release 3 files -ben
|
||||
# 10/22/97 added compiler options for strict ANSI C
|
||||
# checking for gcc and DEC's cc on
|
||||
# Digital Unix 4.x (kahn@zk3.dec.com)
|
||||
# 09/26/07 changes for UnixBench 5.0
|
||||
# 09/30/07 adding ubgears, GRAPHIC_TESTS switch
|
||||
# 10/14/07 adding large.txt
|
||||
##############################################################################
|
||||
|
||||
##############################################################################
|
||||
# CONFIGURATION
|
||||
##############################################################################
|
||||
|
||||
SHELL = /bin/sh
|
||||
|
||||
# GRAPHICS TESTS: Uncomment the definition of "GRAPHIC_TESTS" to enable
|
||||
# the building of the graphics benchmarks. This will require the
|
||||
# X11 libraries on your system.
|
||||
#
|
||||
# Comment the line out to disable these tests.
|
||||
# GRAPHIC_TESTS = defined
|
||||
|
||||
# Set "GL_LIBS" to the libraries needed to link a GL program.
|
||||
GL_LIBS = -lGL -lXext -lX11
|
||||
|
||||
# OPTIMISATION SETTINGS:
|
||||
|
||||
## Very generic
|
||||
OPTON = -O
|
||||
|
||||
## For Linux 486/Pentium, GCC 2.7.x and 2.8.x
|
||||
#OPTON = -O2 -fomit-frame-pointer -fforce-addr -fforce-mem -ffast-math \
|
||||
# -m486 -malign-loops=2 -malign-jumps=2 -malign-functions=2
|
||||
|
||||
## For Linux, GCC previous to 2.7.0
|
||||
#OPTON = -O2 -fomit-frame-pointer -fforce-addr -fforce-mem -ffast-math -m486
|
||||
|
||||
#OPTON = -O2 -fomit-frame-pointer -fforce-addr -fforce-mem -ffast-math \
|
||||
# -m386 -malign-loops=1 -malign-jumps=1 -malign-functions=1
|
||||
|
||||
## For Solaris 2, or general-purpose GCC 2.7.x
|
||||
#OPTON = -O2 -fomit-frame-pointer -fforce-addr -ffast-math -Wall
|
||||
|
||||
## For Digital Unix v4.x, with DEC cc v5.x
|
||||
#OPTON = -O4
|
||||
#CFLAGS = -DTIME -std1 -verbose -w0
|
||||
|
||||
## generic gcc CFLAGS. -DTIME must be included.
|
||||
CFLAGS += $(CPPFLAGS) -DTIME -DMINIX=1 -D_MINIX=1 -D_POSIX_SOURCE=1
|
||||
|
||||
|
||||
##############################################################################
|
||||
# END CONFIGURATION
|
||||
##############################################################################
|
||||
|
||||
|
||||
# local directories
|
||||
PROGDIR = ./pgms
|
||||
SRCDIR = ./src
|
||||
TESTDIR = ./testdir
|
||||
RESULTDIR = ./results
|
||||
TMPDIR = ./tmp
|
||||
# other directories
|
||||
INCLDIR = /usr/include
|
||||
LIBDIR = /lib
|
||||
SCRIPTS = unixbench.logo multi.sh tst.sh index.base
|
||||
SOURCES = arith.c big.c context1.c \
|
||||
dummy.c execl.c \
|
||||
fstime.c hanoi.c \
|
||||
pipe.c spawn.c \
|
||||
syscall.c looper.c timeit.c time-polling.c \
|
||||
dhry_1.c dhry_2.c dhry.h whets.c ubgears.c
|
||||
TESTS = sort.src cctest.c dc.dat large.txt
|
||||
|
||||
# ifdef GRAPHIC_TESTS
|
||||
# GRAPHIC_BINS = $(PROGDIR)/ubgears
|
||||
# else
|
||||
GRAPHIC_BINS =
|
||||
# endif
|
||||
|
||||
# Program binaries.
|
||||
BINS = $(PROGDIR)/arithoh $(PROGDIR)/register $(PROGDIR)/short \
|
||||
$(PROGDIR)/int $(PROGDIR)/long $(PROGDIR)/float $(PROGDIR)/double \
|
||||
$(PROGDIR)/hanoi $(PROGDIR)/syscall $(PROGDIR)/context1 \
|
||||
$(PROGDIR)/pipe $(PROGDIR)/spawn $(PROGDIR)/execl \
|
||||
$(PROGDIR)/dhry2 $(PROGDIR)/dhry2reg $(PROGDIR)/looper \
|
||||
$(PROGDIR)/fstime $(PROGDIR)/whetstone-double $(GRAPHIC_BINS)
|
||||
## These compile only on some platforms...
|
||||
# $(PROGDIR)/poll $(PROGDIR)/poll2 $(PROGDIR)/select
|
||||
|
||||
# Required non-binary files.
|
||||
REQD = $(BINS) $(PROGDIR)/unixbench.logo \
|
||||
$(PROGDIR)/multi.sh $(PROGDIR)/tst.sh $(PROGDIR)/index.base \
|
||||
$(PROGDIR)/gfx-x11 \
|
||||
$(TESTDIR)/sort.src $(TESTDIR)/cctest.c $(TESTDIR)/dc.dat \
|
||||
$(TESTDIR)/large.txt
|
||||
|
||||
# ######################### the big ALL ############################
|
||||
all: distr programs
|
||||
## Ick!!! What is this about??? How about let's not chmod everything bogusly.
|
||||
# @chmod 744 * $(SRCDIR)/* $(PROGDIR)/* $(TESTDIR)/* $(DOCDIR)/*
|
||||
|
||||
# ####################### a check for Run ######################
|
||||
check: $(REQD)
|
||||
make all
|
||||
# ##############################################################
|
||||
# distribute the files out to subdirectories if they are in this one
|
||||
distr:
|
||||
@echo "Checking distribution of files"
|
||||
# scripts
|
||||
@if test ! -d $(PROGDIR) \
|
||||
; then \
|
||||
mkdir $(PROGDIR) \
|
||||
; mv $(SCRIPTS) $(PROGDIR) \
|
||||
; else \
|
||||
echo "$(PROGDIR) exists" \
|
||||
; fi
|
||||
# C sources
|
||||
@if test ! -d $(SRCDIR) \
|
||||
; then \
|
||||
mkdir $(SRCDIR) \
|
||||
; mv $(SOURCES) $(SRCDIR) \
|
||||
; else \
|
||||
echo "$(SRCDIR) exists" \
|
||||
; fi
|
||||
# test data
|
||||
@if test ! -d $(TESTDIR) \
|
||||
; then \
|
||||
mkdir $(TESTDIR) \
|
||||
; mv $(TESTS) $(TESTDIR) \
|
||||
; else \
|
||||
echo "$(TESTDIR) exists" \
|
||||
; fi
|
||||
# temporary work directory
|
||||
@if test ! -d $(TMPDIR) \
|
||||
; then \
|
||||
mkdir $(TMPDIR) \
|
||||
; else \
|
||||
echo "$(TMPDIR) exists" \
|
||||
; fi
|
||||
# directory for results
|
||||
@if test ! -d $(RESULTDIR) \
|
||||
; then \
|
||||
mkdir $(RESULTDIR) \
|
||||
; else \
|
||||
echo "$(RESULTDIR) exists" \
|
||||
; fi
|
||||
|
||||
programs: $(BINS)
|
||||
|
||||
# Individual programs
|
||||
$(PROGDIR)/arithoh: $(SRCDIR)/arith.c
|
||||
$(CC) -o $(PROGDIR)/arithoh ${CFLAGS} ${OPTON} -Darithoh $(SRCDIR)/arith.c
|
||||
$(PROGDIR)/register: $(SRCDIR)/arith.c
|
||||
$(CC) -o $(PROGDIR)/register ${CFLAGS} ${OPTON} -Ddatum='register int' $(SRCDIR)/arith.c
|
||||
$(PROGDIR)/short: $(SRCDIR)/arith.c
|
||||
$(CC) -o $(PROGDIR)/short ${CFLAGS} ${OPTON} -Ddatum=short $(SRCDIR)/arith.c
|
||||
$(PROGDIR)/int: $(SRCDIR)/arith.c
|
||||
$(CC) -o $(PROGDIR)/int ${CFLAGS} ${OPTON} -Ddatum=int $(SRCDIR)/arith.c
|
||||
$(PROGDIR)/long: $(SRCDIR)/arith.c
|
||||
$(CC) -o $(PROGDIR)/long ${CFLAGS} ${OPTON} -Ddatum=long $(SRCDIR)/arith.c
|
||||
$(PROGDIR)/float: $(SRCDIR)/arith.c
|
||||
$(CC) -o $(PROGDIR)/float ${CFLAGS} ${OPTON} -Ddatum=float $(SRCDIR)/arith.c
|
||||
$(PROGDIR)/double: $(SRCDIR)/arith.c
|
||||
$(CC) -o $(PROGDIR)/double ${CFLAGS} ${OPTON} -Ddatum=double $(SRCDIR)/arith.c
|
||||
$(PROGDIR)/whetstone-double: $(SRCDIR)/whets.c
|
||||
$(CC) -o $(PROGDIR)/whetstone-double ${CFLAGS} ${OPTON} -DDP -DUNIX -DUNIXBENCH $(SRCDIR)/whets.c -lm
|
||||
$(PROGDIR)/hanoi: $(SRCDIR)/hanoi.c
|
||||
$(CC) -o $(PROGDIR)/hanoi ${CFLAGS} ${OPTON} $(SRCDIR)/hanoi.c
|
||||
|
||||
$(PROGDIR)/poll: $(SRCDIR)/time-polling.c
|
||||
$(CC) -DHAS_POLL -DUNIXBENCH -o $(PROGDIR)/poll ${CFLAGS} ${OPTON} $(SRCDIR)/time-polling.c
|
||||
|
||||
$(PROGDIR)/poll2: $(SRCDIR)/time-polling.c
|
||||
$(CC) -DHAS_POLL2 -DUNIXBENCH -o $(PROGDIR)/poll2 ${CFLAGS} ${OPTON} $(SRCDIR)/time-polling.c
|
||||
|
||||
$(PROGDIR)/select: $(SRCDIR)/time-polling.c
|
||||
$(CC) -DHAS_SELECT -DUNIXBENCH -o $(PROGDIR)/select ${CFLAGS} ${OPTON} $(SRCDIR)/time-polling.c
|
||||
|
||||
$(PROGDIR)/fstime: $(SRCDIR)/fstime.c
|
||||
$(CC) -o $(PROGDIR)/fstime ${CFLAGS} ${OPTON} $(SRCDIR)/fstime.c
|
||||
|
||||
$(PROGDIR)/syscall: $(SRCDIR)/syscall.c
|
||||
$(CC) -o $(PROGDIR)/syscall ${CFLAGS} ${OPTON} $(SRCDIR)/syscall.c
|
||||
$(PROGDIR)/context1: $(SRCDIR)/context1.c
|
||||
$(CC) -o $(PROGDIR)/context1 ${CFLAGS} ${OPTON} $(SRCDIR)/context1.c
|
||||
$(PROGDIR)/pipe: $(SRCDIR)/pipe.c
|
||||
$(CC) -o $(PROGDIR)/pipe ${CFLAGS} ${OPTON} $(SRCDIR)/pipe.c
|
||||
$(PROGDIR)/spawn: $(SRCDIR)/spawn.c
|
||||
$(CC) -o $(PROGDIR)/spawn ${CFLAGS} ${OPTON} $(SRCDIR)/spawn.c
|
||||
$(PROGDIR)/execl: $(SRCDIR)/execl.c $(SRCDIR)/big.c
|
||||
$(CC) -o $(PROGDIR)/execl ${CFLAGS} ${OPTON} $(SRCDIR)/execl.c
|
||||
|
||||
$(PROGDIR)/dhry2: $(SRCDIR)/dhry_1.c $(SRCDIR)/dhry_2.c $(SRCDIR)/dhry.h
|
||||
cd $(SRCDIR); $(CC) -c ${CFLAGS} -DHZ=${HZ} ${OPTON} dhry_1.c
|
||||
cd $(SRCDIR); $(CC) -c ${CFLAGS} -DHZ=${HZ} ${OPTON} dhry_2.c
|
||||
$(CC) -o $(PROGDIR)/dhry2 ${CFLAGS} ${OPTON} $(SRCDIR)/dhry_1.o $(SRCDIR)/dhry_2.o
|
||||
cd $(SRCDIR); rm -f dhry_1.o dhry_2.o
|
||||
$(PROGDIR)/dhry2reg: $(SRCDIR)/dhry_1.c $(SRCDIR)/dhry_2.c $(SRCDIR)/dhry.h
|
||||
cd $(SRCDIR); $(CC) -c ${CFLAGS} -DREG=register -DHZ=${HZ} ${OPTON} dhry_1.c
|
||||
cd $(SRCDIR); $(CC) -c ${CFLAGS} -DREG=register -DHZ=${HZ} ${OPTON} dhry_2.c
|
||||
$(CC) -o $(PROGDIR)/dhry2reg ${CFLAGS} ${OPTON} $(SRCDIR)/dhry_1.o $(SRCDIR)/dhry_2.o
|
||||
cd $(SRCDIR); rm -f dhry_1.o dhry_2.o
|
||||
|
||||
$(PROGDIR)/looper: $(SRCDIR)/looper.c
|
||||
$(CC) -o $(PROGDIR)/looper ${CFLAGS} ${OPTON} $(SRCDIR)/looper.c
|
||||
|
||||
$(PROGDIR)/ubgears: $(SRCDIR)/ubgears.c
|
||||
$(CC) -o $(PROGDIR)/ubgears ${CFLAGS} ${OPTON} $(SRCDIR)/ubgears.c $(GL_LIBS)
|
||||
|
||||
# Run the benchmarks and create the reports
|
||||
run:
|
||||
sh ./Run
|
||||
|
||||
clean:
|
||||
rm -f $(BINS) core *~ */*~
|
||||
|
||||
spotless: clean
|
||||
rm -f $(RESULTDIR)/* $(TMPDIR)/*
|
||||
|
||||
## END ##
|
||||
@@ -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,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,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,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,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,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,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);
|
||||
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,471 +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);
|
||||
#else
|
||||
extern int 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("/bin/true", (char *) 0);
|
||||
fprintf(stderr,"%s: exec /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,573 +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
|
||||
#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;
|
||||
|
||||
|
||||
/*
|
||||
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 */
|
||||
|
||||
|
||||
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,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,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 $ ]
|
||||
File diff suppressed because it is too large
Load Diff
@@ -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
|
||||
169
boot/Makefile
Normal file → Executable file
169
boot/Makefile
Normal file → Executable file
@@ -1,97 +1,116 @@
|
||||
# Makefile for the boot monitor package.
|
||||
|
||||
# XXX: Can only be built with ACK currently
|
||||
CC:=${CC:C/^gcc/cc/}
|
||||
COMPILER_TYPE:=ack
|
||||
SYS = ..
|
||||
|
||||
PROGS= bootblock cdbootblock boot masterboot \
|
||||
jumpboot installboot edparams dosboot mkfile
|
||||
CC = exec cc
|
||||
CC86 = exec cc -mi86 -Was-ncc
|
||||
CFLAGS = -I$(SYS)
|
||||
LIBS = -lsys
|
||||
LD = $(CC) -s -.o
|
||||
LD86 = $(CC86) -.o
|
||||
BIN = /usr/bin
|
||||
MDEC = /usr/mdec
|
||||
|
||||
SRCS.bootblock= bootblock.s
|
||||
CPPFLAGS.bootblock.s= ${I86CPPFLAGS}
|
||||
LDFLAGS.bootblock= ${I86LDFLAGS}
|
||||
BINDIR.bootblock= /usr/mdec
|
||||
MAN.bootblock=
|
||||
all: bootblock boot edparams masterboot jumpboot installboot addaout
|
||||
dos: boot.com mkfile.com
|
||||
|
||||
SRCS.cdbootblock= cdbootblock.s
|
||||
CPPFLAGS.cdbootblock.s= ${I86CPPFLAGS} -DCDBOOT
|
||||
LDFLAGS.cdbootblock= ${I86LDFLAGS}
|
||||
BINDIR.cdbootblock= /usr/mdec
|
||||
MAN.cdbootblock=
|
||||
bootblock: bootblock.s
|
||||
$(LD86) -com -o $@ bootblock.s
|
||||
|
||||
SRCS.boot= boothead.s boot.c bootimage.c rawfs86.c
|
||||
CPPFLAGS.boothead.s= ${I86CPPFLAGS}
|
||||
CPPFLAGS.boot.c= ${I86CPPFLAGS}
|
||||
CPPFLAGS.bootimage.c= ${I86CPPFLAGS}
|
||||
CPPFLAGS.rawfs86.c= ${I86CPPFLAGS}
|
||||
LDFLAGS.boot= ${I86LDFLAGS}
|
||||
DPADD.boot= ${LIBSYS}
|
||||
LDADD.boot= -lsys
|
||||
BINDIR.boot= /usr/mdec
|
||||
MAN.boot=
|
||||
masterboot: masterboot.s
|
||||
$(LD86) -com -o $@ masterboot.s
|
||||
|
||||
realall: .PHONY bootsize
|
||||
bootsize: boot
|
||||
${INSTALL} -S 22kb boot
|
||||
jumpboot: jumpboot.s
|
||||
$(LD86) -com -o $@ jumpboot.s
|
||||
|
||||
SRCS.masterboot= masterboot.s
|
||||
CPPFLAGS.masterboot.s= ${I86CPPFLAGS}
|
||||
LDFLAGS.masterboot= ${I86LDFLAGS}
|
||||
BINDIR.masterboot= /usr/mdec
|
||||
MAN.masterboot=
|
||||
boot.o: boot.c
|
||||
$(CC86) $(CFLAGS) -c boot.c
|
||||
|
||||
SRCS.jumpboot= jumpboot.s
|
||||
CPPFLAGS.jumpboot.s= ${I86CPPFLAGS}
|
||||
LDFLAGS.jumpboot= ${I86LDFLAGS}
|
||||
BINDIR.jumpboot= /usr/mdec
|
||||
MAN.jumpboot=
|
||||
bootimage.o: bootimage.c
|
||||
$(CC86) $(CFLAGS) -c bootimage.c
|
||||
|
||||
SRCS.installboot= installboot.c rawfs.c
|
||||
BINDIR.installboot= /usr/bin
|
||||
MAN.installboot=
|
||||
|
||||
SRCS.edparams= edparams.c rawfs.c
|
||||
CPPFLAGS.edparams.c= -DUNIX
|
||||
BINDIR.edparams= /usr/bin
|
||||
MAN.edparams=
|
||||
|
||||
SRCS.dosboot= doshead.s dosboot.o bootimage.o rawfs86.o
|
||||
CPPFLAGS.dosboot.c= -DDOS $(I86CPPFLAGS)
|
||||
LDADD.dosboot= ${I86LDFLAGS} -lsys
|
||||
BINDIR.dosboot= /usr/mdec
|
||||
CPPFLAGS.doshead.s= -mi386
|
||||
MAN.dosboot=
|
||||
|
||||
SRCS.mkfile= mkfhead.s mkfile.c
|
||||
CPPFLAGS.mkfile.s= ${I86CPPFLAGS}
|
||||
LDADD.mkfile= ${I86LDFLAGS} -lsys
|
||||
BINDIR.mkfile= /usr/mdec
|
||||
MAN.mkfile=
|
||||
|
||||
rawfs86.c: rawfs.c
|
||||
rawfs86.o: rawfs.c rawfs.o
|
||||
ln -f rawfs.c rawfs86.c
|
||||
$(CC86) $(CFLAGS) -c rawfs86.c
|
||||
rm rawfs86.c
|
||||
-cmp -s rawfs.o rawfs86.o && ln -f rawfs.o rawfs86.o
|
||||
|
||||
edparams.c: boot.c
|
||||
boot: boothead.s boot.o bootimage.o rawfs86.o
|
||||
$(LD86) -o $@ \
|
||||
boothead.s boot.o bootimage.o rawfs86.o $(LIBS)
|
||||
install -S 8kb boot
|
||||
|
||||
edparams.o: boot.c
|
||||
ln -f boot.c edparams.c
|
||||
$(CC) $(CFLAGS) -DUNIX -c edparams.c
|
||||
rm edparams.c
|
||||
|
||||
dosboot.c: boot.c
|
||||
ln -f boot.c dosboot.c
|
||||
edparams: edparams.o rawfs.o
|
||||
$(CC) $(CFLAGS) $(STRIP) -o $@ edparams.o rawfs.o
|
||||
install -S 16kw edparams
|
||||
|
||||
cdbootblock.s: bootblock.s
|
||||
ln -f bootblock.s cdbootblock.s
|
||||
dosboot.o: boot.c
|
||||
$(CC86) $(CFLAGS) -DDOS -o $@ -c boot.c
|
||||
|
||||
mkfile.com: mkfile
|
||||
doshead.o: doshead.s
|
||||
$(CC) -mi386 -o $@ -c doshead.s
|
||||
|
||||
boot.com: dosboot
|
||||
dosboot: doshead.o dosboot.o bootimage.o rawfs86.o
|
||||
$(LD86) -com -o $@ \
|
||||
doshead.o dosboot.o bootimage.o rawfs86.o $(LIBS)
|
||||
|
||||
boot.com: dosboot
|
||||
./a.out2com dosboot boot.com
|
||||
|
||||
CPPFLAGS= -I${MINIXSRCDIR}
|
||||
AFLAGS= -I${MINIXSRCDIR}
|
||||
I86CPPFLAGS= -mi86 -Was-ncc
|
||||
I86LDFLAGS= -mi86 -Was-ncc -.o -com
|
||||
mkfile: mkfhead.s mkfile.c
|
||||
$(LD) -.o -mi86 -com -o $@ mkfhead.s mkfile.c $(LIBS)
|
||||
|
||||
STRIPFLAG= -s
|
||||
mkfile.com: mkfile
|
||||
./a.out2com mkfile mkfile.com
|
||||
|
||||
CLEANFILES+= rawfs86.c edparams.c cdbootblock.s dosboot.c
|
||||
installboot: installboot.o rawfs.o
|
||||
$(CC) $(STRIP) -o installboot installboot.o rawfs.o
|
||||
install -S 6kw installboot
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
addaout: addaout.o
|
||||
$(CC) -o addaout addaout.o
|
||||
|
||||
installboot.o bootimage.o: image.h
|
||||
boot.o bootimage.o dosboot.o edparams.o: boot.h
|
||||
rawfs.o rawfs86.o installboot.o boot.o bootimage.o: rawfs.h
|
||||
|
||||
install: $(MDEC)/bootblock $(MDEC)/boot $(MDEC)/masterboot \
|
||||
$(MDEC)/jumpboot $(BIN)/installboot $(BIN)/edparams
|
||||
dosinstall: $(MDEC)/boot.com $(MDEC)/mkfile.com
|
||||
|
||||
$(MDEC)/bootblock: bootblock
|
||||
install -cs -o bin -m 644 $? $@
|
||||
|
||||
$(MDEC)/boot: boot
|
||||
install -cs -o bin -m 644 $? $@
|
||||
|
||||
$(MDEC)/boot.com: boot.com
|
||||
install -c -m 644 $? $@
|
||||
|
||||
$(MDEC)/mkfile.com: mkfile.com
|
||||
install -c -m 644 $? $@
|
||||
|
||||
$(MDEC)/masterboot: masterboot
|
||||
install -cs -o bin -m 644 $? $@
|
||||
|
||||
$(MDEC)/jumpboot: jumpboot
|
||||
install -cs -o bin -m 644 $? $@
|
||||
|
||||
$(BIN)/installboot: installboot
|
||||
install -cs -o bin $? $@
|
||||
|
||||
$(BIN)/addaout: addaout
|
||||
install -cs -o bin $? $@
|
||||
|
||||
$(BIN)/edparams: edparams
|
||||
install -cs -o bin $? $@
|
||||
|
||||
clean:
|
||||
rm -f *.bak *.o
|
||||
rm -f bootblock addaout installboot boot masterboot jumpboot edparams
|
||||
rm -f dosboot boot.com mkfile mkfile.com
|
||||
|
||||
@@ -20,35 +20,34 @@
|
||||
#define OUTPUT_FILE 2
|
||||
|
||||
/* Report problems. */
|
||||
static void report(const char *problem, const char *message)
|
||||
void report(char *problem, char *message)
|
||||
{
|
||||
fprintf(stderr, "%s:\n", problem);
|
||||
fprintf(stderr, " %s\n\n", message);
|
||||
}
|
||||
|
||||
|
||||
static int copy_data(int srcfd, int dstfd)
|
||||
int copy_data(int srcfd, int dstfd)
|
||||
{
|
||||
char buf[8192];
|
||||
ssize_t n;
|
||||
int total=0;
|
||||
|
||||
/** FIXME: handle error from read() */
|
||||
|
||||
/* Copy the little bytes themselves. (Source from cp.c). */
|
||||
while ((n= read(srcfd, buf, sizeof(buf))) > 0) {
|
||||
char *bp = buf;
|
||||
ssize_t r = 0;
|
||||
ssize_t r;
|
||||
|
||||
/** FIXME: handle error from write() */
|
||||
while (n > 0 && (r= write(dstfd, bp, n)) > 0) {
|
||||
bp += r;
|
||||
n -= r;
|
||||
total += r;
|
||||
}
|
||||
if (r == 0) {
|
||||
fprintf(stderr, "Warning: EOF writing to output file.\n");
|
||||
return(-1);
|
||||
if (r <= 0) {
|
||||
if (r == 0) {
|
||||
fprintf(stderr, "Warning: EOF writing to output file.\n");
|
||||
return(-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
return(total);
|
||||
@@ -63,7 +62,8 @@ int main(int argc, char **argv)
|
||||
int fdin, fdout;
|
||||
char * bp;
|
||||
int n,r;
|
||||
int total_size;
|
||||
int total_size=0;
|
||||
int result;
|
||||
|
||||
/* Check if command line arguments are present, or print usage. */
|
||||
if (argc!=3) {
|
||||
@@ -113,13 +113,13 @@ int main(int argc, char **argv)
|
||||
|
||||
bp = (char *) &aout;
|
||||
n = sizeof(aout);
|
||||
lseek(fdout, 0L, SEEK_SET);
|
||||
lseek(fdout, 0, SEEK_SET);
|
||||
while (n > 0 && (r= write(fdout, bp, n)) > 0) {
|
||||
bp += r;
|
||||
n -= r;
|
||||
}
|
||||
|
||||
printf("Prepended data file (%d bytes) with a.out header (%u bytes).\n",
|
||||
printf("Prepended data file (%u bytes) with a.out header (%u bytes).\n",
|
||||
total_size, sizeof(aout));
|
||||
printf("Done.\n");
|
||||
|
||||
|
||||
326
boot/boot.c
Normal file → Executable file
326
boot/boot.c
Normal file → Executable file
@@ -17,17 +17,17 @@ char version[]= "2.20";
|
||||
#include <limits.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <machine/partition.h>
|
||||
#include <machine/bios.h>
|
||||
#include <ibm/partition.h>
|
||||
#include <minix/config.h>
|
||||
#include <minix/type.h>
|
||||
#include <minix/com.h>
|
||||
#include <minix/dmap.h>
|
||||
#include <minix/const.h>
|
||||
#include <minix/minlib.h>
|
||||
#include <minix/syslib.h>
|
||||
#if BIOS
|
||||
#include <kernel/const.h>
|
||||
#include <sys/video.h>
|
||||
#include <kernel/type.h>
|
||||
#endif
|
||||
#if UNIX
|
||||
#include <stdio.h>
|
||||
@@ -46,12 +46,6 @@ char version[]= "2.20";
|
||||
#define arraylimit(a) ((a) + arraysize(a))
|
||||
#define between(a, c, z) ((unsigned) ((c) - (a)) <= ((z) - (a)))
|
||||
|
||||
int serial_line = -1;
|
||||
|
||||
u16_t vid_port; /* Video i/o port. */
|
||||
u32_t vid_mem_base; /* Video memory base address. */
|
||||
u32_t vid_mem_size; /* Video memory size. */
|
||||
|
||||
int fsok= -1; /* File system state. Initially unknown. */
|
||||
|
||||
static int block_size;
|
||||
@@ -64,7 +58,7 @@ static int block_size;
|
||||
*/
|
||||
unsigned char boot_spec[24];
|
||||
|
||||
static const char *bios_err(int err)
|
||||
char *bios_err(int err)
|
||||
/* Translate BIOS error code to a readable string. (This is a rare trait
|
||||
* known as error checking and reporting. Take a good look at it, you won't
|
||||
* see it often.)
|
||||
@@ -120,44 +114,6 @@ static const char *bios_err(int err)
|
||||
return "Unknown error";
|
||||
}
|
||||
|
||||
/* CD's are addressed in 2048-byte sectors.
|
||||
* In order to be able to read CD's but maintain the same interface of 512-byte
|
||||
* sector addressing, we check if the device is a CD in readsectors() and if so,
|
||||
* read it into our own buffer first
|
||||
*/
|
||||
int readsectors(u32_t bufaddr, u32_t sector, u8_t count)
|
||||
{
|
||||
#define CDSECTOR_SIZE 2048
|
||||
static char cdbuf[CDSECTOR_SIZE];
|
||||
static i32_t cdbuf_sec = -1;
|
||||
i32_t cdsec;
|
||||
|
||||
if(device != cddevice) {
|
||||
return biosreadsectors(bufaddr, sector, count);
|
||||
}
|
||||
|
||||
while(count > 0) {
|
||||
u32_t offset;
|
||||
#define FACTOR (CDSECTOR_SIZE/SECTOR_SIZE)
|
||||
cdsec = sector / FACTOR;
|
||||
offset = (sector % FACTOR) * SECTOR_SIZE;
|
||||
if(cdsec != cdbuf_sec) {
|
||||
int r;
|
||||
if((r=biosreadsectors(mon2abs(cdbuf), cdsec, 1)) != 0) {
|
||||
printf("error %d\n", r);
|
||||
return r;
|
||||
}
|
||||
cdbuf_sec = cdsec;
|
||||
}
|
||||
raw_copy(bufaddr, mon2abs(cdbuf) + offset, SECTOR_SIZE);
|
||||
bufaddr += SECTOR_SIZE;
|
||||
count--;
|
||||
sector++;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
char *unix_err(int err)
|
||||
/* Translate the few errors rawfs can give. */
|
||||
{
|
||||
@@ -168,7 +124,7 @@ char *unix_err(int err)
|
||||
}
|
||||
}
|
||||
|
||||
static void rwerr(const char *rw, off_t sec, int err)
|
||||
void rwerr(char *rw, off_t sec, int err)
|
||||
{
|
||||
printf("\n%s error 0x%02x (%s) at sector %ld absolute\n",
|
||||
rw, err, bios_err(err), sec);
|
||||
@@ -194,7 +150,7 @@ void readblock(off_t blk, char *buf, int block_size)
|
||||
}
|
||||
|
||||
#define istty (1)
|
||||
#define alarm(n) do { } while(0)
|
||||
#define alarm(n) (0)
|
||||
|
||||
#endif /* BIOS */
|
||||
|
||||
@@ -208,8 +164,8 @@ struct biosdev {
|
||||
int device; /* Device to edit parameters. */
|
||||
} bootdev;
|
||||
|
||||
static struct termios termbuf;
|
||||
static int istty;
|
||||
struct termios termbuf;
|
||||
int istty;
|
||||
|
||||
void quit(int status)
|
||||
{
|
||||
@@ -219,13 +175,13 @@ void quit(int status)
|
||||
|
||||
#define exit(s) quit(s)
|
||||
|
||||
void report(const char *label)
|
||||
void report(char *label)
|
||||
/* edparams: label: No such file or directory */
|
||||
{
|
||||
fprintf(stderr, "edparams: %s: %s\n", label, strerror(errno));
|
||||
}
|
||||
|
||||
void fatal(const char *label)
|
||||
void fatal(char *label)
|
||||
{
|
||||
report(label);
|
||||
exit(1);
|
||||
@@ -338,7 +294,7 @@ int getch(void)
|
||||
|
||||
#endif /* UNIX */
|
||||
|
||||
static char *readline(void)
|
||||
char *readline(void)
|
||||
/* Read a line including a newline with echoing. */
|
||||
{
|
||||
char *line;
|
||||
@@ -375,13 +331,13 @@ static char *readline(void)
|
||||
return line;
|
||||
}
|
||||
|
||||
static int sugar(const char *tok)
|
||||
int sugar(char *tok)
|
||||
/* Recognize special tokens. */
|
||||
{
|
||||
return strchr("=(){};\n", tok[0]) != nil;
|
||||
}
|
||||
|
||||
static char *onetoken(char **aline)
|
||||
char *onetoken(char **aline)
|
||||
/* Returns a string with one token for tokenize. */
|
||||
{
|
||||
char *line= *aline;
|
||||
@@ -429,7 +385,7 @@ typedef struct token {
|
||||
char *token;
|
||||
} token;
|
||||
|
||||
static token **tokenize(token **acmds, char *line)
|
||||
token **tokenize(token **acmds, char *line)
|
||||
/* Takes a line apart to form tokens. The tokens are inserted into a command
|
||||
* chain at *acmds. Tokenize returns a reference to where another line could
|
||||
* be added. Tokenize looks at spaces as token separators, and recognizes only
|
||||
@@ -450,10 +406,10 @@ static token **tokenize(token **acmds, char *line)
|
||||
return acmds;
|
||||
}
|
||||
|
||||
static token *cmds; /* String of commands to execute. */
|
||||
static int err; /* Set on an error. */
|
||||
token *cmds; /* String of commands to execute. */
|
||||
int err; /* Set on an error. */
|
||||
|
||||
static char *poptoken(void)
|
||||
char *poptoken(void)
|
||||
/* Pop one token off the command chain. */
|
||||
{
|
||||
token *cmd= cmds;
|
||||
@@ -465,7 +421,7 @@ static char *poptoken(void)
|
||||
return tok;
|
||||
}
|
||||
|
||||
static void voidtoken(void)
|
||||
void voidtoken(void)
|
||||
/* Remove one token from the command chain. */
|
||||
{
|
||||
free(poptoken());
|
||||
@@ -480,7 +436,7 @@ void parse_code(char *code)
|
||||
(void) tokenize(&cmds, code);
|
||||
}
|
||||
|
||||
static int interrupt(void)
|
||||
int interrupt(void)
|
||||
/* Clean up after an ESC has been typed. */
|
||||
{
|
||||
if (escape()) {
|
||||
@@ -493,14 +449,14 @@ static int interrupt(void)
|
||||
|
||||
#if BIOS
|
||||
|
||||
static int activate;
|
||||
int activate;
|
||||
|
||||
struct biosdev {
|
||||
char name[8];
|
||||
int device, primary, secondary;
|
||||
} bootdev, tmpdev;
|
||||
|
||||
static int get_master(char *master, struct part_entry **table, u32_t pos)
|
||||
int get_master(char *master, struct part_entry **table, u32_t pos)
|
||||
/* Read a master boot sector and its partition table. */
|
||||
{
|
||||
int r, n;
|
||||
@@ -526,7 +482,7 @@ static int get_master(char *master, struct part_entry **table, u32_t pos)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void initialize(void)
|
||||
void initialize(void)
|
||||
{
|
||||
char master[SECTOR_SIZE];
|
||||
struct part_entry *table[NR_PARTITIONS];
|
||||
@@ -538,44 +494,17 @@ static void initialize(void)
|
||||
* done to get out of the way of Minix, and to put the data area
|
||||
* cleanly inside a 64K chunk if using BIOS I/O (no DMA problems).
|
||||
*/
|
||||
u32_t oldaddr;
|
||||
u32_t memend;
|
||||
u32_t newaddr;
|
||||
u32_t oldaddr= caddr;
|
||||
u32_t memend= mem[0].base + mem[0].size;
|
||||
u32_t newaddr= (memend - runsize) & ~0x0000FL;
|
||||
#if !DOS
|
||||
u32_t dma64k;
|
||||
#endif
|
||||
|
||||
if (mem_entries) {
|
||||
int i, j;
|
||||
j = 0;
|
||||
for(i = 0; i < mem_entries ; i++) {
|
||||
if (j < 3 && emem[i].type == 1 && !emem[i].base_hi) {
|
||||
mem[j].base = emem[i].base_lo;
|
||||
mem[j].size = emem[i].size_lo;
|
||||
j++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
oldaddr= caddr;
|
||||
memend= mem[0].base + mem[0].size;
|
||||
newaddr= (memend - runsize) & ~0x0000FL;
|
||||
#if !DOS
|
||||
dma64k= (memend - 1) & ~0x0FFFFL;
|
||||
u32_t dma64k= (memend - 1) & ~0x0FFFFL;
|
||||
|
||||
|
||||
/* Check if data segment crosses a 64K boundary. */
|
||||
if (newaddr + (daddr - caddr) < dma64k) {
|
||||
newaddr= (dma64k - runsize) & ~0x0000FL;
|
||||
}
|
||||
if (newaddr + (daddr - caddr) < dma64k) newaddr= dma64k - runsize;
|
||||
#endif
|
||||
|
||||
/* If we were booted from CD, remember what device it was. */
|
||||
if(cdbooted)
|
||||
cddevice = device;
|
||||
else
|
||||
cddevice = 0xff; /* Invalid. */
|
||||
|
||||
/* Set the new caddr for relocate. */
|
||||
caddr= newaddr;
|
||||
|
||||
@@ -591,7 +520,7 @@ static void initialize(void)
|
||||
* and also keep the BIOS data area safe (1.5K), plus a bit extra for
|
||||
* where we may have to put a.out headers for older kernels.
|
||||
*/
|
||||
if ((mon_return = (mem[1].size > 512*1024L))) mem[0].size = newaddr;
|
||||
if (mon_return = (mem[1].size > 512*1024L)) mem[0].size = newaddr;
|
||||
mem[0].base += 2048;
|
||||
mem[0].size -= 2048;
|
||||
|
||||
@@ -625,14 +554,6 @@ static void initialize(void)
|
||||
readerr(masterpos, r); exit(1);
|
||||
}
|
||||
|
||||
/* If we're a CD, we know what we want. */
|
||||
if(device == cddevice) {
|
||||
p = 1; /* We know this is the root FS. */
|
||||
lowsec = table[p]->lowsec;
|
||||
bootdev.primary = p;
|
||||
break; /* Found! */
|
||||
}
|
||||
|
||||
/* See if you can find "lowsec" back. */
|
||||
for (p= 0; p < NR_PARTITIONS; p++) {
|
||||
if (lowsec - table[p]->lowsec < table[p]->size) break;
|
||||
@@ -659,32 +580,14 @@ static void initialize(void)
|
||||
bootdev.primary= p;
|
||||
masterpos= table[p]->lowsec;
|
||||
}
|
||||
|
||||
if(device == cddevice) {
|
||||
strcpy(bootdev.name, CDNAME);
|
||||
} else {
|
||||
strcpy(bootdev.name, "d0p0");
|
||||
bootdev.name[1] += (device - 0x80);
|
||||
bootdev.name[3] += bootdev.primary;
|
||||
if (bootdev.secondary >= 0) {
|
||||
strcat(bootdev.name, "s0");
|
||||
bootdev.name[5] += bootdev.secondary;
|
||||
}
|
||||
strcpy(bootdev.name, "d0p0");
|
||||
bootdev.name[1] += (device - 0x80);
|
||||
bootdev.name[3] += bootdev.primary;
|
||||
if (bootdev.secondary >= 0) {
|
||||
strcat(bootdev.name, "s0");
|
||||
bootdev.name[5] += bootdev.secondary;
|
||||
}
|
||||
|
||||
/* Find out about the video hardware. */
|
||||
raw_copy(mon2abs(&vid_port), VDU_CRT_BASE_ADDR, sizeof(vid_port));
|
||||
if(vid_port == C_6845) {
|
||||
vid_mem_base = COLOR_BASE;
|
||||
vid_mem_size = COLOR_SIZE;
|
||||
} else {
|
||||
vid_mem_base = MONO_BASE;
|
||||
vid_mem_size = MONO_SIZE;
|
||||
}
|
||||
|
||||
if(get_video() >= 3)
|
||||
vid_mem_size = EGA_SIZE;
|
||||
|
||||
#else /* DOS */
|
||||
/* Take the monitor out of the memory map if we have memory to spare,
|
||||
* note that only half our PSP is needed at the new place, the first
|
||||
@@ -734,35 +637,35 @@ static void initialize(void)
|
||||
/* Reserved names: */
|
||||
enum resnames {
|
||||
R_NULL, R_BOOT, R_CTTY, R_DELAY, R_ECHO, R_EXIT, R_HELP,
|
||||
R_LS, R_MENU, R_OFF, R_SAVE, R_SET, R_TRAP, R_UNSET, R_RESET
|
||||
R_LS, R_MENU, R_OFF, R_SAVE, R_SET, R_TRAP, R_UNSET
|
||||
};
|
||||
|
||||
static char resnames[][6] = {
|
||||
char resnames[][6] = {
|
||||
"", "boot", "ctty", "delay", "echo", "exit", "help",
|
||||
"ls", "menu", "off", "save", "set", "trap", "unset", "reset",
|
||||
"ls", "menu", "off", "save", "set", "trap", "unset",
|
||||
};
|
||||
|
||||
/* Using this for all null strings saves a lot of memory. */
|
||||
#define null (resnames[0])
|
||||
|
||||
static enum resnames reserved(const char *s)
|
||||
int reserved(char *s)
|
||||
/* Recognize reserved strings. */
|
||||
{
|
||||
enum resnames r;
|
||||
int r;
|
||||
|
||||
for (r= R_BOOT; r <= R_RESET; r++) {
|
||||
for (r= R_BOOT; r <= R_UNSET; r++) {
|
||||
if (strcmp(s, resnames[r]) == 0) return r;
|
||||
}
|
||||
return R_NULL;
|
||||
}
|
||||
|
||||
static void sfree(char *s)
|
||||
void sfree(char *s)
|
||||
/* Free a non-null string. */
|
||||
{
|
||||
if (s != nil && s != null) free(s);
|
||||
}
|
||||
|
||||
static char *copystr(const char *s)
|
||||
char *copystr(char *s)
|
||||
/* Copy a non-null string using malloc. */
|
||||
{
|
||||
char *c;
|
||||
@@ -773,12 +676,12 @@ static char *copystr(const char *s)
|
||||
return c;
|
||||
}
|
||||
|
||||
static int is_default(const environment *e)
|
||||
int is_default(environment *e)
|
||||
{
|
||||
return (e->flags & E_SPECIAL) && e->defval == nil;
|
||||
}
|
||||
|
||||
static environment **searchenv(const char *name)
|
||||
environment **searchenv(char *name)
|
||||
{
|
||||
environment **aenv= &env;
|
||||
|
||||
@@ -792,7 +695,7 @@ static environment **searchenv(const char *name)
|
||||
#define b_getenv(name) (*searchenv(name))
|
||||
/* Return the environment *structure* belonging to name, or nil if not found. */
|
||||
|
||||
char *b_value(const char *name)
|
||||
char *b_value(char *name)
|
||||
/* The value of a variable. */
|
||||
{
|
||||
environment *e= b_getenv(name);
|
||||
@@ -800,7 +703,7 @@ char *b_value(const char *name)
|
||||
return e == nil || !(e->flags & E_VAR) ? nil : e->value;
|
||||
}
|
||||
|
||||
static char *b_body(const char *name)
|
||||
char *b_body(char *name)
|
||||
/* The value of a function. */
|
||||
{
|
||||
environment *e= b_getenv(name);
|
||||
@@ -808,8 +711,7 @@ static char *b_body(const char *name)
|
||||
return e == nil || !(e->flags & E_FUNCTION) ? nil : e->value;
|
||||
}
|
||||
|
||||
static int b_setenv(int flags, const char *name, const char *arg,
|
||||
const char *value)
|
||||
int b_setenv(int flags, char *name, char *arg, char *value)
|
||||
/* Change the value of an environment variable. Returns the flags of the
|
||||
* variable if you are not allowed to change it, 0 otherwise.
|
||||
*/
|
||||
@@ -858,7 +760,7 @@ int b_setvar(int flags, char *name, char *value)
|
||||
return r;
|
||||
}
|
||||
|
||||
void b_unset(const char *name)
|
||||
void b_unset(char *name)
|
||||
/* Remove a variable from the environment. A special variable is reset to
|
||||
* its default value.
|
||||
*/
|
||||
@@ -884,7 +786,7 @@ void b_unset(const char *name)
|
||||
}
|
||||
}
|
||||
|
||||
long a2l(const char *a)
|
||||
long a2l(char *a)
|
||||
/* Cheap atol(). */
|
||||
{
|
||||
int sign= 1;
|
||||
@@ -914,7 +816,7 @@ char *ul2a10(u32_t n)
|
||||
return ul2a(n, 10);
|
||||
}
|
||||
|
||||
unsigned a2x(const char *a)
|
||||
unsigned a2x(char *a)
|
||||
/* Ascii to hex. */
|
||||
{
|
||||
unsigned n= 0;
|
||||
@@ -935,11 +837,11 @@ unsigned a2x(const char *a)
|
||||
return n;
|
||||
}
|
||||
|
||||
static void get_parameters(void)
|
||||
void get_parameters(void)
|
||||
{
|
||||
char params[SECTOR_SIZE + 1];
|
||||
token **acmds;
|
||||
int r, processor;
|
||||
int r, bus;
|
||||
memory *mp;
|
||||
static char bus_type[][4] = {
|
||||
"xt", "at", "mca"
|
||||
@@ -955,13 +857,8 @@ static void get_parameters(void)
|
||||
b_setvar(E_SPECIAL|E_VAR|E_DEV, "rootdev", "ram");
|
||||
b_setvar(E_SPECIAL|E_VAR|E_DEV, "ramimagedev", "bootdev");
|
||||
b_setvar(E_SPECIAL|E_VAR, "ramsize", "0");
|
||||
#define STRINGIT2(x) #x
|
||||
#define STRINGIT1(x) STRINGIT2(x)
|
||||
b_setvar(E_SPECIAL|E_VAR, "hz", STRINGIT1(DEFAULT_HZ));
|
||||
#if BIOS
|
||||
processor = getprocessor();
|
||||
if(processor == 1586) processor = 686;
|
||||
b_setvar(E_SPECIAL|E_VAR, "processor", ul2a10(processor));
|
||||
b_setvar(E_SPECIAL|E_VAR, "processor", ul2a10(getprocessor()));
|
||||
b_setvar(E_SPECIAL|E_VAR, "bus", bus_type[get_bus()]);
|
||||
b_setvar(E_SPECIAL|E_VAR, "video", vid_type[get_video()]);
|
||||
b_setvar(E_SPECIAL|E_VAR, "chrome", vid_chrome[get_video() & 1]);
|
||||
@@ -975,6 +872,14 @@ static void get_parameters(void)
|
||||
}
|
||||
b_setvar(E_SPECIAL|E_VAR, "memory", params);
|
||||
|
||||
#if 0
|
||||
b_setvar(E_SPECIAL|E_VAR, "c0",
|
||||
DOS ? "dosfile" : get_bus() == 1 ? "at" : "bios");
|
||||
#else
|
||||
b_setvar(E_SPECIAL|E_VAR, "label", "AT");
|
||||
b_setvar(E_SPECIAL|E_VAR, "controller", "c0");
|
||||
#endif
|
||||
|
||||
#if DOS
|
||||
b_setvar(E_SPECIAL|E_VAR, "dosfile-d0", vdisk);
|
||||
#endif
|
||||
@@ -1017,14 +922,14 @@ static void get_parameters(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
static char *addptr;
|
||||
char *addptr;
|
||||
|
||||
static void addparm(const char *n)
|
||||
void addparm(char *n)
|
||||
{
|
||||
while (*n != 0 && *addptr != 0) *addptr++ = *n++;
|
||||
}
|
||||
|
||||
static void save_parameters(void)
|
||||
void save_parameters(void)
|
||||
/* Save nondefault environment variables to the bootparams sector. */
|
||||
{
|
||||
environment *e;
|
||||
@@ -1065,7 +970,7 @@ static void save_parameters(void)
|
||||
}
|
||||
}
|
||||
|
||||
static void show_env(void)
|
||||
void show_env(void)
|
||||
/* Show the environment settings. */
|
||||
{
|
||||
environment *e;
|
||||
@@ -1136,6 +1041,7 @@ dev_t name2dev(char *name)
|
||||
{
|
||||
dev_t dev;
|
||||
ino_t ino;
|
||||
int drive;
|
||||
struct stat st;
|
||||
char *n, *s;
|
||||
|
||||
@@ -1161,9 +1067,12 @@ dev_t name2dev(char *name)
|
||||
n= name;
|
||||
if (strncmp(n, "/dev/", 5) == 0) n+= 5;
|
||||
|
||||
if (strcmp(n, "ram") == 0 || strcmp(n, CDNAME) == 0) {
|
||||
if (strcmp(n, "ram") == 0) {
|
||||
dev= DEV_RAM;
|
||||
} else
|
||||
if (strcmp(n, "boot") == 0) {
|
||||
dev= DEV_BOOT;
|
||||
} else
|
||||
if (n[0] == 'f' && n[1] == 'd' && numeric(n+2)) {
|
||||
/* Floppy. */
|
||||
tmpdev.device= a2l(n+2);
|
||||
@@ -1270,10 +1179,10 @@ static void apm_perror(char *label, u16_t ax)
|
||||
printf("%s: %s\n", label, str);
|
||||
}
|
||||
|
||||
#define apm_printf(args) printf args
|
||||
#define apm_printf printf
|
||||
#else
|
||||
#define apm_perror(label, ax) ((void)0)
|
||||
#define apm_printf(args)
|
||||
#define apm_printf
|
||||
#endif
|
||||
|
||||
static void off(void)
|
||||
@@ -1295,7 +1204,7 @@ static void off(void)
|
||||
}
|
||||
if (be.bx != (('P' << 8) | 'M'))
|
||||
{
|
||||
apm_printf(("APM signature not found (got 0x%04x)\n", be.bx));
|
||||
apm_printf("APM signature not found (got 0x%04x)\n", be.bx);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1305,13 +1214,13 @@ static void off(void)
|
||||
al= be.ax & 0xff;
|
||||
if (al > 9)
|
||||
al= (al >> 4)*10 + (al & 0xf);
|
||||
apm_printf(("APM version %u.%u%s%s%s%s%s\n",
|
||||
apm_printf("APM version %u.%u%s%s%s%s%s\n",
|
||||
ah, al,
|
||||
(be.cx & 0x1) ? ", 16-bit PM" : "",
|
||||
(be.cx & 0x2) ? ", 32-bit PM" : "",
|
||||
(be.cx & 0x4) ? ", CPU-Idle" : "",
|
||||
(be.cx & 0x8) ? ", APM-disabled" : "",
|
||||
(be.cx & 0x10) ? ", APM-disengaged" : ""));
|
||||
(be.cx & 0x10) ? ", APM-disengaged" : "");
|
||||
|
||||
/* Connect */
|
||||
be.ax= 0x5301; /* APM, Real mode interface connect */
|
||||
@@ -1343,7 +1252,7 @@ static void off(void)
|
||||
al= be.ax & 0xff;
|
||||
if (al > 9)
|
||||
al= (al >> 4)*10 + (al & 0xf);
|
||||
apm_printf(("Got APM connection version %u.%u\n", ah, al));
|
||||
apm_printf("Got APM connection version %u.%u\n", ah, al);
|
||||
|
||||
/* Enable */
|
||||
be.ax= 0x5308; /* APM, Enable/disable power management */
|
||||
@@ -1373,8 +1282,8 @@ static void off(void)
|
||||
goto disco;
|
||||
}
|
||||
|
||||
apm_printf(("Power off sequence successfully completed.\n\n"));
|
||||
apm_printf(("Ha, ha, just kidding!\n"));
|
||||
apm_printf("Power off sequence successfully completed.\n\n");
|
||||
apm_printf("Ha, ha, just kidding!\n");
|
||||
|
||||
disco:
|
||||
/* Disconnect */
|
||||
@@ -1434,19 +1343,17 @@ int exec_bootstrap(void)
|
||||
return r;
|
||||
|
||||
bootstrap(device, active);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void boot_device(char *devname)
|
||||
void boot_device(char *devname)
|
||||
/* Boot the device named by devname. */
|
||||
{
|
||||
dev_t dev= name2dev(devname);
|
||||
int save_dev= device;
|
||||
int r;
|
||||
const char *err;
|
||||
char *err;
|
||||
|
||||
if (tmpdev.device < 0) {
|
||||
/* FIXME: clearer error message. */
|
||||
if (dev != -1) printf("Can't boot from %s\n", devname);
|
||||
return;
|
||||
}
|
||||
@@ -1464,42 +1371,33 @@ static void boot_device(char *devname)
|
||||
(void) dev_open();
|
||||
}
|
||||
|
||||
static void ctty(char *line)
|
||||
void ctty(char *line)
|
||||
{
|
||||
if (line == nil) {
|
||||
serial_line = -1;
|
||||
} else if (between('0', line[0], '3') && line[1] == 0) {
|
||||
serial_line = line[0] - '0';
|
||||
if (between('0', line[0], '3') && line[1] == 0) {
|
||||
serial_init(line[0] - '0');
|
||||
} else {
|
||||
printf("Bad serial line number: %s\n", line);
|
||||
return;
|
||||
}
|
||||
serial_init(serial_line);
|
||||
}
|
||||
|
||||
#else /* DOS */
|
||||
|
||||
static void boot_device(char *devname)
|
||||
void boot_device(char *devname)
|
||||
/* No booting of other devices under DOS. */
|
||||
{
|
||||
printf("Can't boot devices under DOS\n");
|
||||
}
|
||||
|
||||
static void ctty(char *line)
|
||||
void ctty(char *line)
|
||||
/* Don't know how to handle serial lines under DOS. */
|
||||
{
|
||||
printf("No serial line support under DOS\n");
|
||||
}
|
||||
|
||||
reset()
|
||||
{
|
||||
printf("No reset support under DOS\n");
|
||||
}
|
||||
|
||||
#endif /* DOS */
|
||||
#endif /* BIOS */
|
||||
|
||||
static void ls(char *dir)
|
||||
void ls(char *dir)
|
||||
/* List the contents of a directory. */
|
||||
{
|
||||
ino_t ino;
|
||||
@@ -1518,24 +1416,24 @@ static void ls(char *dir)
|
||||
}
|
||||
(void) r_readdir(name); /* Skip ".." too. */
|
||||
|
||||
while (r_readdir(name) != 0) printf("%s/%s\n", dir, name);
|
||||
while ((ino= r_readdir(name)) != 0) printf("%s/%s\n", dir, name);
|
||||
}
|
||||
|
||||
static u32_t milli_time(void)
|
||||
u32_t milli_time(void)
|
||||
{
|
||||
return get_tick() * MSEC_PER_TICK;
|
||||
}
|
||||
|
||||
static u32_t milli_since(u32_t base)
|
||||
u32_t milli_since(u32_t base)
|
||||
{
|
||||
return (milli_time() + (TICKS_PER_DAY*MSEC_PER_TICK) - base)
|
||||
% (TICKS_PER_DAY*MSEC_PER_TICK);
|
||||
}
|
||||
|
||||
static char *Thandler;
|
||||
static u32_t Tbase, Tcount;
|
||||
char *Thandler;
|
||||
u32_t Tbase, Tcount;
|
||||
|
||||
static void unschedule(void)
|
||||
void unschedule(void)
|
||||
/* Invalidate a waiting command. */
|
||||
{
|
||||
alarm(0);
|
||||
@@ -1546,7 +1444,7 @@ static void unschedule(void)
|
||||
}
|
||||
}
|
||||
|
||||
static void schedule(long msec, char *cmd)
|
||||
void schedule(long msec, char *cmd)
|
||||
/* Schedule command at a certain time from now. */
|
||||
{
|
||||
unschedule();
|
||||
@@ -1562,7 +1460,7 @@ int expired(void)
|
||||
return (Thandler != nil && milli_since(Tbase) >= Tcount);
|
||||
}
|
||||
|
||||
void delay(const char *msec)
|
||||
void delay(char *msec)
|
||||
/* Delay for a given time. */
|
||||
{
|
||||
u32_t base, count;
|
||||
@@ -1577,7 +1475,7 @@ void delay(const char *msec)
|
||||
} while (!interrupt() && !expired() && milli_since(base) < count);
|
||||
}
|
||||
|
||||
static enum whatfun { NOFUN, SELECT, DEFFUN, USERFUN } menufun(const environment *e)
|
||||
enum whatfun { NOFUN, SELECT, DEFFUN, USERFUN } menufun(environment *e)
|
||||
{
|
||||
if (!(e->flags & E_FUNCTION) || e->arg[0] == 0) return NOFUN;
|
||||
if (e->arg[1] != ',') return SELECT;
|
||||
@@ -1612,7 +1510,6 @@ void menu(void)
|
||||
case SELECT:
|
||||
printf(" %c Select %s kernel\n", e->arg[0],e->name);
|
||||
break;
|
||||
case NOFUN:
|
||||
default:;
|
||||
}
|
||||
}
|
||||
@@ -1631,8 +1528,6 @@ void menu(void)
|
||||
case USERFUN:
|
||||
case SELECT:
|
||||
if (c == e->arg[0]) choice= e->value;
|
||||
case NOFUN:
|
||||
break;
|
||||
}
|
||||
}
|
||||
} while (choice == nil);
|
||||
@@ -1683,12 +1578,12 @@ void help(void)
|
||||
}
|
||||
}
|
||||
|
||||
static void execute(void)
|
||||
void execute(void)
|
||||
/* Get one command from the command chain and execute it. */
|
||||
{
|
||||
token *second, *third, *fourth, *sep;
|
||||
char *name;
|
||||
enum resnames res;
|
||||
int res;
|
||||
size_t n= 0;
|
||||
|
||||
if (err) {
|
||||
@@ -1831,7 +1726,7 @@ static void execute(void)
|
||||
putch('\n');
|
||||
break;
|
||||
case 'v':
|
||||
printf("%s", version);
|
||||
printf(version);
|
||||
break;
|
||||
case 'c':
|
||||
clear_screen();
|
||||
@@ -1902,15 +1797,6 @@ static void execute(void)
|
||||
case R_HELP: help(); ok= 1; break;
|
||||
case R_EXIT: exit(0);
|
||||
case R_OFF: off(); ok= 1; break;
|
||||
case R_CTTY: ctty(nil); ok= 1; break;
|
||||
case R_RESET: reset(); ok= 1; break;
|
||||
|
||||
case R_NULL:
|
||||
case R_ECHO:
|
||||
case R_TRAP:
|
||||
case R_UNSET:
|
||||
/* Handled after the switch. */
|
||||
break;
|
||||
}
|
||||
|
||||
/* Command to check bootparams: */
|
||||
@@ -1951,7 +1837,7 @@ int run_trailer(void)
|
||||
return !err;
|
||||
}
|
||||
|
||||
static void monitor(void)
|
||||
void monitor(void)
|
||||
/* Read a line and tokenize it. */
|
||||
{
|
||||
char *line;
|
||||
@@ -1968,9 +1854,13 @@ static void monitor(void)
|
||||
|
||||
#if BIOS
|
||||
|
||||
unsigned char cdspec[25];
|
||||
void bootcdinfo(u32_t, int *, int drive);
|
||||
|
||||
void boot(void)
|
||||
/* Load Minix and start it, among other things. */
|
||||
{
|
||||
|
||||
/* Initialize tables. */
|
||||
initialize();
|
||||
|
||||
@@ -1990,7 +1880,7 @@ void boot(void)
|
||||
|
||||
#if UNIX
|
||||
|
||||
int main(int argc, char **argv)
|
||||
void main(int argc, char **argv)
|
||||
/* Do not load or start anything, just edit parameters. */
|
||||
{
|
||||
int i;
|
||||
@@ -2019,7 +1909,8 @@ int main(int argc, char **argv)
|
||||
fatal(bootdev.name);
|
||||
|
||||
/* Check if it is a bootable Minix device. */
|
||||
if (readsectors(mon2abs(bootcode), lowsec, 1) != 0) {
|
||||
if (readsectors(mon2abs(bootcode), lowsec, 1) != 0
|
||||
|| memcmp(bootcode, boot_magic, sizeof(boot_magic)) != 0) {
|
||||
fprintf(stderr, "edparams: %s: not a bootable Minix device\n",
|
||||
bootdev.name);
|
||||
exit(1);
|
||||
@@ -2062,14 +1953,9 @@ int main(int argc, char **argv)
|
||||
monitor();
|
||||
}
|
||||
exit(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
reset() { }
|
||||
|
||||
#endif /* UNIX */
|
||||
|
||||
/*
|
||||
* $PchId: boot.c,v 1.14 2002/02/27 19:46:14 philip Exp $
|
||||
*/
|
||||
|
||||
|
||||
33
boot/boot.h
Normal file → Executable file
33
boot/boot.h
Normal file → Executable file
@@ -58,29 +58,14 @@ EXTERN u32_t caddr, daddr; /* Code and data address of the boot program. */
|
||||
EXTERN u32_t runsize; /* Size of this program. */
|
||||
|
||||
EXTERN u16_t device; /* Drive being booted from. */
|
||||
EXTERN u16_t cddevice; /* Drive that is CD if known. */
|
||||
|
||||
#define CDNAME "cd" /* Name of the CD device. */
|
||||
|
||||
typedef struct { /* One chunk of free memory. */
|
||||
u32_t base; /* Start byte. */
|
||||
u32_t size; /* Number of bytes. */
|
||||
} memory;
|
||||
|
||||
typedef struct { /* One chunk of free memory. */
|
||||
u32_t base_lo; /* Start byte. */
|
||||
u32_t base_hi;
|
||||
u32_t size_lo; /* Number of bytes. */
|
||||
u32_t size_hi; /* Number of bytes. */
|
||||
u32_t type;
|
||||
u32_t acpi_attrs;
|
||||
} e820_memory;
|
||||
|
||||
EXTERN memory mem[3]; /* List of available memory. */
|
||||
EXTERN e820_memory emem[16]; /* List of available memory. */
|
||||
EXTERN int mem_entries;
|
||||
EXTERN int mon_return; /* Monitor stays in memory? */
|
||||
EXTERN int cdbooted; /* Did we boot from CD? (Set by boothead.s.) */
|
||||
|
||||
typedef struct bios_env
|
||||
{
|
||||
@@ -104,7 +89,7 @@ void raw_copy(u32_t dstaddr, u32_t srcaddr, u32_t count);
|
||||
/* Copy bytes from anywhere to anywhere. */
|
||||
u16_t get_word(u32_t addr);
|
||||
/* Get a word from anywhere. */
|
||||
void put_word(u32_t addr, u16_t word);
|
||||
void put_word(u32_t addr, U16_t word);
|
||||
/* Put a word anywhere. */
|
||||
void relocate(void);
|
||||
/* Switch to a copy of this program. */
|
||||
@@ -112,13 +97,10 @@ int dev_open(void), dev_close(void);
|
||||
/* Open device and determine params / close device. */
|
||||
int dev_boundary(u32_t sector);
|
||||
/* True if sector is on a track boundary. */
|
||||
int readsectors(u32_t bufaddr, u32_t sector, u8_t count);
|
||||
int readsectors(u32_t bufaddr, u32_t sector, U8_t count);
|
||||
/* Read 1 or more sectors from "device". */
|
||||
int writesectors(u32_t bufaddr, u32_t sector, u8_t count);
|
||||
int writesectors(u32_t bufaddr, u32_t sector, U8_t count);
|
||||
/* Write 1 or more sectors to "device". */
|
||||
|
||||
int biosreadsectors(u32_t bufaddr, u32_t sector, u8_t count);
|
||||
|
||||
int getch(void);
|
||||
/* Read a keypress. */
|
||||
void scan_keyboard(void);
|
||||
@@ -178,9 +160,8 @@ typedef struct environment {
|
||||
|
||||
EXTERN environment *env; /* Lists the environment. */
|
||||
|
||||
char *b_value(const char *name); /* Get/set the value of a variable. */
|
||||
char *b_value(char *name); /* Get/set the value of a variable. */
|
||||
int b_setvar(int flags, char *name, char *value);
|
||||
void b_unset(const char *name);
|
||||
|
||||
void parse_code(char *code); /* Parse boot monitor commands. */
|
||||
|
||||
@@ -198,9 +179,9 @@ void readerr(off_t sec, int err);
|
||||
/* Report a read error. */
|
||||
char *ul2a(u32_t n, unsigned b), *ul2a10(u32_t n);
|
||||
/* Transform u32_t to ASCII at base b or base 10. */
|
||||
long a2l(const char *a);
|
||||
long a2l(char *a);
|
||||
/* Cheap atol(). */
|
||||
unsigned a2x(const char *a);
|
||||
unsigned a2x(char *a);
|
||||
/* ASCII to hex. */
|
||||
dev_t name2dev(char *name);
|
||||
/* Translate a device name to a device number. */
|
||||
@@ -224,7 +205,7 @@ EXTERN char *drun; /* Initial command from DOS command line. */
|
||||
#endif
|
||||
|
||||
void readblock(off_t, char *, int);
|
||||
void delay(const char *);
|
||||
void delay(char *);
|
||||
|
||||
/*
|
||||
* $PchId: boot.h,v 1.12 2002/02/27 19:42:45 philip Exp $
|
||||
|
||||
33
boot/bootblock.s
Normal file → Executable file
33
boot/bootblock.s
Normal file → Executable file
@@ -1,4 +1,3 @@
|
||||
#
|
||||
! Bootblock 1.5 - Minix boot block. Author: Kees J. Bot
|
||||
! 21 Dec 1991
|
||||
!
|
||||
@@ -19,21 +18,15 @@
|
||||
|
||||
LOADOFF = 0x7C00 ! 0x0000:LOADOFF is where this code is loaded
|
||||
BOOTSEG = 0x1000 ! Secondary boot code segment.
|
||||
#ifdef CDBOOT
|
||||
BOOTOFF = 0x0050 ! Offset into /boot above header
|
||||
#else
|
||||
BOOTOFF = 0x0030 ! Offset into /boot above header
|
||||
#endif
|
||||
BUFFER = 0x0600 ! First free memory
|
||||
#ifndef CDBOOT /* just constants, but make no sense for CDs */
|
||||
LOWSEC = 8 ! Offset of logical first sector in partition
|
||||
! table
|
||||
|
||||
! Variables addressed using bp register
|
||||
device = 0 ! The boot device
|
||||
lowsec = 2 ! Offset of boot partition within drive
|
||||
secpcyl = 6 ! Sectors per cylinder = heads * sectors
|
||||
#endif
|
||||
device = 0 ! The boot device
|
||||
|
||||
.text
|
||||
|
||||
@@ -58,21 +51,18 @@ boot:
|
||||
|
||||
mov di, #LOADOFF+sectors ! char *di = sectors;
|
||||
|
||||
#ifndef CDBOOT
|
||||
testb dl, dl ! Winchester disks if dl >= 0x80
|
||||
jge floppy
|
||||
#endif
|
||||
|
||||
winchester:
|
||||
|
||||
#ifndef CDBOOT
|
||||
! Get the offset of the first sector of the boot partition from the partition
|
||||
! table. The table is found at es:si, the lowsec parameter at offset LOWSEC.
|
||||
|
||||
eseg
|
||||
les ax, LOWSEC(si) ! es:ax = LOWSEC+2(si):LOWSEC(si)
|
||||
mov lowsec+0(bp), ax ! Low 16 bits of partitions first sector
|
||||
mov lowsec+2(bp), es ! High 16 bits of partitions first sector
|
||||
mov lowsec+0(bp), ax ! Low 16 bits of partition's first sector
|
||||
mov lowsec+2(bp), es ! High 16 bits of partition's first sector
|
||||
|
||||
! Get the drive parameters, the number of sectors is bluntly written into the
|
||||
! floppy disk sectors/track array.
|
||||
@@ -82,10 +72,8 @@ winchester:
|
||||
andb cl, #0x3F ! cl = max sector number (1-origin)
|
||||
movb (di), cl ! Number of sectors per track
|
||||
incb dh ! dh = 1 + max head number (0-origin)
|
||||
#endif
|
||||
jmp loadboot
|
||||
|
||||
#ifndef CDBOOT
|
||||
! Floppy:
|
||||
! Execute three read tests to determine the drive type. Test for each floppy
|
||||
! type by reading the last sector on the first track. If it fails, try a type
|
||||
@@ -113,16 +101,13 @@ floppy: xorb ah, ah ! Reset drive
|
||||
jc next ! Error, try the next floppy type
|
||||
|
||||
success:movb dh, #2 ! Load number of heads for multiply
|
||||
#endif
|
||||
|
||||
loadboot:
|
||||
! Load /boot from the boot device
|
||||
|
||||
#ifndef CDBOOT
|
||||
movb al, (di) ! al = (di) = sectors per track
|
||||
mulb dh ! dh = heads, ax = heads * sectors
|
||||
mov secpcyl(bp), ax ! Sectors per cylinder = heads * sectors
|
||||
#endif
|
||||
|
||||
mov ax, #BOOTSEG ! Segment to load /boot into
|
||||
mov es, ax
|
||||
@@ -132,7 +117,6 @@ load:
|
||||
mov ax, 1(si) ! Get next sector number: low 16 bits
|
||||
movb dl, 3(si) ! Bits 16-23 for your up to 8GB partition
|
||||
xorb dh, dh ! dx:ax = sector within partition
|
||||
#ifndef CDBOOT
|
||||
add ax, lowsec+0(bp)
|
||||
adc dx, lowsec+2(bp)! dx:ax = sector within drive
|
||||
cmp dx, #[1024*255*63-255]>>16 ! Near 8G limit?
|
||||
@@ -152,14 +136,13 @@ load:
|
||||
movb al, (di) ! Sectors per track - Sector number (0-origin)
|
||||
subb al, ah ! = Sectors left on this track
|
||||
cmpb al, (si) ! Compare with # sectors to read
|
||||
jbe read ! Cant read past the end of a cylinder?
|
||||
jbe read ! Can't read past the end of a cylinder?
|
||||
movb al, (si) ! (si) < sectors left on this track
|
||||
read: push ax ! Save al = sectors to read
|
||||
movb ah, #0x02 ! Code for disk read (all registers in use now!)
|
||||
int 0x13 ! Call the BIOS for a read
|
||||
pop cx ! Restore al in cl
|
||||
jmp rdeval
|
||||
#endif
|
||||
bigdisk:
|
||||
movb cl, (si) ! Number of sectors to read
|
||||
push si ! Save si
|
||||
@@ -178,14 +161,6 @@ rdeval:
|
||||
movb al, cl ! Restore al = sectors read
|
||||
addb bh, al ! bx += 2 * al * 256 (add bytes read)
|
||||
addb bh, al ! es:bx = where next sector must be read
|
||||
#ifdef CDBOOT
|
||||
addb bh, al ! For CDs, a sector is 2048 bytes, so
|
||||
addb bh, al ! do this 6 more times to get byte count.
|
||||
addb bh, al
|
||||
addb bh, al
|
||||
addb bh, al
|
||||
addb bh, al
|
||||
#endif
|
||||
add 1(si), ax ! Update address by sectors read
|
||||
adcb 3(si), ah ! Don't forget bits 16-23 (add ah = 0)
|
||||
subb (si), al ! Decrement sector count by sectors read
|
||||
|
||||
120
boot/boothead.s
Normal file → Executable file
120
boot/boothead.s
Normal file → Executable file
@@ -41,35 +41,18 @@
|
||||
.extern _rem_part ! To pass partition info
|
||||
.extern _k_flags ! Special kernel flags
|
||||
.extern _mem ! Free memory list
|
||||
.extern _emem ! Free memory list for E820
|
||||
.extern _mem_entries ! Free memory E820 list entries
|
||||
.extern _cdbooted ! Whether we booted from CD
|
||||
.extern _cddevice ! Whether we booted from CD
|
||||
|
||||
.text
|
||||
|
||||
|
||||
! Set segment registers and stack pointer using the programs own header!
|
||||
! The header is either 32 bytes (short form) or 48 bytes (long form). The
|
||||
! bootblock will jump to address 0x10030 in both cases, calling one of the
|
||||
! two jmpf instructions below.
|
||||
!
|
||||
! CD bootblock jumps to address 0x10050 in both cases.
|
||||
|
||||
jmpf boot, LOADSEG+3 ! Set cs right (skipping long a.out header)
|
||||
.space 11 ! jmpf + 11 = 16 bytes
|
||||
jmpf boot, LOADSEG+2 ! Set cs right (skipping short a.out header)
|
||||
.space 11 ! jmpf + 11 = 16 bytes
|
||||
jmpf cdboot, LOADSEG+3
|
||||
.space 11
|
||||
jmpf cdboot, LOADSEG+2
|
||||
.space 11
|
||||
cdboot:
|
||||
mov bx, #1
|
||||
jmp commonboot
|
||||
boot:
|
||||
mov bx, #0
|
||||
commonboot:
|
||||
mov ax, #LOADSEG
|
||||
mov ds, ax ! ds = header
|
||||
|
||||
@@ -113,7 +96,6 @@ sepID:
|
||||
mov _device, dx ! Boot device (probably 0x00 or 0x80)
|
||||
mov _rem_part+0, si ! Remote partition table offset
|
||||
pop _rem_part+2 ! and segment (saved es)
|
||||
mov _cdbooted, bx ! Booted from CD? (bx set above)
|
||||
|
||||
! Remember the current video mode for restoration on exit.
|
||||
movb ah, #0x0F ! Get current video mode
|
||||
@@ -145,64 +127,6 @@ sepID:
|
||||
mov _runsize+0, ax
|
||||
mov _runsize+2, dx ! 32 bit size of this process
|
||||
|
||||
!Determine memory using the 0xE820 BIOS function if available
|
||||
mov di, #_emem
|
||||
mov 20(di), #1 ! force a valid ACPI 3.X entry
|
||||
|
||||
.data1 o32
|
||||
xor bx, bx ! zero EBX
|
||||
xor bp, bp !zero bp
|
||||
.data1 o32
|
||||
mov dx, e820_magic
|
||||
.data1 o32
|
||||
mov cx, const_24 ! request 24 bytes
|
||||
|
||||
.data1 o32
|
||||
mov ax, const_0xe820
|
||||
int 0x15
|
||||
jc e820_failed
|
||||
|
||||
.data1 o32
|
||||
mov dx, e820_magic
|
||||
.data1 o32
|
||||
cmp dx, ax
|
||||
jne e820_failed
|
||||
|
||||
.data1 o32
|
||||
test bx, bx
|
||||
je e820_failed
|
||||
jmp e820_gotit
|
||||
|
||||
e820_next:
|
||||
.data1 o32
|
||||
mov ax, const_0xe820
|
||||
mov 20(di), #1 ! force a valid ACPI 3.X entry
|
||||
|
||||
.data1 o32
|
||||
mov cx, const_24 ! request 24 bytes
|
||||
int 0x15
|
||||
jc e820_done
|
||||
.data1 o32
|
||||
mov dx, e820_magic
|
||||
|
||||
|
||||
e820_gotit:
|
||||
jcxz e820_skip
|
||||
cmp bp, #16
|
||||
je e820_done ! we have only space for 16 entries
|
||||
inc bp
|
||||
add di, #24
|
||||
e820_skip:
|
||||
.data1 o32
|
||||
test bx, bx
|
||||
jne e820_next
|
||||
|
||||
e820_done:
|
||||
mov _mem_entries, bp
|
||||
jmp memory_detected
|
||||
|
||||
e820_failed:
|
||||
|
||||
! Determine available memory as a list of (base,size) pairs as follows:
|
||||
! mem[0] = low memory, mem[1] = memory between 1M and 16M, mem[2] = memory
|
||||
! above 16M. Last two coalesced into mem[1] if adjacent.
|
||||
@@ -245,8 +169,6 @@ adj_ext:
|
||||
add 14(di), bx ! Add ext mem above 16M to mem below 16M
|
||||
no_ext:
|
||||
|
||||
memory_detected:
|
||||
|
||||
|
||||
! Time to switch to a higher level language (not much higher)
|
||||
call _boot
|
||||
@@ -363,12 +285,10 @@ smallcopy:
|
||||
ext_copy:
|
||||
mov x_dst_desc+2, ax
|
||||
movb x_dst_desc+4, dl ! Set base of destination segment
|
||||
movb x_dst_desc+7, dh
|
||||
mov ax, 8(bp)
|
||||
mov dx, 10(bp)
|
||||
mov x_src_desc+2, ax
|
||||
movb x_src_desc+4, dl ! Set base of source segment
|
||||
movb x_src_desc+7, dh
|
||||
mov si, #x_gdt ! es:si = global descriptor table
|
||||
shr cx, #1 ! Words to move
|
||||
movb ah, #0x87 ! Code for extended memory move
|
||||
@@ -496,8 +416,6 @@ _dev_open:
|
||||
push es
|
||||
push di ! Save registers used by BIOS calls
|
||||
movb dl, _device ! The default device
|
||||
cmpb dl, _cddevice
|
||||
je cdopen
|
||||
cmpb dl, #0x80 ! Floppy < 0x80, winchester >= 0x80
|
||||
jae winchester
|
||||
floppy:
|
||||
@@ -545,10 +463,6 @@ winchester:
|
||||
jc geoerr ! No such drive?
|
||||
andb cl, #0x3F ! cl = max sector number (1-origin)
|
||||
incb dh ! dh = 1 + max head number (0-origin)
|
||||
jmp geoboth
|
||||
cdopen:
|
||||
movb cl, #0x3F ! Think up geometry for CD's
|
||||
movb dh, #0x2
|
||||
geoboth:
|
||||
movb sectors, cl ! Sectors per track
|
||||
movb al, cl ! al = sectors per track
|
||||
@@ -601,20 +515,20 @@ _dev_boundary:
|
||||
neg ax ! ax = (sector % sectors) == 0
|
||||
ret
|
||||
|
||||
! int biosreadsectors(u32_t bufaddr, u32_t sector, u8_t count)
|
||||
! int readsectors(u32_t bufaddr, u32_t sector, u8_t count)
|
||||
! int writesectors(u32_t bufaddr, u32_t sector, u8_t count)
|
||||
! Read/write several sectors from/to disk or floppy. The buffer must
|
||||
! be between 64K boundaries! Count must fit in a byte. The external
|
||||
! variables _device, sectors and secspcyl describe the disk and its
|
||||
! geometry. Returns 0 for success, otherwise the BIOS error code.
|
||||
!
|
||||
.define _biosreadsectors, _writesectors
|
||||
.define _readsectors, _writesectors
|
||||
_writesectors:
|
||||
push bp
|
||||
mov bp, sp
|
||||
movb 13(bp), #0x03 ! Code for a disk write
|
||||
jmp rwsec
|
||||
_biosreadsectors:
|
||||
_readsectors:
|
||||
push bp
|
||||
mov bp, sp
|
||||
movb 13(bp), #0x02 ! Code for a disk read
|
||||
@@ -641,9 +555,6 @@ more: mov ax, 8(bp)
|
||||
mov dx, 10(bp) ! dx:ax = abs sector. Divide it by sectors/cyl
|
||||
cmp dx, #[1024*255*63-255]>>16 ! Near 8G limit?
|
||||
jae bigdisk
|
||||
mov si, _device
|
||||
cmp si, _cddevice ! Is it a CD?
|
||||
je bigdisk ! CD's need extended read.
|
||||
div secspcyl ! ax = cylinder, dx = sector within cylinder
|
||||
xchg ax, dx ! ax = sector within cylinder, dx = cylinder
|
||||
movb ch, dl ! ch = low 8 bits of cylinder
|
||||
@@ -729,7 +640,7 @@ _getch:
|
||||
test ax, ax
|
||||
jnz gotch
|
||||
getch:
|
||||
! hlt ! Play dead until interrupted (see pause())
|
||||
hlt ! Play dead until interrupted (see pause())
|
||||
movb ah, #0x01 ! Keyboard status
|
||||
int 0x16
|
||||
jz 0f ! Nothing typed
|
||||
@@ -830,7 +741,7 @@ nulch: ret
|
||||
! power, or tells an x86 emulator that nothing is happening right now.
|
||||
.define _pause
|
||||
_pause:
|
||||
! hlt
|
||||
hlt
|
||||
ret
|
||||
|
||||
! void set_mode(unsigned mode);
|
||||
@@ -943,9 +854,6 @@ restore_video: ! To restore the video mode on exit
|
||||
_serial_init:
|
||||
mov bx, sp
|
||||
mov dx, 2(bx) ! Line number
|
||||
mov line, #0
|
||||
test dx, dx ! Off if line number < 0
|
||||
js 0f
|
||||
push ds
|
||||
xor ax, ax
|
||||
mov ds, ax ! Vector and BIOS data segment
|
||||
@@ -1516,11 +1424,6 @@ _scan_keyboard:
|
||||
outb 0x61
|
||||
ret
|
||||
|
||||
.define _reset
|
||||
_reset:
|
||||
lidt idt_zero
|
||||
int 0x3
|
||||
|
||||
.data
|
||||
.ascii "(null)\0" ! Just in case someone follows a null pointer
|
||||
.align 2
|
||||
@@ -1528,8 +1431,6 @@ c60: .data2 60 ! Constants for MUL and DIV
|
||||
c1024: .data2 1024
|
||||
c1080: .data2 1080
|
||||
c19663: .data2 19663
|
||||
idt_zero:
|
||||
.data4 0,0
|
||||
|
||||
! Global descriptor tables.
|
||||
UNSET = 0 ! Must be computed
|
||||
@@ -1596,15 +1497,6 @@ p_mcs_desc:
|
||||
.data2 0xFFFF, UNSET
|
||||
.data1 UNSET, 0x9A, 0x00, 0x00
|
||||
|
||||
e820_magic:
|
||||
! .data1 0x53, 0x4D, 0x41, 0x50
|
||||
.data1 0x50, 0x41, 0x4D, 0x53
|
||||
const_24:
|
||||
.data1 0x18, 0x0, 0x0, 0x0
|
||||
const_0xe820:
|
||||
.data2 0xe820
|
||||
|
||||
|
||||
.bss
|
||||
.comm old_vid_mode, 2 ! Video mode at startup
|
||||
.comm cur_vid_mode, 2 ! Current video mode
|
||||
@@ -1617,3 +1509,5 @@ const_0xe820:
|
||||
.comm bus, 2 ! Saved return value of _get_bus
|
||||
.comm unchar, 2 ! Char returned by ungetch(c)
|
||||
.comm line, 2 ! Serial line I/O port to copy console I/O to.
|
||||
|
||||
|
||||
|
||||
216
boot/bootimage.c
Normal file → Executable file
216
boot/bootimage.c
Normal file → Executable file
@@ -18,28 +18,14 @@
|
||||
#include <minix/const.h>
|
||||
#include <minix/type.h>
|
||||
#include <minix/syslib.h>
|
||||
#include <minix/tty.h>
|
||||
#include <sys/video.h>
|
||||
#include <kernel/const.h>
|
||||
#include <kernel/type.h>
|
||||
#include <machine/partition.h>
|
||||
#include <ibm/partition.h>
|
||||
#include "rawfs.h"
|
||||
#include "image.h"
|
||||
#include "boot.h"
|
||||
|
||||
static int block_size = 0;
|
||||
static int verboseboot = VERBOSEBOOT_QUIET;
|
||||
|
||||
#define DEBUG_PRINT(params, level) do { \
|
||||
if (verboseboot >= (level)) printf params; } while (0)
|
||||
#define DEBUGBASIC(params) DEBUG_PRINT(params, VERBOSEBOOT_BASIC)
|
||||
#define DEBUGEXTRA(params) DEBUG_PRINT(params, VERBOSEBOOT_EXTRA)
|
||||
#define DEBUGMAX(params) DEBUG_PRINT(params, VERBOSEBOOT_MAX)
|
||||
|
||||
extern int serial_line;
|
||||
extern u16_t vid_port; /* Video i/o port. */
|
||||
extern u32_t vid_mem_base; /* Video memory base address. */
|
||||
extern u32_t vid_mem_size; /* Video memory size. */
|
||||
|
||||
#define click_shift clck_shft /* 7 char clash with click_size. */
|
||||
|
||||
@@ -53,14 +39,13 @@ extern u32_t vid_mem_size; /* Video memory size. */
|
||||
#define K_INT86 0x0040 /* Requires generic INT support. */
|
||||
#define K_MEML 0x0080 /* Pass a list of free memory. */
|
||||
#define K_BRET 0x0100 /* New monitor code on shutdown in boot parameters. */
|
||||
#define K_KHIGH 0x0200 /* Load kernel in extended memory. */
|
||||
#define K_ALL 0x03FF /* All feature bits this monitor supports. */
|
||||
#define K_ALL 0x01FF /* All feature bits this monitor supports. */
|
||||
|
||||
|
||||
/* Data about the different processes. */
|
||||
|
||||
#define PROCESS_MAX 16 /* Must match the space in kernel/mpx.x */
|
||||
#define KERNEL_IDX 0 /* The first process is the kernel. */
|
||||
#define KERNEL 0 /* The first process is the kernel. */
|
||||
#define FS 2 /* The third must be fs. */
|
||||
|
||||
struct process { /* Per-process memory adresses. */
|
||||
@@ -85,7 +70,7 @@ int n_procs; /* Number of processes. */
|
||||
|
||||
#define between(a, c, z) ((unsigned) ((c) - (a)) <= ((z) - (a)))
|
||||
|
||||
void pretty_image(const char *image)
|
||||
void pretty_image(char *image)
|
||||
/* Pretty print the name of the image to load. Translate '/' and '_' to
|
||||
* space, first letter goes uppercase. An 'r' before a digit prints as
|
||||
* 'revision'. E.g. 'minix/1.6.16r10' -> 'Minix 1.6.16 revision 10'.
|
||||
@@ -110,20 +95,16 @@ void pretty_image(const char *image)
|
||||
}
|
||||
}
|
||||
|
||||
#define RAW_ALIGN 16
|
||||
#define BUFSIZE_ZEROS 128
|
||||
|
||||
void raw_clear(u32_t addr, u32_t count)
|
||||
/* Clear "count" bytes at absolute address "addr". */
|
||||
{
|
||||
static char zerosdata[BUFSIZE_ZEROS + RAW_ALIGN];
|
||||
char *zeros = zerosdata + RAW_ALIGN - (unsigned) &zerosdata % RAW_ALIGN;
|
||||
static char zeros[128];
|
||||
u32_t dst;
|
||||
u32_t zct;
|
||||
|
||||
zct= BUFSIZE_ZEROS;
|
||||
zct= sizeof(zeros);
|
||||
if (zct > count) zct= count;
|
||||
raw_copy(addr, mon2abs(zeros), zct);
|
||||
raw_copy(addr, mon2abs(&zeros), zct);
|
||||
count-= zct;
|
||||
|
||||
while (count > 0) {
|
||||
@@ -213,7 +194,7 @@ void patch_sizes(void)
|
||||
|
||||
/* Patch text and data sizes of the processes into kernel data space.
|
||||
*/
|
||||
doff= process[KERNEL_IDX].data + P_SIZ_OFF;
|
||||
doff= process[KERNEL].data + P_SIZ_OFF;
|
||||
|
||||
for (i= 0; i < n_procs; i++) {
|
||||
procp= &process[i];
|
||||
@@ -235,7 +216,7 @@ void patch_sizes(void)
|
||||
put_word(process[FS].data + P_INIT_OFF+4, data_size);
|
||||
}
|
||||
|
||||
int selected(const char *name)
|
||||
int selected(char *name)
|
||||
/* True iff name has no label or the proper label. */
|
||||
{
|
||||
char *colon, *label;
|
||||
@@ -250,7 +231,7 @@ int selected(const char *name)
|
||||
return cmp == 0;
|
||||
}
|
||||
|
||||
static u32_t proc_size(const struct image_header *hdr)
|
||||
u32_t proc_size(struct image_header *hdr)
|
||||
/* Return the size of a process in sectors as found in an image. */
|
||||
{
|
||||
u32_t len= hdr->process.a_text;
|
||||
@@ -294,10 +275,9 @@ char *get_sector(u32_t vsec)
|
||||
u32_t sec;
|
||||
int r;
|
||||
#define SECBUFS 16
|
||||
static char bufdata[SECBUFS * SECTOR_SIZE + RAW_ALIGN];
|
||||
static char buf[SECBUFS * SECTOR_SIZE];
|
||||
static size_t count; /* Number of sectors in the buffer. */
|
||||
static u32_t bufsec; /* First Sector now in the buffer. */
|
||||
char *buf = bufdata + RAW_ALIGN - (unsigned) &bufdata % RAW_ALIGN;
|
||||
|
||||
if (vsec == 0) count= 0; /* First sector; initialize. */
|
||||
|
||||
@@ -378,20 +358,10 @@ int get_segment(u32_t *vsec, long *size, u32_t *addr, u32_t limit)
|
||||
if ((buf= get_sector((*vsec)++)) == nil) return 0;
|
||||
cnt= SECTOR_SIZE;
|
||||
}
|
||||
if (*addr + click_size > limit)
|
||||
{
|
||||
DEBUGEXTRA(("get_segment: out of memory; "
|
||||
"addr=0x%lx; limit=0x%lx; size=%lx\n",
|
||||
*addr, limit, size));
|
||||
errno= ENOMEM;
|
||||
return 0;
|
||||
}
|
||||
if (*addr + click_size > limit) { errno= ENOMEM; return 0; }
|
||||
n= click_size;
|
||||
if (n > cnt) n= cnt;
|
||||
DEBUGMAX(("raw_copy(0x%lx, 0x%lx/0x%x, 0x%lx)... ",
|
||||
*addr, mon2abs(buf), buf, n));
|
||||
raw_copy(*addr, mon2abs(buf), n);
|
||||
DEBUGMAX(("done\n"));
|
||||
*addr+= n;
|
||||
*size-= n;
|
||||
buf+= n;
|
||||
@@ -400,76 +370,35 @@ int get_segment(u32_t *vsec, long *size, u32_t *addr, u32_t limit)
|
||||
|
||||
/* Zero extend to a click. */
|
||||
n= align(*addr, click_size) - *addr;
|
||||
DEBUGMAX(("raw_clear(0x%lx, 0x%lx)... ", *addr, n));
|
||||
raw_clear(*addr, n);
|
||||
DEBUGMAX(("done\n"));
|
||||
*addr+= n;
|
||||
*size-= n;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void restore_screen(void)
|
||||
{
|
||||
struct boot_tty_info boot_tty_info;
|
||||
u32_t info_location;
|
||||
#define LINES 25
|
||||
#define CHARS 80
|
||||
static u16_t consolescreen[LINES][CHARS];
|
||||
|
||||
/* Try and find out what the main console was displaying
|
||||
* by looking into video memory.
|
||||
*/
|
||||
|
||||
info_location = vid_mem_base+vid_mem_size-sizeof(boot_tty_info);
|
||||
raw_copy(mon2abs(&boot_tty_info), info_location,
|
||||
sizeof(boot_tty_info));
|
||||
|
||||
if(boot_tty_info.magic == TTYMAGIC) {
|
||||
if((boot_tty_info.flags & (BTIF_CONSORIGIN|BTIF_CONSCURSOR)) ==
|
||||
(BTIF_CONSORIGIN|BTIF_CONSCURSOR)) {
|
||||
int line;
|
||||
raw_copy(mon2abs(consolescreen),
|
||||
vid_mem_base + boot_tty_info.consorigin,
|
||||
sizeof(consolescreen));
|
||||
clear_screen();
|
||||
for(line = 0; line < LINES; line++) {
|
||||
int ch;
|
||||
for(ch = 0; ch < CHARS; ch++) {
|
||||
u16_t newch = consolescreen[line][ch] & BYTE;
|
||||
if(newch < ' ') newch = ' ';
|
||||
putch(newch);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void exec_image(char *image)
|
||||
/* Get a Minix image into core, patch it up and execute. */
|
||||
{
|
||||
char *delayvalue;
|
||||
int i;
|
||||
struct image_header hdr;
|
||||
char *buf;
|
||||
u32_t vsec, addr, limit, aout, n, totalmem = 0;
|
||||
u32_t vsec, addr, limit, aout, n;
|
||||
struct process *procp; /* Process under construction. */
|
||||
long a_text, a_data, a_bss, a_stack;
|
||||
int banner= 0;
|
||||
long processor= a2l(b_value("processor"));
|
||||
u16_t kmagic, mode;
|
||||
u16_t mode;
|
||||
char *console;
|
||||
char params[SECTOR_SIZE];
|
||||
extern char *sbrk(int);
|
||||
char *verb;
|
||||
|
||||
/* The stack is pretty deep here, so check if heap and stack collide. */
|
||||
(void) sbrk(0);
|
||||
|
||||
if ((verb= b_value(VERBOSEBOOTVARNAME)) != nil)
|
||||
verboseboot = a2l(verb);
|
||||
|
||||
printf("\nLoading ");
|
||||
pretty_image(image);
|
||||
printf(".\n");
|
||||
printf(".\n\n");
|
||||
|
||||
vsec= 0; /* Load this sector from image next. */
|
||||
addr= mem[0].base; /* Into this memory block. */
|
||||
@@ -484,8 +413,6 @@ void exec_image(char *image)
|
||||
|
||||
/* Read the many different processes: */
|
||||
for (i= 0; vsec < image_size; i++) {
|
||||
u32_t startaddr;
|
||||
startaddr = addr;
|
||||
if (i == PROCESS_MAX) {
|
||||
printf("There are more then %d programs in %s\n",
|
||||
PROCESS_MAX, image);
|
||||
@@ -495,7 +422,6 @@ void exec_image(char *image)
|
||||
procp= &process[i];
|
||||
|
||||
/* Read header. */
|
||||
DEBUGEXTRA(("Reading header... "));
|
||||
for (;;) {
|
||||
if ((buf= get_sector(vsec++)) == nil) return;
|
||||
|
||||
@@ -509,7 +435,6 @@ void exec_image(char *image)
|
||||
/* Bad label, skip this process. */
|
||||
vsec+= proc_size(&hdr);
|
||||
}
|
||||
DEBUGEXTRA(("done\n"));
|
||||
|
||||
/* Sanity check: an 8086 can't run a 386 kernel. */
|
||||
if (hdr.process.a_cpu == A_I80386 && processor < 386) {
|
||||
@@ -520,38 +445,25 @@ void exec_image(char *image)
|
||||
}
|
||||
|
||||
/* Get the click shift from the kernel text segment. */
|
||||
if (i == KERNEL_IDX) {
|
||||
if (i == KERNEL) {
|
||||
if (!get_clickshift(vsec, &hdr)) return;
|
||||
addr= align(addr, click_size);
|
||||
|
||||
/* big kernels must be loaded into extended memory */
|
||||
if (k_flags & K_KHIGH) {
|
||||
addr= mem[1].base;
|
||||
limit= mem[1].base + mem[1].size;
|
||||
}
|
||||
}
|
||||
|
||||
/* Save a copy of the header for the kernel, with a_syms
|
||||
* misused as the address where the process is loaded at.
|
||||
*/
|
||||
DEBUGEXTRA(("raw_copy(0x%lx, 0x%lx, 0x%x)... ",
|
||||
aout + i * A_MINHDR, mon2abs(&hdr.process), A_MINHDR));
|
||||
hdr.process.a_syms= addr;
|
||||
raw_copy(aout + i * A_MINHDR, mon2abs(&hdr.process), A_MINHDR);
|
||||
DEBUGEXTRA(("done\n"));
|
||||
|
||||
if (!banner) {
|
||||
DEBUGBASIC((" cs ds text data bss"));
|
||||
if (k_flags & K_CHMEM) DEBUGBASIC((" stack"));
|
||||
DEBUGBASIC(("\n"));
|
||||
printf(" cs ds text data bss");
|
||||
if (k_flags & K_CHMEM) printf(" stack");
|
||||
putch('\n');
|
||||
banner= 1;
|
||||
}
|
||||
|
||||
/* Segment sizes. */
|
||||
DEBUGEXTRA(("a_text=0x%lx; a_data=0x%lx; a_bss=0x%lx; a_flags=0x%x)\n",
|
||||
hdr.process.a_text, hdr.process.a_data,
|
||||
hdr.process.a_bss, hdr.process.a_flags));
|
||||
|
||||
a_text= hdr.process.a_text;
|
||||
a_data= hdr.process.a_data;
|
||||
a_bss= hdr.process.a_bss;
|
||||
@@ -575,12 +487,7 @@ void exec_image(char *image)
|
||||
/* Separate I&D: two segments. Common I&D: only one. */
|
||||
if (hdr.process.a_flags & A_SEP) {
|
||||
/* Read the text segment. */
|
||||
DEBUGEXTRA(("get_segment(0x%lx, 0x%lx, 0x%lx, 0x%lx)\n",
|
||||
vsec, a_text, addr, limit));
|
||||
if (!get_segment(&vsec, &a_text, &addr, limit)) return;
|
||||
DEBUGEXTRA(("get_segment done vsec=0x%lx a_text=0x%lx "
|
||||
"addr=0x%lx\n",
|
||||
vsec, a_text, addr));
|
||||
|
||||
/* The data segment follows. */
|
||||
procp->ds= addr;
|
||||
@@ -593,21 +500,20 @@ void exec_image(char *image)
|
||||
a_data+= a_text;
|
||||
}
|
||||
|
||||
printf("%07lx %07lx %8ld %8ld %8ld",
|
||||
procp->cs, procp->ds,
|
||||
hdr.process.a_text, hdr.process.a_data,
|
||||
hdr.process.a_bss
|
||||
);
|
||||
if (k_flags & K_CHMEM) printf(" %8ld", a_stack);
|
||||
|
||||
printf(" %s\n", hdr.name);
|
||||
|
||||
/* Read the data segment. */
|
||||
DEBUGEXTRA(("get_segment(0x%lx, 0x%lx, 0x%lx, 0x%lx)\n",
|
||||
vsec, a_data, addr, limit));
|
||||
if (!get_segment(&vsec, &a_data, &addr, limit)) return;
|
||||
DEBUGEXTRA(("get_segment done vsec=0x%lx a_data=0x%lx "
|
||||
"addr=0x%lx\n",
|
||||
vsec, a_data, addr));
|
||||
|
||||
/* Make space for bss and stack unless... */
|
||||
if (i != KERNEL_IDX && (k_flags & K_CLAIM)) a_bss= a_stack= 0;
|
||||
|
||||
DEBUGBASIC(("%07lx %07lx %8ld %8ld %8ld",
|
||||
procp->cs, procp->ds, hdr.process.a_text,
|
||||
hdr.process.a_data, hdr.process.a_bss));
|
||||
if (k_flags & K_CHMEM) DEBUGBASIC((" %8ld", a_stack));
|
||||
if (i != KERNEL && (k_flags & K_CLAIM)) a_bss= a_stack= 0;
|
||||
|
||||
/* Note that a_data may be negative now, but we can look at it
|
||||
* as -a_data bss bytes.
|
||||
@@ -619,10 +525,8 @@ void exec_image(char *image)
|
||||
a_bss-= n;
|
||||
|
||||
/* Zero out bss. */
|
||||
DEBUGEXTRA(("\nraw_clear(0x%lx, 0x%lx); limit=0x%lx... ", addr, n, limit));
|
||||
if (addr + n > limit) { errno= ENOMEM; return; }
|
||||
raw_clear(addr, n);
|
||||
DEBUGEXTRA(("done\n"));
|
||||
addr+= n;
|
||||
|
||||
/* And the number of stack clicks. */
|
||||
@@ -636,25 +540,13 @@ void exec_image(char *image)
|
||||
/* Process endpoint. */
|
||||
procp->end= addr;
|
||||
|
||||
if (verboseboot >= VERBOSEBOOT_BASIC)
|
||||
printf(" %s\n", hdr.name);
|
||||
else {
|
||||
u32_t mem;
|
||||
mem = addr-startaddr;
|
||||
printf("%s ", hdr.name);
|
||||
totalmem += mem;
|
||||
}
|
||||
|
||||
if (i == 0 && (k_flags & (K_HIGH | K_KHIGH)) == K_HIGH) {
|
||||
if (i == 0 && (k_flags & K_HIGH)) {
|
||||
/* Load the rest in extended memory. */
|
||||
addr= mem[1].base;
|
||||
limit= mem[1].base + mem[1].size;
|
||||
}
|
||||
}
|
||||
|
||||
if (verboseboot < VERBOSEBOOT_BASIC)
|
||||
printf("(%luk)\n", totalmem/1024);
|
||||
|
||||
if ((n_procs= i) == 0) {
|
||||
printf("There are no programs in %s\n", image);
|
||||
errno= 0;
|
||||
@@ -662,19 +554,14 @@ void exec_image(char *image)
|
||||
}
|
||||
|
||||
/* Check the kernel magic number. */
|
||||
raw_copy(mon2abs(&kmagic),
|
||||
process[KERNEL_IDX].data + MAGIC_OFF, sizeof(kmagic));
|
||||
if (kmagic != KERNEL_D_MAGIC) {
|
||||
printf("Kernel magic number is incorrect (0x%x@0x%lx)\n",
|
||||
kmagic, process[KERNEL_IDX].data + MAGIC_OFF);
|
||||
if (get_word(process[KERNEL].data + MAGIC_OFF) != KERNEL_D_MAGIC) {
|
||||
printf("Kernel magic number is incorrect\n");
|
||||
errno= 0;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Patch sizes, etc. into kernel data. */
|
||||
DEBUGEXTRA(("patch_sizes()... "));
|
||||
patch_sizes();
|
||||
DEBUGEXTRA(("done\n"));
|
||||
|
||||
#if !DOS
|
||||
if (!(k_flags & K_MEML)) {
|
||||
@@ -683,36 +570,30 @@ void exec_image(char *image)
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Do delay if wanted. */
|
||||
if((delayvalue = b_value("bootdelay")) != nil > 0) {
|
||||
delay(delayvalue);
|
||||
}
|
||||
|
||||
/* Run the trailer function just before starting Minix. */
|
||||
DEBUGEXTRA(("run_trailer()... "));
|
||||
if (!run_trailer()) { errno= 0; return; }
|
||||
DEBUGEXTRA(("done\n"));
|
||||
|
||||
/* Translate the boot parameters to what Minix likes best. */
|
||||
DEBUGEXTRA(("params2params(0x%x, 0x%x)... ", params, sizeof(params)));
|
||||
if (!params2params(params, sizeof(params))) { errno= 0; return; }
|
||||
DEBUGEXTRA(("done\n"));
|
||||
|
||||
/* Set the video to the required mode. */
|
||||
if ((console= b_value("console")) == nil || (mode= a2x(console)) == 0) {
|
||||
mode= strcmp(b_value("chrome"), "color") == 0 ? COLOR_MODE :
|
||||
MONO_MODE;
|
||||
}
|
||||
DEBUGEXTRA(("set_mode(%d)... ", mode));
|
||||
set_mode(mode);
|
||||
DEBUGEXTRA(("done\n"));
|
||||
|
||||
/* Close the disk. */
|
||||
DEBUGEXTRA(("dev_close()... "));
|
||||
(void) dev_close();
|
||||
DEBUGEXTRA(("done\n"));
|
||||
|
||||
/* Minix. */
|
||||
DEBUGEXTRA(("minix(0x%lx, 0x%lx, 0x%lx, 0x%x, 0x%x, 0x%lx)\n",
|
||||
process[KERNEL_IDX].entry, process[KERNEL_IDX].cs,
|
||||
process[KERNEL_IDX].ds, params, sizeof(params), aout));
|
||||
minix(process[KERNEL_IDX].entry, process[KERNEL_IDX].cs,
|
||||
process[KERNEL_IDX].ds, params, sizeof(params), aout);
|
||||
minix(process[KERNEL].entry, process[KERNEL].cs,
|
||||
process[KERNEL].ds, params, sizeof(params), aout);
|
||||
|
||||
if (!(k_flags & K_BRET)) {
|
||||
extern u32_t reboot_code;
|
||||
@@ -726,13 +607,8 @@ void exec_image(char *image)
|
||||
|
||||
/* Read leftover character, if any. */
|
||||
scan_keyboard();
|
||||
|
||||
/* Restore screen contents. */
|
||||
restore_screen();
|
||||
}
|
||||
|
||||
|
||||
|
||||
ino_t latest_version(char *version, struct stat *stp)
|
||||
/* Recursively read the current directory, selecting the newest image on
|
||||
* the way up. (One can't use r_stat while reading a directory.)
|
||||
@@ -825,13 +701,6 @@ void bootminix(void)
|
||||
|
||||
if ((image= select_image(b_value("image"))) == nil) return;
|
||||
|
||||
if(serial_line >= 0) {
|
||||
char linename[2];
|
||||
linename[0] = serial_line + '0';
|
||||
linename[1] = '\0';
|
||||
b_setvar(E_VAR, SERVARNAME, linename);
|
||||
}
|
||||
|
||||
exec_image(image);
|
||||
|
||||
switch (errno) {
|
||||
@@ -842,14 +711,11 @@ void bootminix(void)
|
||||
printf("Not enough memory to load %s\n", image);
|
||||
break;
|
||||
case EIO:
|
||||
printf("Unexpected EOF on %s\n", image);
|
||||
printf("Unsuspected EOF on %s\n", image);
|
||||
case 0:
|
||||
/* No error or error already reported. */;
|
||||
}
|
||||
free(image);
|
||||
|
||||
if(serial_line >= 0)
|
||||
b_unset(SERVARNAME);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
17
boot/doshead.s
Normal file → Executable file
17
boot/doshead.s
Normal file → Executable file
@@ -634,19 +634,19 @@ _dev_boundary:
|
||||
xor ax, ax
|
||||
ret
|
||||
|
||||
! int biosreadsectors(u32_t bufaddr, u32_t sector, u8_t count)
|
||||
! int readsectors(u32_t bufaddr, u32_t sector, u8_t count)
|
||||
! int writesectors(u32_t bufaddr, u32_t sector, u8_t count)
|
||||
! Read/write several sectors from/to the Minix virtual disk. Count
|
||||
! must fit in a byte. The external variable vfd is the file handle.
|
||||
! Returns 0 for success, otherwise the DOS error code.
|
||||
!
|
||||
.define _biosreadsectors, _writesectors
|
||||
.define _readsectors, _writesectors
|
||||
_writesectors:
|
||||
push bp
|
||||
mov bp, sp
|
||||
movb 13(bp), 0x40 ! Code for a file write
|
||||
jmp rwsec
|
||||
_biosreadsectors:
|
||||
_readsectors:
|
||||
push bp
|
||||
mov bp, sp
|
||||
movb 13(bp), 0x3F ! Code for a file read
|
||||
@@ -1277,17 +1277,6 @@ _int15:
|
||||
pop si ! Restore
|
||||
ret
|
||||
|
||||
! void scan_keyboard(void)
|
||||
! Read keyboard character. Needs to be done in case one is waiting.
|
||||
.define _scan_keyboard
|
||||
_scan_keyboard:
|
||||
movb ah, 1 ! Check keyboard
|
||||
int 0x16
|
||||
jz no_key
|
||||
movb ah, 0 ! Empty it
|
||||
int 0x16
|
||||
no_key: ret
|
||||
|
||||
.sect .rom
|
||||
.align 4
|
||||
c60: .data2 60 ! Constants for MUL and DIV
|
||||
|
||||
0
boot/image.h
Normal file → Executable file
0
boot/image.h
Normal file → Executable file
87
boot/installboot.c
Normal file → Executable file
87
boot/installboot.c
Normal file → Executable file
@@ -3,6 +3,7 @@
|
||||
*
|
||||
* Either make a device bootable or make an image from kernel, mm, fs, etc.
|
||||
*/
|
||||
#define nil 0
|
||||
#define _POSIX_SOURCE 1
|
||||
#define _MINIX 1
|
||||
#include <stdio.h>
|
||||
@@ -39,13 +40,13 @@
|
||||
|
||||
#define BOOT_BLOCK_SIZE 1024
|
||||
|
||||
static void report(const char *label)
|
||||
void report(char *label)
|
||||
/* installboot: label: No such file or directory */
|
||||
{
|
||||
fprintf(stderr, "installboot: %s: %s\n", label, strerror(errno));
|
||||
}
|
||||
|
||||
static void fatal(const char *label)
|
||||
void fatal(char *label)
|
||||
{
|
||||
report(label);
|
||||
exit(1);
|
||||
@@ -60,12 +61,12 @@ char *basename(char *name)
|
||||
static char base[IM_NAME_MAX];
|
||||
char *p, *bp= base;
|
||||
|
||||
if ((p= strchr(name, ':')) != NULL) {
|
||||
if ((p= strchr(name, ':')) != nil) {
|
||||
while (name <= p && bp < base + IM_NAME_MAX - 1)
|
||||
*bp++ = *name++;
|
||||
}
|
||||
for (;;) {
|
||||
if ((p= strrchr(name, '/')) == NULL) { p= name; break; }
|
||||
if ((p= strrchr(name, '/')) == nil) { p= name; break; }
|
||||
if (*++p != 0) break;
|
||||
*--p= 0;
|
||||
}
|
||||
@@ -74,7 +75,7 @@ char *basename(char *name)
|
||||
return base;
|
||||
}
|
||||
|
||||
static void bread(FILE *f, char *name, void *buf, size_t len)
|
||||
void bread(FILE *f, char *name, void *buf, size_t len)
|
||||
/* Read len bytes. Don't dare return without them. */
|
||||
{
|
||||
if (len > 0 && fread(buf, len, 1, f) != 1) {
|
||||
@@ -84,7 +85,7 @@ static void bread(FILE *f, char *name, void *buf, size_t len)
|
||||
}
|
||||
}
|
||||
|
||||
static void bwrite(FILE *f, const char *name, const void *buf, size_t len)
|
||||
void bwrite(FILE *f, char *name, void *buf, size_t len)
|
||||
{
|
||||
if (len > 0 && fwrite(buf, len, 1, f) != 1) fatal(name);
|
||||
}
|
||||
@@ -94,14 +95,14 @@ int making_image= 0;
|
||||
|
||||
void read_header(int talk, char *proc, FILE *procf, struct image_header *ihdr)
|
||||
/* Read the a.out header of a program and check it. If procf happens to be
|
||||
* NULL then the header is already in *image_hdr and need only be checked.
|
||||
* nil then the header is already in *image_hdr and need only be checked.
|
||||
*/
|
||||
{
|
||||
int n, big= 0;
|
||||
static int banner= 0;
|
||||
struct exec *phdr= &ihdr->process;
|
||||
|
||||
if (procf == NULL) {
|
||||
if (procf == nil) {
|
||||
/* Header already present. */
|
||||
n= phdr->a_hdrlen;
|
||||
} else {
|
||||
@@ -121,7 +122,7 @@ void read_header(int talk, char *proc, FILE *procf, struct image_header *ihdr)
|
||||
}
|
||||
|
||||
/* Get the rest of the exec header. */
|
||||
if (procf != NULL) {
|
||||
if (procf != nil) {
|
||||
bread(procf, proc, ((char *) phdr) + A_MINHDR,
|
||||
phdr->a_hdrlen - A_MINHDR);
|
||||
}
|
||||
@@ -159,7 +160,7 @@ void read_header(int talk, char *proc, FILE *procf, struct image_header *ihdr)
|
||||
}
|
||||
}
|
||||
|
||||
void padimage(const char *image, FILE *imagef, int n)
|
||||
void padimage(char *image, FILE *imagef, int n)
|
||||
/* Add n zeros to image to pad it to a sector boundary. */
|
||||
{
|
||||
while (n > 0) {
|
||||
@@ -205,16 +206,16 @@ void make_image(char *image, char **procv)
|
||||
|
||||
making_image= 1;
|
||||
|
||||
if ((imagef= fopen(image, "w")) == NULL) fatal(image);
|
||||
if ((imagef= fopen(image, "w")) == nil) fatal(image);
|
||||
|
||||
for (procn= 0; (proc= *procv++) != NULL; procn++) {
|
||||
for (procn= 0; (proc= *procv++) != nil; procn++) {
|
||||
/* Remove the label from the file name. */
|
||||
if ((file= strchr(proc, ':')) != NULL) file++; else file= proc;
|
||||
if ((file= strchr(proc, ':')) != nil) file++; else file= proc;
|
||||
|
||||
/* Real files please, may need to seek. */
|
||||
if (stat(file, &st) < 0
|
||||
|| (errno= EISDIR, !S_ISREG(st.st_mode))
|
||||
|| (procf= fopen(file, "r")) == NULL
|
||||
|| (procf= fopen(file, "r")) == nil
|
||||
) fatal(proc);
|
||||
|
||||
/* Read a.out header. */
|
||||
@@ -295,7 +296,7 @@ void extract_image(char *image)
|
||||
/* Size of the image. */
|
||||
len= S_ISREG(st.st_mode) ? st.st_size : -1;
|
||||
|
||||
if ((imagef= fopen(image, "r")) == NULL) fatal(image);
|
||||
if ((imagef= fopen(image, "r")) == nil) fatal(image);
|
||||
|
||||
while (len != 0) {
|
||||
/* Extract a program, first sector is an extended header. */
|
||||
@@ -306,9 +307,9 @@ void extract_image(char *image)
|
||||
phdr= ihdr.process;
|
||||
|
||||
/* Check header. */
|
||||
read_header(1, ihdr.name, NULL, &ihdr);
|
||||
read_header(1, ihdr.name, nil, &ihdr);
|
||||
|
||||
if ((procf= fopen(ihdr.name, "w")) == NULL) fatal(ihdr.name);
|
||||
if ((procf= fopen(ihdr.name, "w")) == nil) fatal(ihdr.name);
|
||||
|
||||
if (phdr.a_flags & A_PAL) {
|
||||
/* A page aligned process contains a header in text. */
|
||||
@@ -332,8 +333,8 @@ void extract_image(char *image)
|
||||
}
|
||||
}
|
||||
|
||||
static int rawfd; /* File descriptor to open device. */
|
||||
static const char *rawdev; /* Name of device. */
|
||||
int rawfd; /* File descriptor to open device. */
|
||||
char *rawdev; /* Name of device. */
|
||||
|
||||
void readblock(off_t blk, char *buf, int block_size)
|
||||
/* For rawfs, so that it can read blocks. */
|
||||
@@ -350,7 +351,7 @@ void readblock(off_t blk, char *buf, int block_size)
|
||||
}
|
||||
}
|
||||
|
||||
void writeblock(off_t blk, const char *buf, int block_size)
|
||||
void writeblock(off_t blk, char *buf, int block_size)
|
||||
/* Add a function to write blocks for local use. */
|
||||
{
|
||||
if (lseek(rawfd, blk * block_size, SEEK_SET) < 0
|
||||
@@ -366,7 +367,7 @@ int raw_install(char *file, off_t *start, off_t *len, int block_size)
|
||||
* Note: *len == 0 when an image is read. It is set right afterwards.
|
||||
*/
|
||||
{
|
||||
static char buf[_MAX_BLOCK_SIZE]; /* Nonvolatile block buffer. */
|
||||
static char buf[MAX_BLOCK_SIZE]; /* Nonvolatile block buffer. */
|
||||
FILE *f;
|
||||
off_t sec;
|
||||
unsigned long devsize;
|
||||
@@ -377,7 +378,7 @@ int raw_install(char *file, off_t *start, off_t *len, int block_size)
|
||||
devsize= -1;
|
||||
if (ioctl(rawfd, DIOCGETP, &entry) == 0) devsize= cv64ul(entry.size);
|
||||
|
||||
if ((f= fopen(file, "r")) == NULL) fatal(file);
|
||||
if ((f= fopen(file, "r")) == nil) fatal(file);
|
||||
|
||||
/* Copy sectors from file onto the boot device. */
|
||||
sec= *start;
|
||||
@@ -423,7 +424,7 @@ void make_bootable(enum howto how, char *device, char *bootblock,
|
||||
* vector are added to the end of the device.
|
||||
*/
|
||||
{
|
||||
char buf[_MAX_BLOCK_SIZE + 256], *adrp, *parmp;
|
||||
char buf[MAX_BLOCK_SIZE + 256], *adrp, *parmp;
|
||||
struct fileaddr {
|
||||
off_t address;
|
||||
int count;
|
||||
@@ -485,7 +486,7 @@ void make_bootable(enum howto how, char *device, char *bootblock,
|
||||
*/
|
||||
if (stat(bootcode, &st) < 0) fatal(bootcode);
|
||||
|
||||
if ((bootf= fopen(bootcode, "r")) == NULL) fatal(bootcode);
|
||||
if ((bootf= fopen(bootcode, "r")) == nil) fatal(bootcode);
|
||||
} else {
|
||||
/* Boot code is present in the file system. */
|
||||
r_stat(ino, &st);
|
||||
@@ -497,14 +498,14 @@ void make_bootable(enum howto how, char *device, char *bootblock,
|
||||
readblock(addr, buf, block_size);
|
||||
memcpy(&boothdr, buf, sizeof(struct exec));
|
||||
}
|
||||
bootf= NULL;
|
||||
bootf= nil;
|
||||
dummy.process= boothdr;
|
||||
}
|
||||
/* See if it is an executable (read_header does the check). */
|
||||
read_header(0, bootcode, bootf, &dummy);
|
||||
boothdr= dummy.process;
|
||||
|
||||
if (bootf != NULL) fclose(bootf);
|
||||
if (bootf != nil) fclose(bootf);
|
||||
|
||||
/* Get all the sector addresses of the secondary boot code. */
|
||||
max_sector= (boothdr.a_hdrlen + boothdr.a_text
|
||||
@@ -549,7 +550,7 @@ void make_bootable(enum howto how, char *device, char *bootblock,
|
||||
/* Get the boot block and patch the pieces in. */
|
||||
readblock(BOOTBLOCK, buf, BOOT_BLOCK_SIZE);
|
||||
|
||||
if ((bootf= fopen(bootblock, "r")) == NULL) fatal(bootblock);
|
||||
if ((bootf= fopen(bootblock, "r")) == nil) fatal(bootblock);
|
||||
|
||||
read_header(0, bootblock, bootf, &dummy);
|
||||
boothdr= dummy.process;
|
||||
@@ -594,7 +595,7 @@ void make_bootable(enum howto how, char *device, char *bootblock,
|
||||
* necessary.
|
||||
*/
|
||||
for (parmp= buf + SECTOR_SIZE; parmp < buf + 2*SECTOR_SIZE; parmp++) {
|
||||
if (*imagev != NULL || (control(*parmp) && *parmp != '\n')) {
|
||||
if (*imagev != nil || (control(*parmp) && *parmp != '\n')) {
|
||||
/* Param sector must be initialized. */
|
||||
memset(buf + SECTOR_SIZE, '\n', SECTOR_SIZE);
|
||||
break;
|
||||
@@ -627,10 +628,10 @@ void make_bootable(enum howto how, char *device, char *bootblock,
|
||||
parmp+= strlen(parmp);
|
||||
}
|
||||
|
||||
while ((labels= *imagev++) != NULL) {
|
||||
while ((labels= *imagev++) != nil) {
|
||||
/* Place each kernel image on the boot device. */
|
||||
|
||||
if ((image= strchr(labels, ':')) != NULL)
|
||||
if ((image= strchr(labels, ':')) != nil)
|
||||
*image++= 0;
|
||||
else {
|
||||
if (nolabel) {
|
||||
@@ -640,23 +641,23 @@ void make_bootable(enum howto how, char *device, char *bootblock,
|
||||
}
|
||||
nolabel= 1;
|
||||
image= labels;
|
||||
labels= NULL;
|
||||
labels= nil;
|
||||
}
|
||||
len= 0;
|
||||
if (!raw_install(image, &pos, &len, block_size)) exit(1);
|
||||
|
||||
if (labels == NULL) {
|
||||
if (labels == nil) {
|
||||
/* Let this image be the default. */
|
||||
sprintf(parmp, "image=%ld:%ld\n", pos-len, len);
|
||||
parmp+= strlen(parmp);
|
||||
}
|
||||
|
||||
while (labels != NULL) {
|
||||
while (labels != nil) {
|
||||
/* Image is prefixed by a comma separated list of
|
||||
* labels. Define functions to select label and image.
|
||||
*/
|
||||
label= labels;
|
||||
if ((labels= strchr(labels, ',')) != NULL) *labels++ = 0;
|
||||
if ((labels= strchr(labels, ',')) != nil) *labels++ = 0;
|
||||
|
||||
sprintf(parmp,
|
||||
"%s(%c){label=%s;image=%ld:%ld;echo %s kernel selected;menu}\n",
|
||||
@@ -683,7 +684,7 @@ void make_bootable(enum howto how, char *device, char *bootblock,
|
||||
}
|
||||
}
|
||||
|
||||
static void install_master(const char *device, char *masterboot, char **guide)
|
||||
void install_master(char *device, char *masterboot, char **guide)
|
||||
/* Booting a hard disk is a two stage process: The master bootstrap in sector
|
||||
* 0 loads the bootstrap from sector 0 of the active partition which in turn
|
||||
* starts the operating system. This code installs such a master bootstrap
|
||||
@@ -694,13 +695,13 @@ static void install_master(const char *device, char *masterboot, char **guide)
|
||||
FILE *masf;
|
||||
unsigned long size;
|
||||
struct stat st;
|
||||
static char buf[_MAX_BLOCK_SIZE];
|
||||
static char buf[MAX_BLOCK_SIZE];
|
||||
|
||||
/* Open device. */
|
||||
if ((rawfd= open(rawdev= device, O_RDWR)) < 0) fatal(device);
|
||||
|
||||
/* Open the master boot code. */
|
||||
if ((masf= fopen(masterboot, "r")) == NULL) fatal(masterboot);
|
||||
if ((masf= fopen(masterboot, "r")) == nil) fatal(masterboot);
|
||||
|
||||
/* See if the user is cloning a device. */
|
||||
if (fstat(fileno(masf), &st) >=0 && S_ISBLK(st.st_mode))
|
||||
@@ -723,10 +724,10 @@ static void install_master(const char *device, char *masterboot, char **guide)
|
||||
memset(buf, 0, PARTPOS);
|
||||
(void) bread(masf, masterboot, buf, size);
|
||||
|
||||
if (guide[0] != NULL) {
|
||||
if (guide[0] != nil) {
|
||||
/* Fixate partition to boot. */
|
||||
const char *keys= guide[0];
|
||||
const char *logical= guide[1];
|
||||
char *keys= guide[0];
|
||||
char *logical= guide[1];
|
||||
size_t i;
|
||||
int logfd;
|
||||
u32_t offset;
|
||||
@@ -753,7 +754,7 @@ static void install_master(const char *device, char *masterboot, char **guide)
|
||||
size += i;
|
||||
buf[size]= '\r';
|
||||
|
||||
if (logical != NULL) {
|
||||
if (logical != nil) {
|
||||
if ((logfd= open(logical, O_RDONLY)) < 0
|
||||
|| ioctl(logfd, DIOCGETP, &geometry) < 0
|
||||
) {
|
||||
@@ -780,7 +781,7 @@ static void install_master(const char *device, char *masterboot, char **guide)
|
||||
writeblock(BOOTBLOCK, buf, BOOT_BLOCK_SIZE);
|
||||
}
|
||||
|
||||
static void usage(void)
|
||||
void usage(void)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"Usage: installboot -i(mage) image kernel mm fs ... init\n"
|
||||
@@ -791,7 +792,7 @@ static void usage(void)
|
||||
exit(1);
|
||||
}
|
||||
|
||||
static int isoption(const char *option, const char *test)
|
||||
int isoption(char *option, char *test)
|
||||
/* Check if the option argument is equals "test". Also accept -i as short
|
||||
* for -image, and the special case -x for -extract.
|
||||
*/
|
||||
|
||||
0
boot/jumpboot.s
Normal file → Executable file
0
boot/jumpboot.s
Normal file → Executable file
0
boot/masterboot.s
Normal file → Executable file
0
boot/masterboot.s
Normal file → Executable file
0
boot/mkfhead.s
Normal file → Executable file
0
boot/mkfhead.s
Normal file → Executable file
3
boot/mkfile.c
Normal file → Executable file
3
boot/mkfile.c
Normal file → Executable file
@@ -21,7 +21,7 @@ int printf(const char *fmt, ...);
|
||||
#define SEEK_END 2
|
||||
|
||||
/* Kernel printf requires a putk() function. */
|
||||
void putk(int c)
|
||||
int putk(int c)
|
||||
{
|
||||
char ch = c;
|
||||
|
||||
@@ -72,6 +72,7 @@ char *strerror(int err)
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int i;
|
||||
static char buf[512];
|
||||
unsigned long size, mul;
|
||||
off_t offset;
|
||||
|
||||
41
boot/rawfs.c
Normal file → Executable file
41
boot/rawfs.c
Normal file → Executable file
@@ -2,6 +2,7 @@
|
||||
* 23 Dec 1991
|
||||
* Based on readfs by Paul Polderman
|
||||
*/
|
||||
#define nil 0
|
||||
#define _POSIX_SOURCE 1
|
||||
#define _MINIX 1
|
||||
#include <sys/types.h>
|
||||
@@ -13,11 +14,11 @@
|
||||
#include <minix/config.h>
|
||||
#include <minix/const.h>
|
||||
#include <minix/type.h>
|
||||
#include <servers/mfs/const.h>
|
||||
#include <servers/mfs/type.h>
|
||||
#include <servers/mfs/buf.h>
|
||||
#include <servers/mfs/super.h>
|
||||
#include <servers/mfs/inode.h>
|
||||
#include <servers/fs/const.h>
|
||||
#include <servers/fs/type.h>
|
||||
#include <servers/fs/buf.h>
|
||||
#include <servers/fs/super.h>
|
||||
#include <servers/fs/inode.h>
|
||||
#include "rawfs.h"
|
||||
|
||||
void readblock(off_t blockno, char *buf, int);
|
||||
@@ -52,15 +53,15 @@ static struct super_block super; /* Superblock of file system */
|
||||
#endif
|
||||
|
||||
static struct inode curfil; /* Inode of file under examination */
|
||||
static char indir[_MAX_BLOCK_SIZE]; /* Single indirect block. */
|
||||
static char dindir[_MAX_BLOCK_SIZE]; /* Double indirect block. */
|
||||
static char dirbuf[_MAX_BLOCK_SIZE]; /* Scratch/Directory block. */
|
||||
static char indir[MAX_BLOCK_SIZE]; /* Single indirect block. */
|
||||
static char dindir[MAX_BLOCK_SIZE]; /* Double indirect block. */
|
||||
static char dirbuf[MAX_BLOCK_SIZE]; /* Scratch/Directory block. */
|
||||
#define scratch dirbuf
|
||||
|
||||
static block_t a_indir, a_dindir; /* Addresses of the indirects. */
|
||||
static off_t dirpos; /* Reading pos in a dir. */
|
||||
|
||||
#define fsbuf(b) (* (union fsdata_u *) (b))
|
||||
#define fsbuf(b) (* (struct buf *) (b))
|
||||
|
||||
#define zone_shift (super.s_log_zone_size) /* zone to block ratio */
|
||||
|
||||
@@ -82,8 +83,8 @@ off_t r_super(int *bs)
|
||||
if(super.s_magic == SUPER_V2)
|
||||
super.s_block_size = 1024;
|
||||
*bs = block_size = super.s_block_size;
|
||||
if(block_size < _MIN_BLOCK_SIZE ||
|
||||
block_size > _MAX_BLOCK_SIZE) {
|
||||
if(block_size < MIN_BLOCK_SIZE ||
|
||||
block_size > MAX_BLOCK_SIZE) {
|
||||
return 0;
|
||||
}
|
||||
nr_dzones= V2_NR_DZONES;
|
||||
@@ -109,7 +110,6 @@ void r_stat(Ino_t inum, struct stat *stp)
|
||||
block_t block;
|
||||
block_t ino_block;
|
||||
ino_t ino_offset;
|
||||
union fsdata_u *blockbuf;
|
||||
|
||||
/* Calculate start of i-list */
|
||||
block = START_BLOCK + super.s_imap_blocks + super.s_zmap_blocks;
|
||||
@@ -120,14 +120,13 @@ void r_stat(Ino_t inum, struct stat *stp)
|
||||
block += ino_block;
|
||||
|
||||
/* Fetch the block */
|
||||
blockbuf = (union fsdata_u *) scratch;
|
||||
readblock(block, (char *) blockbuf, block_size);
|
||||
readblock(block, scratch, block_size);
|
||||
|
||||
if (super.s_magic == SUPER_V2 || super.s_magic == SUPER_V3) {
|
||||
d2_inode *dip;
|
||||
int i;
|
||||
|
||||
dip= &blockbuf->b__v2_ino[(unsigned int) ino_offset];
|
||||
dip= &fsbuf(scratch).b_v2_ino[ino_offset];
|
||||
|
||||
curfil.i_mode= dip->d2_mode;
|
||||
curfil.i_nlinks= dip->d2_nlinks;
|
||||
@@ -143,7 +142,7 @@ void r_stat(Ino_t inum, struct stat *stp)
|
||||
d1_inode *dip;
|
||||
int i;
|
||||
|
||||
dip= &blockbuf->b__v1_ino[(unsigned int) ino_offset];
|
||||
dip= &fsbuf(scratch).b_v1_ino[ino_offset];
|
||||
|
||||
curfil.i_mode= dip->d1_mode;
|
||||
curfil.i_nlinks= dip->d1_nlinks;
|
||||
@@ -264,8 +263,8 @@ off_t r_vir2abs(off_t virblk)
|
||||
|
||||
i = zone / (zone_t) nr_indirects;
|
||||
ind_zone = (super.s_magic == SUPER_V2 || super.s_magic == SUPER_V3)
|
||||
? fsbuf(dindir).b__v2_ind[i]
|
||||
: fsbuf(dindir).b__v1_ind[i];
|
||||
? fsbuf(dindir).b_v2_ind[i]
|
||||
: fsbuf(dindir).b_v1_ind[i];
|
||||
zone %= (zone_t) nr_indirects;
|
||||
}
|
||||
if (ind_zone == 0) return 0;
|
||||
@@ -277,15 +276,15 @@ off_t r_vir2abs(off_t virblk)
|
||||
a_indir= z;
|
||||
}
|
||||
zone = (super.s_magic == SUPER_V2 || super.s_magic == SUPER_V3)
|
||||
? fsbuf(indir).b__v2_ind[(int) zone]
|
||||
: fsbuf(indir).b__v1_ind[(int) zone];
|
||||
? fsbuf(indir).b_v2_ind[(int) zone]
|
||||
: fsbuf(indir).b_v1_ind[(int) zone];
|
||||
|
||||
/* Calculate absolute datablock number */
|
||||
z = ((block_t) zone << zone_shift) + zone_index;
|
||||
return z;
|
||||
}
|
||||
|
||||
ino_t r_lookup(Ino_t cwd, const char *path)
|
||||
ino_t r_lookup(Ino_t cwd, char *path)
|
||||
/* Translates a pathname to an inode number. This is just a nice utility
|
||||
* function, it only needs r_stat and r_readdir.
|
||||
*/
|
||||
|
||||
17
boot/rawfs.h
Normal file → Executable file
17
boot/rawfs.h
Normal file → Executable file
@@ -17,7 +17,7 @@
|
||||
* Return next directory entry or 0 if there are no more.
|
||||
* Returns -1 and sets errno on error.
|
||||
*
|
||||
* ino_t r_lookup(ino_t cwd, const char *path);
|
||||
* ino_t r_lookup(ino_t cwd, char *path);
|
||||
* A utility function that translates a pathname to an
|
||||
* inode number. It starts from directory "cwd" unless
|
||||
* path starts with a '/', then from ROOT_INO.
|
||||
@@ -30,19 +30,14 @@
|
||||
* errors.
|
||||
*/
|
||||
|
||||
#ifndef INC_RAWFS_H
|
||||
#define INC_RAWFS_H
|
||||
|
||||
#define ROOT_INO ((ino_t) 1) /* Inode nr of root dir. */
|
||||
|
||||
extern off_t r_super(int *);
|
||||
extern void r_stat(Ino_t file, struct stat *stp);
|
||||
extern off_t r_vir2abs(off_t virblockno);
|
||||
extern ino_t r_readdir(char *name);
|
||||
extern ino_t r_lookup(Ino_t cwd, const char *path);
|
||||
off_t r_super(int *);
|
||||
void r_stat(Ino_t file, struct stat *stp);
|
||||
off_t r_vir2abs(off_t virblockno);
|
||||
ino_t r_readdir(char *name);
|
||||
ino_t r_lookup(Ino_t cwd, char *path);
|
||||
|
||||
/*
|
||||
* $PchId: rawfs.h,v 1.4 1996/04/19 08:16:36 philip Exp $
|
||||
*/
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
#!/bin/sh
|
||||
set -e
|
||||
|
||||
BOOT=/boot/boot
|
||||
ROOT=`printroot -r`
|
||||
|
||||
if [ ! -b "$ROOT" ]
|
||||
then echo root device $ROOT not found
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo -n "Install boot as $BOOT on current root and patch into $ROOT? (y/N) "
|
||||
read ans
|
||||
|
||||
if [ ! "$ans" = y ]
|
||||
then echo Aborting.
|
||||
exit 1
|
||||
fi
|
||||
|
||||
make install || true
|
||||
|
||||
echo Installing boot monitor into $BOOT.
|
||||
cp boot $BOOT
|
||||
|
||||
echo Patching position of $BOOT into $ROOT.
|
||||
installboot -d "$ROOT" /usr/mdec/bootblock $BOOT
|
||||
sync
|
||||
@@ -1,4 +0,0 @@
|
||||
SCRIPTS= DESCRIBE.sh
|
||||
MAN=
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
@@ -1,7 +0,0 @@
|
||||
SCRIPTS= M.sh
|
||||
BINDIR= /bin
|
||||
MAN=
|
||||
|
||||
LINKS+= ${BINDIR}/M ${BINDIR}/U
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
@@ -1,4 +0,0 @@
|
||||
SCRIPTS= MAKEDEV.sh
|
||||
MAN=
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
120
commands/Makefile
Normal file → Executable file
120
commands/Makefile
Normal file → Executable file
@@ -1,44 +1,86 @@
|
||||
# Makefile for commands.
|
||||
|
||||
.include <bsd.own.mk>
|
||||
MAKE = exec make -$(MAKEFLAGS)
|
||||
FLEX=flex-2.5.4
|
||||
GZIP=gzip-1.2.4
|
||||
PYTHON=python-1.5.2
|
||||
BZIP2=bzip2-1.0.3
|
||||
KERMIT=kermit-2.1.1
|
||||
NVI=nvi-1.79
|
||||
NVIWORK=$(NVI)/minix
|
||||
EMACS=emacs-21.4
|
||||
LYNX=lynx2-8-5
|
||||
COREUTILS=gnu-coreutils-5.2.1
|
||||
|
||||
SUBDIR= aal add_route adduser advent arp ash at autil awk \
|
||||
backup badblocks banner basename bigmake binpackage \
|
||||
binpackages binsizes bzip2 bzip2recover cal calendar \
|
||||
cat cawf cd cdprobe checkhier chmem \
|
||||
chmod chown chroot ci cksum cleantmp clear cmp co \
|
||||
comm compress cp crc cron crontab cut date \
|
||||
dd de decomp16 DESCRIBE dev2name devsize df dhcpd \
|
||||
dhrystone diff dirname dis88 diskctl du dumpcore \
|
||||
ed eject elle elvis env expand factor file \
|
||||
find finger fingerd fix fold format fortune fsck.mfs \
|
||||
fsck1 ftp101 ftpd200 gcov-pull getty grep gomoku head hexdump host \
|
||||
hostaddr id ifconfig ifdef indent install \
|
||||
intr ipcrm ipcs irdpd isoread join kill last leave \
|
||||
less lex life loadkeys loadramdisk logger login look lp \
|
||||
lpd ls lspci M m4 mail make MAKEDEV man \
|
||||
mdb mdocml mesg mined mkdep mkdir mkdist mkfifo mkfs.mfs mknod \
|
||||
mkproto modem mount mt netconf newroot nice acknm nohup \
|
||||
nonamed od packman passwd paste patch pax \
|
||||
ping postinstall poweroff pr prep printf printroot \
|
||||
profile progressbar proto pr_routes ps pwd pwdauth \
|
||||
ramdisk rarpd rawspeed rcp rdate readall readclock \
|
||||
readfs reboot remsync rev rget rlogin rlogind rmdir \
|
||||
rotate rsh rshd sed service setup shar size \
|
||||
sleep slip sort spell split srccrc stat strings ackstrip \
|
||||
stty su sum svclog swapfs swifi sync synctree sysenv \
|
||||
syslogd tail talk talkd tar tcpd tcpdp tcpstat tee telnet \
|
||||
telnetd term termcap tget time tinyhalt top touch tr \
|
||||
truncate tsort ttt tty udpstat umount uname unexpand \
|
||||
uniq unstack update urlget uud uue version vol wc \
|
||||
whereis which who write writeisofs fetch \
|
||||
xargs yacc yes zdump zic zmodem pkg_install pkgin_cd
|
||||
SMALLPROGRAMS=`arch` aal advent ash autil awk bc byacc cawf cron de dhcpd dis88 elle elvis ftp ftpd ftpd200 httpd ibm indent m4 make mdb mined patch ps reboot rlogind scripts sh simple talk talkd telnet telnetd urlget yap zmodem
|
||||
|
||||
.if ${ARCH} == "i386"
|
||||
SUBDIR+= atnormalize dosread fdisk loadfont \
|
||||
mixer autopart part partition playwave postmort \
|
||||
recwave repartition screendump padtext
|
||||
SUBDIR+= acd asmconv gas2ack
|
||||
.endif
|
||||
usage:
|
||||
@echo "Usage: make all # Compile all commands" >&2
|
||||
@echo " make install # Install the result (run as bin!)" >&2
|
||||
@echo " make clean # Delete .o files and other junk" >&2
|
||||
@echo " make big # Compile all big commands" >&2
|
||||
@echo " make biginstall # Install all big commands" >&2
|
||||
@echo " make small # Install all small commands" >&2
|
||||
@echo " make smallinstall # Install all small commands" >&2
|
||||
@echo " make ack # Make ack" >&2
|
||||
@echo " make ackinstall # Install ack" >&2
|
||||
@echo " "
|
||||
@echo "big compiles the commands the require large compiler sizes."
|
||||
@echo "small compiles the rest. all compiles all."
|
||||
@false
|
||||
|
||||
all: small big
|
||||
|
||||
install: biginstall smallinstall
|
||||
|
||||
small::
|
||||
cd $(GZIP) && CC="$(CC)" /bin/sh ./configure --prefix=/usr/local && $(MAKE) all
|
||||
|
||||
smallinstall:: small
|
||||
cd $(GZIP) && $(MAKE) install
|
||||
|
||||
big:
|
||||
cd $(FLEX) && /bin/sh makeme.sh
|
||||
cd $(BZIP2) && /bin/sh makeme.sh
|
||||
cd $(KERMIT) && /bin/sh makeme.sh
|
||||
cd $(LYNX) && /bin/sh makeme.sh
|
||||
cd $(COREUTILS) && /bin/sh makeme.sh
|
||||
cd $(EMACS) && /bin/sh makeme.sh
|
||||
cd $(PYTHON) && /bin/sh makeme.sh
|
||||
-mkdir $(NVIWORK)
|
||||
cd $(NVI) && make all
|
||||
|
||||
biginstall: big
|
||||
cd $(FLEX) && make install
|
||||
cd $(PYTHON) && make install
|
||||
cd $(BZIP2) && make install
|
||||
cd $(KERMIT) && make install
|
||||
cd $(LYNX) && make install
|
||||
cd $(EMACS) && make install
|
||||
cd $(COREUTILS) && make install
|
||||
cd $(NVI) && make install
|
||||
|
||||
clean::
|
||||
if [ -f $(FLEX)/Makefile ] ; then cd $(FLEX) && make $@; fi
|
||||
if [ -f $(GZIP)/Makefile ] ; then cd $(GZIP) && make $@; fi
|
||||
if [ -f $(PYTHON)/Makefile ] ; then cd $(PYTHON) && make $@; fi
|
||||
cd $(BZIP2) && make clean
|
||||
cd $(KERMIT) && make clean
|
||||
if [ -f $(NVIWORK)/Makefile ]; then cd $(NVIWORK) && make clean; fi
|
||||
if [ -f $(LYNX)/Makefile ] ; then cd $(LYNX) && make clean; fi
|
||||
if [ -f $(EMACS)/Makefile ] ; then cd $(EMACS) && make clean; fi
|
||||
cd $(COREUTILS) && make clean
|
||||
for p in $(SMALLPROGRAMS); do ( cd $$p && make clean ); done
|
||||
|
||||
small::
|
||||
for p in $(SMALLPROGRAMS); do ( cd $$p && make all ); done
|
||||
|
||||
smallinstall::
|
||||
for p in $(SMALLPROGRAMS); do ( cd $$p && make install ); done
|
||||
|
||||
ack:
|
||||
cd ackpack && make
|
||||
|
||||
ackinstall:
|
||||
cd ackpack && make install
|
||||
|
||||
.include <bsd.subdir.mk>
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
CPPFLAGS+= -D_MINIX -D_POSIX_SOURCE
|
||||
BINDIR?=/usr/bin
|
||||
59
commands/aal/Makefile
Normal file → Executable file
59
commands/aal/Makefile
Normal file → Executable file
@@ -1,11 +1,56 @@
|
||||
# Makefile for aal
|
||||
|
||||
PROG= aal
|
||||
SRCS= archiver.c print.c rd.c rd_arhdr.c rd_unsig2.c sprint.c \
|
||||
wr_arhdr.c wr_bytes.c wr_int2.c wr_long.c wr_ranlib.c \
|
||||
format.c rd_bytes.c system.c write.c long2str.c
|
||||
CPPFLAGS+= -I${.CURDIR} -DAAL -DSTB -DNDEBUG -DDISTRIBUTION
|
||||
CC=exec cc
|
||||
CFLAGS=-I. -wo -DAAL -DSTB -DNDEBUG -DDISTRIBUTION -D_POSIX_SOURCE -D_MINIX
|
||||
LDFLAGS=-i
|
||||
|
||||
MAN=
|
||||
all: aal
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
OFILES= archiver.o \
|
||||
print.o \
|
||||
rd.o \
|
||||
rd_arhdr.o \
|
||||
rd_unsig2.o \
|
||||
sprint.o \
|
||||
wr_arhdr.o \
|
||||
wr_bytes.o \
|
||||
wr_int2.o \
|
||||
wr_long.o \
|
||||
wr_ranlib.o \
|
||||
format.o \
|
||||
rd_bytes.o \
|
||||
system.o \
|
||||
write.o \
|
||||
long2str.o
|
||||
|
||||
aal: $(OFILES)
|
||||
$(CC) $(LDFLAGS) -o aal $(OFILES)
|
||||
install -S 512k $@
|
||||
|
||||
install: /usr/bin/aal /usr/bin/ar
|
||||
|
||||
/usr/bin/aal: aal
|
||||
install -cs -o bin aal $@
|
||||
|
||||
/usr/bin/ar: /usr/bin/aal
|
||||
install -l $? $@
|
||||
|
||||
archiver.o:
|
||||
print.o:
|
||||
rd.o:
|
||||
rd_arhdr.o:
|
||||
rd_unsig2.o:
|
||||
sprint.o:
|
||||
wr_arhdr.o:
|
||||
wr_bytes.o:
|
||||
wr_int2.o:
|
||||
wr_long.o:
|
||||
wr_ranlib.o:
|
||||
format.o:
|
||||
rd_bytes.o:
|
||||
system.o:
|
||||
write.o:
|
||||
long2str.o:
|
||||
|
||||
clean:
|
||||
rm -f *.o core *.bak aal
|
||||
|
||||
3
commands/aal/arch.h
Normal file → Executable file
3
commands/aal/arch.h
Normal file → Executable file
@@ -22,7 +22,4 @@ struct ar_hdr {
|
||||
#define AR_TOTAL 26
|
||||
#define AR_SIZE 22
|
||||
|
||||
extern int rd_arhdr(int fd, register struct ar_hdr arhdr[]);
|
||||
extern void wr_arhdr(int fd, struct ar_hdr arhdr[]);
|
||||
|
||||
#endif /* __ARCH_H_INCLUDED */
|
||||
|
||||
181
commands/aal/archiver.c
Normal file → Executable file
181
commands/aal/archiver.c
Normal file → Executable file
@@ -4,18 +4,7 @@
|
||||
*/
|
||||
/* ar - archiver Author: Michiel Huisjes */
|
||||
/* Made into arch/aal by Ceriel Jacobs
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include "rd.h"
|
||||
#include "wr_bytes.h"
|
||||
#include "wr_long.h"
|
||||
#include "wr_int2.h"
|
||||
#include "arch.h"
|
||||
#include "archiver.h"
|
||||
#include "print.h"
|
||||
*/
|
||||
|
||||
static char RcsId[] = "$Header$";
|
||||
|
||||
@@ -36,10 +25,6 @@ static char RcsId[] = "$Header$";
|
||||
#endif
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#ifndef S_IREAD
|
||||
@@ -62,6 +47,7 @@ struct ranlib *tab;
|
||||
unsigned int tnum = 0;
|
||||
char *tstrtab;
|
||||
unsigned int tssiz = 0;
|
||||
char *malloc(), *realloc(), *strcpy(), *strncpy();
|
||||
long time();
|
||||
unsigned int tabsz, strtabsz;
|
||||
#else
|
||||
@@ -82,6 +68,10 @@ typedef char BOOL;
|
||||
|
||||
#define MEMBER struct ar_hdr
|
||||
|
||||
#define NIL_PTR ((char *) 0)
|
||||
#define NIL_MEM ((MEMBER *) 0)
|
||||
#define NIL_LONG ((long *) 0)
|
||||
|
||||
#define IO_SIZE (10 * 1024)
|
||||
|
||||
#define equal(str1, str2) (!strncmp((str1), (str2), 14))
|
||||
@@ -115,49 +105,9 @@ char *temp_arch = &temp_buf[0];
|
||||
extern char *mktemp();
|
||||
extern char *ctime();
|
||||
|
||||
/* Forward declarations. */
|
||||
static void enter_name(struct outname *namep);
|
||||
static void do_names(struct outhead *headp);
|
||||
static void do_object(int f, long size);
|
||||
static void show(char *s, char *name);
|
||||
static void write_symdef(void);
|
||||
static void mwrite(int fd, char *address, int bytes);
|
||||
static void extract(register MEMBER *member);
|
||||
static void copy_member(MEMBER *member, int from, int to, int extracting);
|
||||
static void add(char *name, int fd, char *mess);
|
||||
static void get(int argc, char *argv[]);
|
||||
|
||||
/*VARARGS2*/
|
||||
void error1(BOOL quit, char *str1)
|
||||
usage()
|
||||
{
|
||||
fputs(str1,stderr);
|
||||
if (quit) {
|
||||
unlink(temp_arch);
|
||||
_exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
void error2(BOOL quit, char *str1, char *str2)
|
||||
{
|
||||
fprintf(stderr,str1,str2);
|
||||
if (quit) {
|
||||
unlink(temp_arch);
|
||||
_exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
void error3(BOOL quit, char *str1, char *str2, char *str3)
|
||||
{
|
||||
fprintf(stderr,str1,str2,str3);
|
||||
if (quit) {
|
||||
unlink(temp_arch);
|
||||
_exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
void usage()
|
||||
{
|
||||
error3(TRUE, "usage: %s %s archive [file] ...\n",
|
||||
error(TRUE, "usage: %s %s archive [file] ...\n",
|
||||
progname,
|
||||
#ifdef AAL
|
||||
"[acdrtxvlu]"
|
||||
@@ -167,17 +117,33 @@ void usage()
|
||||
);
|
||||
}
|
||||
|
||||
char *basename(char *path)
|
||||
/*VARARGS2*/
|
||||
error(quit, str1, str2, str3, str4)
|
||||
BOOL quit;
|
||||
char *str1, *str2, *str3, *str4;
|
||||
{
|
||||
char errbuf[256];
|
||||
|
||||
sprint(errbuf, str1, str2, str3, str4);
|
||||
write(2, errbuf, strlen(errbuf));
|
||||
if (quit) {
|
||||
unlink(temp_arch);
|
||||
_exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
char *basename(path)
|
||||
char *path;
|
||||
{
|
||||
register char *ptr = path;
|
||||
register char *last = NULL;
|
||||
register char *last = NIL_PTR;
|
||||
|
||||
while (*ptr != '\0') {
|
||||
if (*ptr == '/')
|
||||
last = ptr;
|
||||
ptr++;
|
||||
}
|
||||
if (last == NULL)
|
||||
if (last == NIL_PTR)
|
||||
return path;
|
||||
if (*(last + 1) == '\0') {
|
||||
*last = '\0';
|
||||
@@ -188,14 +154,16 @@ char *basename(char *path)
|
||||
|
||||
extern unsigned int rd_unsigned2();
|
||||
|
||||
int open_archive(char *name, int mode)
|
||||
open_archive(name, mode)
|
||||
register char *name;
|
||||
register int mode;
|
||||
{
|
||||
unsigned short magic = 0;
|
||||
int fd;
|
||||
|
||||
if (mode == CREATE) {
|
||||
if ((fd = creat(name, 0666)) < 0)
|
||||
error2(TRUE, "cannot creat %s\n", name);
|
||||
error(TRUE, "cannot creat %s\n", name);
|
||||
magic = MAGIC_NUMBER;
|
||||
wr_int2(fd, magic);
|
||||
return fd;
|
||||
@@ -204,15 +172,15 @@ int open_archive(char *name, int mode)
|
||||
if ((fd = open(name, mode)) < 0) {
|
||||
if (mode == APPEND) {
|
||||
close(open_archive(name, CREATE));
|
||||
if (!nocr_fl) error3(FALSE, "%s: creating %s\n", progname, name);
|
||||
if (!nocr_fl) error(FALSE, "%s: creating %s\n", progname, name);
|
||||
return open_archive(name, APPEND);
|
||||
}
|
||||
error2(TRUE, "cannot open %s\n", name);
|
||||
error(TRUE, "cannot open %s\n", name);
|
||||
}
|
||||
lseek(fd, 0L, 0);
|
||||
magic = rd_unsigned2(fd);
|
||||
if (magic != AALMAG && magic != ARMAG)
|
||||
error2(TRUE, "%s is not in ar format\n", name);
|
||||
error(TRUE, "%s is not in ar format\n", name);
|
||||
|
||||
return fd;
|
||||
}
|
||||
@@ -227,7 +195,9 @@ catch()
|
||||
_exit (2);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
main(argc, argv)
|
||||
int argc;
|
||||
char *argv[];
|
||||
{
|
||||
register char *ptr;
|
||||
int needs_arg = 0;
|
||||
@@ -314,7 +284,7 @@ int main(int argc, char *argv[])
|
||||
#ifdef AAL
|
||||
tab = (struct ranlib *) malloc(512 * sizeof(struct ranlib));
|
||||
tstrtab = malloc(4096);
|
||||
if (!tab || !tstrtab) error1(TRUE,"Out of core\n");
|
||||
if (!tab || !tstrtab) error(TRUE,"Out of core\n");
|
||||
tabsz = 512;
|
||||
strtabsz = 4096;
|
||||
#endif
|
||||
@@ -332,9 +302,9 @@ get_member()
|
||||
|
||||
again:
|
||||
if (rd_arhdr(ar_fd, &member) == 0)
|
||||
return NULL;
|
||||
return NIL_MEM;
|
||||
if (member.ar_size < 0) {
|
||||
error1(TRUE, "archive has member with negative size\n");
|
||||
error(TRUE, "archive has member with negative size\n");
|
||||
}
|
||||
#ifdef AAL
|
||||
if (equal(SYMDEF, member.ar_name)) {
|
||||
@@ -347,7 +317,9 @@ again:
|
||||
|
||||
char *get_mode();
|
||||
|
||||
static void get(int argc, char *argv[])
|
||||
get(argc, argv)
|
||||
int argc;
|
||||
register char *argv[];
|
||||
{
|
||||
register MEMBER *member;
|
||||
int i = 0;
|
||||
@@ -360,7 +332,7 @@ static void get(int argc, char *argv[])
|
||||
#endif
|
||||
)
|
||||
temp_fd = open_archive(temp_arch, CREATE);
|
||||
while ((member = get_member()) != NULL) {
|
||||
while ((member = get_member()) != NIL_MEM) {
|
||||
if (argc > 3) {
|
||||
for (i = 3; i < argc; i++) {
|
||||
if (equal(basename(argv[i]), member->ar_name))
|
||||
@@ -489,7 +461,10 @@ static void get(int argc, char *argv[])
|
||||
close(ar_fd);
|
||||
}
|
||||
|
||||
static void add(char *name, int fd, char *mess)
|
||||
add(name, fd, mess)
|
||||
char *name;
|
||||
int fd;
|
||||
char *mess;
|
||||
{
|
||||
static MEMBER member;
|
||||
register int read_chars;
|
||||
@@ -497,15 +472,15 @@ static void add(char *name, int fd, char *mess)
|
||||
int src_fd;
|
||||
|
||||
if (stat(name, &status) < 0) {
|
||||
error2(FALSE, "cannot find %s\n", name);
|
||||
error(FALSE, "cannot find %s\n", name);
|
||||
return;
|
||||
}
|
||||
else if (S_ISDIR(status.st_mode)) {
|
||||
error2(FALSE, "%s is a directory (ignored)\n", name);
|
||||
error(FALSE, "%s is a directory (ignored)\n", name);
|
||||
return;
|
||||
}
|
||||
else if ((src_fd = open(name, 0)) < 0) {
|
||||
error2(FALSE, "cannot open %s\n", name);
|
||||
error(FALSE, "cannot open %s\n", name);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -541,7 +516,7 @@ static void add(char *name, int fd, char *mess)
|
||||
}
|
||||
else status.st_size -= x;
|
||||
if (read(src_fd, io_buffer, read_chars) != read_chars) {
|
||||
error2(FALSE,"%s seems to shrink\n", name);
|
||||
error(FALSE,"%s seems to shrink\n", name);
|
||||
break;
|
||||
}
|
||||
mwrite(fd, io_buffer, x);
|
||||
@@ -552,7 +527,8 @@ static void add(char *name, int fd, char *mess)
|
||||
close(src_fd);
|
||||
}
|
||||
|
||||
static void extract(register MEMBER *member)
|
||||
extract(member)
|
||||
register MEMBER *member;
|
||||
{
|
||||
int fd = 1;
|
||||
char buf[sizeof(member->ar_name) + 1];
|
||||
@@ -560,7 +536,7 @@ static void extract(register MEMBER *member)
|
||||
strncpy(buf, member->ar_name, sizeof(member->ar_name));
|
||||
buf[sizeof(member->ar_name)] = 0;
|
||||
if (pr_fl == FALSE && (fd = creat(buf, 0666)) < 0) {
|
||||
error2(FALSE, "cannot create %s\n", buf);
|
||||
error(FALSE, "cannot create %s\n", buf);
|
||||
fd = -1;
|
||||
}
|
||||
|
||||
@@ -576,7 +552,9 @@ static void extract(register MEMBER *member)
|
||||
if (pr_fl == FALSE) chmod(buf, member->ar_mode);
|
||||
}
|
||||
|
||||
static void copy_member(MEMBER *member, int from, int to, int extracting)
|
||||
copy_member(member, from, to, extracting)
|
||||
register MEMBER *member;
|
||||
int from, to;
|
||||
{
|
||||
register int rest;
|
||||
long mem_size = member->ar_size;
|
||||
@@ -598,7 +576,7 @@ static void copy_member(MEMBER *member, int from, int to, int extracting)
|
||||
|
||||
strncpy(buf, member->ar_name, sizeof(member->ar_name));
|
||||
buf[sizeof(member->ar_name)] = 0;
|
||||
error2(TRUE, "read error on %s\n", buf);
|
||||
error(TRUE, "read error on %s\n", buf);
|
||||
}
|
||||
if (to >= 0) mwrite(to, io_buffer, rest);
|
||||
mem_size -= (long) rest;
|
||||
@@ -633,23 +611,27 @@ register int mode;
|
||||
return mode_buf;
|
||||
}
|
||||
|
||||
void wr_fatal()
|
||||
wr_fatal()
|
||||
{
|
||||
error1(TRUE, "write error\n");
|
||||
error(TRUE, "write error\n");
|
||||
}
|
||||
|
||||
void rd_fatal()
|
||||
rd_fatal()
|
||||
{
|
||||
error1(TRUE, "read error\n");
|
||||
error(TRUE, "read error\n");
|
||||
}
|
||||
|
||||
static void mwrite(int fd, char *address, int bytes)
|
||||
mwrite(fd, address, bytes)
|
||||
int fd;
|
||||
register char *address;
|
||||
register int bytes;
|
||||
{
|
||||
if (write(fd, address, bytes) != bytes)
|
||||
error1(TRUE, "write error\n");
|
||||
error(TRUE, "write error\n");
|
||||
}
|
||||
|
||||
static void show(char *s, char *name)
|
||||
show(s, name)
|
||||
char *s, *name;
|
||||
{
|
||||
MEMBER x;
|
||||
char buf[sizeof(x.ar_name)+1];
|
||||
@@ -667,7 +649,7 @@ static void show(char *s, char *name)
|
||||
* then 4 bytes giving the size of the string table, followed by the string
|
||||
* table itself.
|
||||
*/
|
||||
static void write_symdef(void)
|
||||
write_symdef()
|
||||
{
|
||||
register struct ranlib *ran;
|
||||
register int i;
|
||||
@@ -712,12 +694,15 @@ static void write_symdef(void)
|
||||
* The header is put in `headp'.
|
||||
*/
|
||||
int
|
||||
is_outhead(register struct outhead *headp)
|
||||
is_outhead(headp)
|
||||
register struct outhead *headp;
|
||||
{
|
||||
|
||||
return !BADMAGIC(*headp) && headp->oh_nname != 0;
|
||||
}
|
||||
|
||||
static void do_object(int f, long size)
|
||||
do_object(f, size)
|
||||
long size;
|
||||
{
|
||||
struct outhead headbuf;
|
||||
|
||||
@@ -743,7 +728,8 @@ static void do_object(int f, long size)
|
||||
* name table and read and write the names one by one. Update the ranlib table
|
||||
* accordingly.
|
||||
*/
|
||||
static void do_names(struct outhead *headp)
|
||||
do_names(headp)
|
||||
struct outhead *headp;
|
||||
{
|
||||
register char *strings;
|
||||
register int nnames = headp->oh_nname;
|
||||
@@ -754,7 +740,7 @@ static void do_names(struct outhead *headp)
|
||||
if ( headp->oh_nchar != (unsigned int)headp->oh_nchar ||
|
||||
(strings = malloc((unsigned int)headp->oh_nchar)) == (char *)0
|
||||
) {
|
||||
error1(TRUE, "string table too big\n");
|
||||
error(TRUE, "string table too big\n");
|
||||
}
|
||||
rd_string(strings, headp->oh_nchar);
|
||||
while (nnames) {
|
||||
@@ -788,14 +774,15 @@ static void do_names(struct outhead *headp)
|
||||
free(strings);
|
||||
}
|
||||
|
||||
static void enter_name(struct outname *namep)
|
||||
enter_name(namep)
|
||||
struct outname *namep;
|
||||
{
|
||||
register char *cp;
|
||||
|
||||
if (tnum >= tabsz) {
|
||||
tab = (struct ranlib *)
|
||||
realloc((char *) tab, (tabsz += 512) * sizeof(struct ranlib));
|
||||
if (! tab) error1(TRUE, "Out of core\n");
|
||||
if (! tab) error(TRUE, "Out of core\n");
|
||||
}
|
||||
tab[tnum].ran_off = tssiz;
|
||||
tab[tnum].ran_pos = offset;
|
||||
@@ -803,11 +790,11 @@ static void enter_name(struct outname *namep)
|
||||
for (cp = namep->on_mptr;; cp++) {
|
||||
if (tssiz >= strtabsz) {
|
||||
tstrtab = realloc(tstrtab, (strtabsz += 4096));
|
||||
if (! tstrtab) error1(TRUE, "string table overflow\n");
|
||||
if (! tstrtab) error(TRUE, "string table overflow\n");
|
||||
}
|
||||
tstrtab[tssiz++] = *cp;
|
||||
if (!*cp) break;
|
||||
}
|
||||
tnum++;
|
||||
}
|
||||
#endif /* AAL */
|
||||
#endif AAL
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
|
||||
extern void rd_fatal();
|
||||
extern void wr_fatal();
|
||||
3
commands/aal/build
Executable file
3
commands/aal/build
Executable file
@@ -0,0 +1,3 @@
|
||||
#!/bin/sh
|
||||
make clean
|
||||
make && make install
|
||||
0
commands/aal/byte_order.h
Normal file → Executable file
0
commands/aal/byte_order.h
Normal file → Executable file
14
commands/aal/format.c
Normal file → Executable file
14
commands/aal/format.c
Normal file → Executable file
@@ -9,12 +9,11 @@
|
||||
#else
|
||||
#include <varargs.h>
|
||||
#endif
|
||||
#include <string.h>
|
||||
|
||||
extern char *long2str();
|
||||
|
||||
static int
|
||||
integral(int c)
|
||||
integral(c)
|
||||
{
|
||||
switch (c) {
|
||||
case 'b':
|
||||
@@ -40,14 +39,16 @@ integral(int c)
|
||||
%d = int
|
||||
$ */
|
||||
int
|
||||
_format(char *buf, char *fmt, va_list argp)
|
||||
_format(buf, fmt, argp)
|
||||
char *buf, *fmt;
|
||||
register va_list argp;
|
||||
{
|
||||
register char *pf = fmt;
|
||||
register char *pb = buf;
|
||||
|
||||
while (*pf) {
|
||||
if (*pf == '%') {
|
||||
register int width, base, pad, npad;
|
||||
register width, base, pad, npad;
|
||||
char *arg;
|
||||
char cbuf[2];
|
||||
char *badformat = "<bad format>";
|
||||
@@ -77,8 +78,7 @@ _format(char *buf, char *fmt, va_list argp)
|
||||
else
|
||||
if (*pf == 'l') {
|
||||
/* alignment ??? */
|
||||
base = integral(*++pf);
|
||||
if (base) {
|
||||
if (base = integral(*++pf)) {
|
||||
arg = long2str(va_arg(argp,long), base);
|
||||
}
|
||||
else {
|
||||
@@ -87,7 +87,7 @@ _format(char *buf, char *fmt, va_list argp)
|
||||
}
|
||||
}
|
||||
else
|
||||
if ((base = integral(*pf))) {
|
||||
if (base = integral(*pf)) {
|
||||
arg = long2str((long)va_arg(argp,int), base);
|
||||
}
|
||||
else
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
|
||||
extern int _format(char *buf, char *fmt, va_list argp);
|
||||
2
commands/aal/local.h
Normal file → Executable file
2
commands/aal/local.h
Normal file → Executable file
@@ -12,7 +12,7 @@
|
||||
# define ACKM "minix"
|
||||
|
||||
/* size of local machine, either 0 (for 16 bit address space), or 1 */
|
||||
# undef BIGMACHINE
|
||||
# undef BIGMACHINE 1
|
||||
|
||||
/* operating system, SYS_5, V7, BSD4_1 or BSD4_2; Do NOT delete the comment
|
||||
in the next line! */
|
||||
|
||||
4
commands/aal/long2str.c
Normal file → Executable file
4
commands/aal/long2str.c
Normal file → Executable file
@@ -15,7 +15,7 @@
|
||||
char *
|
||||
long2str(val, base)
|
||||
register long val;
|
||||
register int base;
|
||||
register base;
|
||||
{
|
||||
static char numbuf[MAXWIDTH];
|
||||
static char vec[] = "0123456789ABCDEF";
|
||||
@@ -38,7 +38,7 @@ long2str(val, base)
|
||||
if (base < 0) { /* unsigned */
|
||||
base = -base;
|
||||
if (val < 0L) { /* taken from Amoeba src */
|
||||
register int mod, i;
|
||||
register mod, i;
|
||||
overflow:
|
||||
mod = 0;
|
||||
for (i = 0; i < 8 * sizeof val; i++) {
|
||||
|
||||
0
commands/aal/object.h
Normal file → Executable file
0
commands/aal/object.h
Normal file → Executable file
0
commands/aal/out.h
Normal file → Executable file
0
commands/aal/out.h
Normal file → Executable file
0
commands/aal/param.h
Normal file → Executable file
0
commands/aal/param.h
Normal file → Executable file
4
commands/aal/print.c
Normal file → Executable file
4
commands/aal/print.c
Normal file → Executable file
@@ -11,8 +11,6 @@
|
||||
#endif
|
||||
#include <system.h>
|
||||
#include "param.h"
|
||||
#include "format.h"
|
||||
#include "write.h"
|
||||
|
||||
/*VARARGS*/
|
||||
/*FORMAT0v $
|
||||
@@ -22,7 +20,7 @@
|
||||
%[uxbo] = unsigned int
|
||||
%d = int
|
||||
$ */
|
||||
void
|
||||
int
|
||||
#if __STDC__
|
||||
print(char *fmt, ...)
|
||||
#else
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
|
||||
extern void print(char *fmt, ...);
|
||||
2
commands/aal/ranlib.h
Normal file → Executable file
2
commands/aal/ranlib.h
Normal file → Executable file
@@ -31,6 +31,4 @@ struct ranlib {
|
||||
#define SZ_RAN 8
|
||||
#define SF_RAN "44"
|
||||
|
||||
extern void wr_ranlib(int fd, struct ranlib ran[], long cnt);
|
||||
#endif /* __RANLIB_H_INCLUDED */
|
||||
|
||||
|
||||
51
commands/aal/rd.c
Normal file → Executable file
51
commands/aal/rd.c
Normal file → Executable file
@@ -3,13 +3,8 @@
|
||||
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
|
||||
* See the copyright notice in the ACK home directory, in the file "Copyright".
|
||||
*/
|
||||
#include <sys/types.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include "out.h"
|
||||
#include <out.h>
|
||||
#include "object.h"
|
||||
#include "rd.h"
|
||||
#include "rd_bytes.h"
|
||||
|
||||
extern long lseek();
|
||||
|
||||
@@ -48,7 +43,9 @@ static long rd_base;
|
||||
static int sectionnr;
|
||||
|
||||
static
|
||||
void OUTREAD(int p, char *b, long n)
|
||||
OUTREAD(p, b, n)
|
||||
char *b;
|
||||
long n;
|
||||
{
|
||||
register long l = outseek[p];
|
||||
|
||||
@@ -65,17 +62,18 @@ void OUTREAD(int p, char *b, long n)
|
||||
* Open the output file according to the chosen strategy.
|
||||
*/
|
||||
int
|
||||
rd_open(char *f)
|
||||
rd_open(f)
|
||||
char *f;
|
||||
{
|
||||
int outfile = open(f, 0);
|
||||
if (outfile < 0)
|
||||
|
||||
if ((outfile = open(f, 0)) < 0)
|
||||
return 0;
|
||||
return rd_fdopen(outfile);
|
||||
}
|
||||
|
||||
static int offcnt;
|
||||
|
||||
int rd_fdopen(int fd)
|
||||
rd_fdopen(fd)
|
||||
{
|
||||
register int i;
|
||||
|
||||
@@ -92,19 +90,20 @@ int rd_fdopen(int fd)
|
||||
return 1;
|
||||
}
|
||||
|
||||
void rd_close()
|
||||
rd_close()
|
||||
{
|
||||
|
||||
close(outfile);
|
||||
outfile = -1;
|
||||
}
|
||||
|
||||
int rd_fd()
|
||||
rd_fd()
|
||||
{
|
||||
return outfile;
|
||||
}
|
||||
|
||||
void rd_ohead(register struct outhead *head)
|
||||
rd_ohead(head)
|
||||
register struct outhead *head;
|
||||
{
|
||||
register long off;
|
||||
|
||||
@@ -136,7 +135,7 @@ void rd_ohead(register struct outhead *head)
|
||||
#endif
|
||||
}
|
||||
|
||||
void rd_rew_relos(head)
|
||||
rd_rew_relos(head)
|
||||
register struct outhead *head;
|
||||
{
|
||||
register long off = OFF_RELO(*head) + rd_base;
|
||||
@@ -144,7 +143,7 @@ void rd_rew_relos(head)
|
||||
BEGINSEEK(PARTRELO, off);
|
||||
}
|
||||
|
||||
void rd_sect(sect, cnt)
|
||||
rd_sect(sect, cnt)
|
||||
register struct outsect *sect;
|
||||
register unsigned int cnt;
|
||||
{
|
||||
@@ -174,7 +173,7 @@ void rd_sect(sect, cnt)
|
||||
}
|
||||
}
|
||||
|
||||
void rd_outsect(int s)
|
||||
rd_outsect(s)
|
||||
{
|
||||
OUTSECT(s);
|
||||
sectionnr = s;
|
||||
@@ -183,7 +182,7 @@ void rd_outsect(int s)
|
||||
/*
|
||||
* We don't have to worry about byte order here.
|
||||
*/
|
||||
void rd_emit(emit, cnt)
|
||||
rd_emit(emit, cnt)
|
||||
char *emit;
|
||||
long cnt;
|
||||
{
|
||||
@@ -191,10 +190,11 @@ void rd_emit(emit, cnt)
|
||||
offset[sectionnr] += cnt;
|
||||
}
|
||||
|
||||
void rd_relo(relo, cnt)
|
||||
rd_relo(relo, cnt)
|
||||
register struct outrelo *relo;
|
||||
register unsigned int cnt;
|
||||
{
|
||||
|
||||
OUTREAD(PARTRELO, (char *) relo, (long) cnt * SZ_RELO);
|
||||
#if ! (BYTES_REVERSED || WORDS_REVERSED)
|
||||
if (sizeof(struct outrelo) != SZ_RELO)
|
||||
@@ -213,7 +213,9 @@ void rd_relo(relo, cnt)
|
||||
}
|
||||
}
|
||||
|
||||
void rd_name(struct outname *name, unsigned int cnt)
|
||||
rd_name(name, cnt)
|
||||
register struct outname *name;
|
||||
register unsigned int cnt;
|
||||
{
|
||||
|
||||
OUTREAD(PARTNAME, (char *) name, (long) cnt * SZ_NAME);
|
||||
@@ -234,13 +236,18 @@ void rd_name(struct outname *name, unsigned int cnt)
|
||||
}
|
||||
}
|
||||
|
||||
void rd_string(char *addr, long len)
|
||||
rd_string(addr, len)
|
||||
char *addr;
|
||||
long len;
|
||||
{
|
||||
|
||||
OUTREAD(PARTCHAR, addr, len);
|
||||
}
|
||||
|
||||
#ifdef SYMDBUG
|
||||
void rd_dbug(char *buf, long size)
|
||||
rd_dbug(buf, size)
|
||||
char *buf;
|
||||
long size;
|
||||
{
|
||||
OUTREAD(PARTDBUG, buf, size);
|
||||
}
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
/*
|
||||
* Headers for rd.c
|
||||
*/
|
||||
|
||||
#include "out.h"
|
||||
|
||||
extern void rd_string(char *addr, long len);
|
||||
extern void rd_name(struct outname name[], unsigned int cnt);
|
||||
extern int rd_fdopen(int fd);
|
||||
extern void rd_ohead(register struct outhead head[]);
|
||||
8
commands/aal/rd_arhdr.c
Normal file → Executable file
8
commands/aal/rd_arhdr.c
Normal file → Executable file
@@ -3,16 +3,12 @@
|
||||
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
|
||||
* See the copyright notice in the ACK home directory, in the file "Copyright".
|
||||
*/
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <arch.h>
|
||||
#include "object.h"
|
||||
|
||||
#include "arch.h"
|
||||
#include "archiver.h"
|
||||
|
||||
int
|
||||
rd_arhdr(int fd, register struct ar_hdr *arhdr)
|
||||
rd_arhdr(fd, arhdr)
|
||||
register struct ar_hdr *arhdr;
|
||||
{
|
||||
char buf[AR_TOTAL];
|
||||
register char *c = buf;
|
||||
|
||||
11
commands/aal/rd_bytes.c
Normal file → Executable file
11
commands/aal/rd_bytes.c
Normal file → Executable file
@@ -9,19 +9,16 @@
|
||||
an int!
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "archiver.h"
|
||||
#include "rd_bytes.h"
|
||||
|
||||
static int maxchunk = MAXCHUNK;
|
||||
|
||||
/*
|
||||
* We don't have to worry about byte order here.
|
||||
* Just read "cnt" bytes from file-descriptor "fd".
|
||||
*/
|
||||
void rd_bytes(int fd, char *string, long cnt)
|
||||
int
|
||||
rd_bytes(fd, string, cnt)
|
||||
register char *string;
|
||||
register long cnt;
|
||||
{
|
||||
|
||||
while (cnt) {
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
|
||||
extern void rd_bytes(int fd, char *string, long cnt);
|
||||
3
commands/aal/rd_unsig2.c
Normal file → Executable file
3
commands/aal/rd_unsig2.c
Normal file → Executable file
@@ -4,10 +4,9 @@
|
||||
* See the copyright notice in the ACK home directory, in the file "Copyright".
|
||||
*/
|
||||
#include "object.h"
|
||||
#include "rd_bytes.h"
|
||||
|
||||
unsigned int
|
||||
rd_unsigned2(int fd)
|
||||
rd_unsigned2(fd)
|
||||
{
|
||||
char buf[2];
|
||||
|
||||
|
||||
1
commands/aal/sprint.c
Normal file → Executable file
1
commands/aal/sprint.c
Normal file → Executable file
@@ -11,7 +11,6 @@
|
||||
#endif
|
||||
#include <system.h>
|
||||
#include "param.h"
|
||||
#include "format.h"
|
||||
|
||||
/*VARARGS*/
|
||||
/*FORMAT1v $
|
||||
|
||||
0
commands/aal/system.c
Normal file → Executable file
0
commands/aal/system.c
Normal file → Executable file
4
commands/aal/system.h
Normal file → Executable file
4
commands/aal/system.h
Normal file → Executable file
@@ -43,7 +43,5 @@ extern File _sys_ftab[];
|
||||
#define ILL_BREAK ((char *)0)
|
||||
|
||||
/* system's idea of block */
|
||||
#ifndef BUFSIZ
|
||||
#define BUFSIZ 1024
|
||||
#endif
|
||||
#endif /* __SYSTEM_INCLUDED__ */
|
||||
#endif __SYSTEM_INCLUDED__
|
||||
|
||||
0
commands/aal/varargs.h
Normal file → Executable file
0
commands/aal/varargs.h
Normal file → Executable file
6
commands/aal/wr_arhdr.c
Normal file → Executable file
6
commands/aal/wr_arhdr.c
Normal file → Executable file
@@ -5,11 +5,9 @@
|
||||
*/
|
||||
#include <arch.h>
|
||||
#include "object.h"
|
||||
#include "arch.h"
|
||||
#include "write.h"
|
||||
#include "wr_bytes.h"
|
||||
|
||||
void wr_arhdr(int fd, struct ar_hdr *arhdr)
|
||||
wr_arhdr(fd, arhdr)
|
||||
register struct ar_hdr *arhdr;
|
||||
{
|
||||
char buf[AR_TOTAL];
|
||||
register char *c = buf;
|
||||
|
||||
9
commands/aal/wr_bytes.c
Normal file → Executable file
9
commands/aal/wr_bytes.c
Normal file → Executable file
@@ -9,17 +9,14 @@
|
||||
You have to put it in an int!
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include "wr_bytes.h"
|
||||
#include "archiver.h"
|
||||
|
||||
static int maxchunk = MAXCHUNK;
|
||||
|
||||
/*
|
||||
* Just write "cnt" bytes to file-descriptor "fd".
|
||||
*/
|
||||
void wr_bytes(int fd, register char *string, long cnt)
|
||||
wr_bytes(fd, string, cnt)
|
||||
register char *string;
|
||||
register long cnt;
|
||||
{
|
||||
|
||||
while (cnt) {
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
/*
|
||||
* Exported symbols of wr_bytes.c
|
||||
*/
|
||||
extern void wr_bytes(int fd, register char *string, long cnt);
|
||||
4
commands/aal/wr_int2.c
Normal file → Executable file
4
commands/aal/wr_int2.c
Normal file → Executable file
@@ -4,10 +4,8 @@
|
||||
* See the copyright notice in the ACK home directory, in the file "Copyright".
|
||||
*/
|
||||
#include "object.h"
|
||||
#include "wr_int2.h"
|
||||
#include "wr_bytes.h"
|
||||
|
||||
void wr_int2(int fd, int i)
|
||||
wr_int2(fd, i)
|
||||
{
|
||||
char buf[2];
|
||||
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
|
||||
extern void wr_int2(int fd, int i);
|
||||
5
commands/aal/wr_long.c
Normal file → Executable file
5
commands/aal/wr_long.c
Normal file → Executable file
@@ -4,10 +4,9 @@
|
||||
* See the copyright notice in the ACK home directory, in the file "Copyright".
|
||||
*/
|
||||
#include "object.h"
|
||||
#include "wr_bytes.h"
|
||||
#include "wr_long.h"
|
||||
|
||||
void wr_long(int fd, long l)
|
||||
wr_long(fd, l)
|
||||
long l;
|
||||
{
|
||||
char buf[4];
|
||||
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
|
||||
extern void wr_long(int fd, long l);
|
||||
6
commands/aal/wr_ranlib.c
Normal file → Executable file
6
commands/aal/wr_ranlib.c
Normal file → Executable file
@@ -5,10 +5,10 @@
|
||||
*/
|
||||
#include <ranlib.h>
|
||||
#include "object.h"
|
||||
#include "wr_bytes.h"
|
||||
#include "ranlib.h"
|
||||
|
||||
void wr_ranlib(int fd, struct ranlib *ran, long cnt)
|
||||
wr_ranlib(fd, ran, cnt)
|
||||
register struct ranlib *ran;
|
||||
register long cnt;
|
||||
{
|
||||
#if ! (BYTES_REVERSED || WORDS_REVERSED)
|
||||
if (sizeof (struct ranlib) != SZ_RAN)
|
||||
|
||||
8
commands/aal/write.c
Normal file → Executable file
8
commands/aal/write.c
Normal file → Executable file
@@ -4,13 +4,13 @@
|
||||
*/
|
||||
/* $Header$ */
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <system.h>
|
||||
#include "write.h"
|
||||
|
||||
int
|
||||
sys_write(File *fp, char *bufptr, int nbytes)
|
||||
sys_write(fp, bufptr, nbytes)
|
||||
File *fp;
|
||||
char *bufptr;
|
||||
int nbytes;
|
||||
{
|
||||
if (! fp) return 0;
|
||||
return write(fp->o_fd, bufptr, nbytes) == nbytes;
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
|
||||
#include "system.h"
|
||||
extern int sys_write(File *fp, char *bufptr, int nbytes);
|
||||
@@ -1,13 +0,0 @@
|
||||
# Makefile for acd
|
||||
|
||||
.include <bsd.own.mk>
|
||||
|
||||
PROG= acd
|
||||
CPPFLAGS+= -DARCH=\"`arch`\" -DDESCR=\"/usr/lib/descr\"
|
||||
LINKS+= ${BINDIR}/acd ${BINDIR}/cc
|
||||
FILESDIR= /usr/lib
|
||||
FILES= acd.descr
|
||||
FILESNAME= descr
|
||||
MAN=
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
@@ -1,438 +0,0 @@
|
||||
# ACD pass description for the ACK compilers.
|
||||
#
|
||||
# Pre-set variables.
|
||||
# PROGRAM - Name the compiler driver is called with.
|
||||
# ARCH - Default target architecture.
|
||||
|
||||
# Library directories search path.
|
||||
L = /lib /usr/lib
|
||||
|
||||
# ACK Compilers support search path.
|
||||
A = $L $L/ack
|
||||
|
||||
# ARCH must be defined.
|
||||
ifndef ARCH
|
||||
error "\$ARCH is not predefined"
|
||||
|
||||
# Get ARCH from the environment if set.
|
||||
import ARCH
|
||||
|
||||
# Compiler passes.
|
||||
ACK_CPP = $A/cpp.ansi $CPP_F $PREDEF $NOLINENO
|
||||
ACK_CEM = $A/em_cemcom.ansi -L $CPP_F $PREDEF \
|
||||
-Vw${W}.${W}i${W}.${W}p${P}.${W}f4.${W}s2.2l4.${W}d8.${W}
|
||||
ACK_M2 = $A/em_m2 -I$MOD_INCL -WR \
|
||||
-Vw${W}.${W}i${W}.${W}p${P}.${W}l4.${W}f4.${W}d8.${W}
|
||||
ACK_PC = $A/em_pc \
|
||||
-Vw${W}.${W}i${W}.${W}l4.${W}p${P}.${W}f8.${W}S${W}.${W}
|
||||
MOD_INCL = $A/m2 +
|
||||
ACK_DECODE = $A/em_decode
|
||||
ACK_ENCODE = $A/em_encode
|
||||
ACK_OPT = $A/em_opt
|
||||
ACK_EGO = $A/em_ego -P $A/ego -M$EGO_DESCR
|
||||
EGO_DESCR = $A/ego/${ARCH}descr +
|
||||
ACK_OPT2 = $A/em_opt2
|
||||
ACK_CG = $A/$ARCH/cg
|
||||
ACK_AS = $A/$ARCH/as \-
|
||||
ACK_LED = $A/em_led -a0:$W -a1:$W -a2:$W -a3:$W
|
||||
ACK_CV = $A/cv
|
||||
ASMCONV = /usr/bin/asmconv
|
||||
AAL = /usr/bin/aal
|
||||
|
||||
# Minix predefined symbols.
|
||||
CPP_F = -D__minix -D__minix3 -D__$ARCH
|
||||
|
||||
# Library path.
|
||||
LIBPATH = $USERLIBPATH $A/$ARCH
|
||||
|
||||
# Default output "model".
|
||||
MODEL = -sep
|
||||
|
||||
# Floating point is done in software.
|
||||
LIBS = -fsoft
|
||||
|
||||
# Default optimization level.
|
||||
OPT_LEVEL = 1
|
||||
|
||||
# Call names.
|
||||
if $PROGRAM = acc
|
||||
PROGRAM = cc
|
||||
if $PROGRAM = apc
|
||||
PROGRAM = pc
|
||||
if $PROGRAM = am2
|
||||
PROGRAM = m2
|
||||
if $PROGRAM = kcc
|
||||
PROGRAM = cc
|
||||
|
||||
# Default transformation target.
|
||||
stop .out
|
||||
|
||||
# Select the runtime environment by option or program name.
|
||||
arg -.c
|
||||
if $PROGRAM = cc
|
||||
ifndef RTSO
|
||||
RTSO = -.c
|
||||
LIBS = $LIBS + -.c
|
||||
|
||||
# Omit the runtime startoff, but keep the libraries.
|
||||
arg -.o
|
||||
RTSO =
|
||||
|
||||
arg -.$any
|
||||
error ".$any: unknown language"
|
||||
|
||||
# Select the target architecture.
|
||||
arg -m$arch
|
||||
ARCH = $arch
|
||||
|
||||
# Preprocessor directives.
|
||||
arg -D$name
|
||||
arg -D $name
|
||||
CPP_F = $CPP_F -D$name
|
||||
arg -U$name
|
||||
arg -U $name
|
||||
CPP_F = $CPP_F -U$name
|
||||
arg -I$dir
|
||||
arg -I $dir
|
||||
CPP_F = $CPP_F -I$dir
|
||||
ACK_M2 = $ACK_M2 -I$dir
|
||||
|
||||
# Debugging.
|
||||
arg -g # Add debugging info.
|
||||
ACK_CEM = $ACK_CEM -g
|
||||
ACK_CG = $ACK_CG -gdb
|
||||
|
||||
arg -n # Suppress line numbers.
|
||||
ACK_M2 = $ACK_M2 -L
|
||||
ACK_PC = $ACK_PC -L
|
||||
arg -a # Enable assertions.
|
||||
arg -A # Enable array bound checks.
|
||||
ACK_M2 = $ACK_M2 $*
|
||||
ACK_PC = $ACK_PC $*
|
||||
|
||||
# Language checking.
|
||||
arg -w # No warnings.
|
||||
ACK_CEM = $ACK_CEM $*
|
||||
ACK_M2 = $ACK_M2 $*
|
||||
ACK_PC = $ACK_PC $*
|
||||
|
||||
arg -ws # No strict warnings.
|
||||
ACK_CEM = $ACK_CEM -s
|
||||
ACK_M2 = $ACK_M2 -wR
|
||||
|
||||
arg -wa # No warnings and no strict warnings.
|
||||
ACK_CEM = $ACK_CEM -a
|
||||
ACK_M2 = $ACK_M2 -wR
|
||||
|
||||
arg -wo # No warnings about old style C.
|
||||
ACK_CPP = $ACK_CPP -o
|
||||
ACK_CEM = $ACK_CEM -o
|
||||
ACK_M2 = $ACK_M2 -wO
|
||||
|
||||
arg -3 # Only accept 3rd generation Modula-2.
|
||||
ACK_M2 = $ACK_M2 $*
|
||||
|
||||
arg -_ # Allow underscores in identifiers.
|
||||
ACK_M2 = $ACK_M2 -U
|
||||
ACK_PC = $ACK_PC -U
|
||||
|
||||
arg -w$any
|
||||
arg -F
|
||||
arg -m
|
||||
# Ignore strange -w flags, and past and present i86 compiler flags.
|
||||
|
||||
# Stop suffix.
|
||||
arg -c
|
||||
stop .o
|
||||
|
||||
arg -c.$stop
|
||||
stop .$stop
|
||||
|
||||
arg -E
|
||||
stop .E
|
||||
|
||||
arg -P
|
||||
CPP_F = $CPP_F -P
|
||||
stop .i
|
||||
|
||||
arg -S
|
||||
stop .s
|
||||
|
||||
# Optimization.
|
||||
arg -O
|
||||
OPT_LEVEL = 1
|
||||
|
||||
arg -OS # Optimize for size.
|
||||
ACK_EGO = $ACK_EGO -S
|
||||
arg -OT # Optimize for time.
|
||||
ACK_EGO = $ACK_EGO -T
|
||||
|
||||
arg -O$n
|
||||
numeric $n
|
||||
OPT_LEVEL = $n
|
||||
|
||||
# Library search path.
|
||||
arg -L$dir
|
||||
arg -L $dir
|
||||
USERLIBPATH = $USERLIBPATH $dir/$ARCH $dir
|
||||
|
||||
# -llib must be searched in $LIBPATH later.
|
||||
arg -l$lib
|
||||
arg -l $lib
|
||||
$> = $LIBPATH/lib$lib.a
|
||||
|
||||
# Software floating point, hardware floating point, or no floating point.
|
||||
arg -f
|
||||
arg -fp
|
||||
arg -fsoft
|
||||
LIBS = $LIBS + -fsoft
|
||||
|
||||
arg -fhard
|
||||
LIBS = $LIBS - -fsoft
|
||||
|
||||
arg -fnone
|
||||
LIBS = $LIBS + -fnone
|
||||
|
||||
# Output model.
|
||||
arg -com
|
||||
MODEL = # Common I&D.
|
||||
|
||||
arg -sep
|
||||
arg -i # Separate I&D.
|
||||
MODEL = -sep
|
||||
|
||||
arg -r # Relocatable object (combined .o)
|
||||
MODEL = -r
|
||||
|
||||
# Strip executable.
|
||||
arg -s
|
||||
ACK_LED = $ACK_LED -s
|
||||
|
||||
# Size of heap+stack.
|
||||
arg -stack $size
|
||||
ACK_CV = $ACK_CV -S $size
|
||||
|
||||
# Change output file.
|
||||
arg -o$out
|
||||
arg -o $out
|
||||
OUT = $out
|
||||
|
||||
# Complain about just -D, -U, -I, ...
|
||||
arg -D; arg -U; arg -I; arg -L; arg -l; arg -o; arg -stack
|
||||
error "argument expected after '$*'"
|
||||
|
||||
arg -R$pass-$flag # The ACK way of passing options to passes.
|
||||
arg -Wack-R$pass-$flag # The ACD way.
|
||||
if $pass = cpp
|
||||
ACK_CPP = $ACK_CPP -$flag
|
||||
if $pass = cem
|
||||
ACK_CEM = $ACK_CEM -$flag
|
||||
if $pass = m2
|
||||
ACK_M2 = $ACK_M2 -$flag
|
||||
if $pass = pc
|
||||
ACK_PC = $ACK_PC -$flag
|
||||
if $pass = opt
|
||||
ACK_OPT = $ACK_OPT -$flag
|
||||
if $pass = ego
|
||||
ACK_EGO = $ACK_EGO -$flag
|
||||
if $pass = opt2
|
||||
ACK_OPT2 = $ACK_OPT2 -$flag
|
||||
if $pass = cg
|
||||
ACK_CG = $ACK_CG -$flag
|
||||
if $pass = as
|
||||
ACK_AS = $ACK_AS -$flag
|
||||
if $pass = led
|
||||
ACK_LED = $ACK_LED -$flag
|
||||
|
||||
arg -Was-$dialect # Default assembly dialect.
|
||||
ASDIALECT = $dialect
|
||||
|
||||
arg -W$any
|
||||
# Ignore any other -W options.
|
||||
|
||||
# Complain about unknown options, don't give them to the loader.
|
||||
arg -$any
|
||||
error "$*: unknown option"
|
||||
|
||||
# Do the scanning phase early, we need to know the architecture.
|
||||
scan
|
||||
|
||||
# The word and pointer sizes of the target.
|
||||
if $ARCH = i86
|
||||
W = 2; P = 2
|
||||
if $ARCH = i386
|
||||
W = 4; P = 4
|
||||
|
||||
ifndef W
|
||||
error "$ARCH: unsupported architecture"
|
||||
|
||||
# Optimize -O2 or higher?
|
||||
if (0 1 - $OPT_LEVEL) = (0 1)
|
||||
ACK_EGO = $ACK_EGO -O$OPT_LEVEL
|
||||
ACK_OPT = $ACK_OPT -m0 # Leave multiplication optimization to opt2.
|
||||
prefer .m .gk
|
||||
|
||||
# Tell cem to reverse bitfields on the i386 to be compatible with gcc.
|
||||
if $ARCH = i386
|
||||
ACK_CEM = $ACK_CEM -Vr
|
||||
|
||||
# Predefined preprocessor flags.
|
||||
PREDEF = -D_EM_WSIZE=$W -D_EM_PSIZE=$P -D_EM_SSIZE=2 -D_EM_LSIZE=4 \
|
||||
-D_EM_FSIZE=4 -D_EM_DSIZE=8 -D__ACK__ -D_ACK
|
||||
|
||||
# Preprocess C source.
|
||||
transform .c .i
|
||||
$ACK_CPP $* > $>
|
||||
|
||||
# Preprocess any type of file and send it to standard output or $OUT.
|
||||
transform "" .E
|
||||
if $* = "-"
|
||||
file = # Standard input.
|
||||
else
|
||||
file = $*
|
||||
ifndef OUT
|
||||
$ACK_CPP $file
|
||||
else
|
||||
$ACK_CPP $file > $OUT
|
||||
|
||||
# Compile C source to EM-code.
|
||||
transform .c .k
|
||||
transform .i .k
|
||||
$ACK_CEM $* $>
|
||||
ifndef RTSO
|
||||
RTSO = -.c
|
||||
LIBS = $LIBS + -.c
|
||||
|
||||
# Compact EM to readable EM.
|
||||
transform .k .e
|
||||
transform .m .e
|
||||
transform .gk .e
|
||||
transform .g .e
|
||||
$ACK_DECODE $* > $>
|
||||
|
||||
# Readable EM to compact EM.
|
||||
transform .e .k
|
||||
ifhash $*
|
||||
NOLINENO = -P # Encode chokes on cpp line directives.
|
||||
apply .c .i
|
||||
unset NOLINENO
|
||||
$ACK_ENCODE $* > $>
|
||||
|
||||
# Peephole optimization.
|
||||
transform .k .m
|
||||
$ACK_OPT $* > $>
|
||||
|
||||
# Global optimization.
|
||||
transform .m .gk
|
||||
$ACK_EGO $* > $>
|
||||
|
||||
# Second peephole optimization after global optimization.
|
||||
transform .gk .g
|
||||
$ACK_OPT2 $* > $>
|
||||
|
||||
# EM-code to target machine assembly.
|
||||
transform .m .ack.s
|
||||
transform .g .ack.s
|
||||
transform .m .s
|
||||
transform .g .s
|
||||
if $ARCH = i386
|
||||
$ACK_CG -F__fp_hook $* > $>
|
||||
else
|
||||
$ACK_CG $* > $>
|
||||
|
||||
# How to treat plain .s?
|
||||
ifndef ASDIALECT
|
||||
transform .s .ack.s
|
||||
$> = $*
|
||||
|
||||
# Assembly to object file.
|
||||
transform .ack.s .o
|
||||
ifhash $*
|
||||
apply .c .i
|
||||
if $> = $<.o
|
||||
ifdef OUT
|
||||
$> = $OUT
|
||||
$ACK_AS -o $> $*
|
||||
|
||||
# Combine object files and libraries to an executable.
|
||||
combine (.o .a) .out
|
||||
if $MODEL = ()
|
||||
model = -b0:0
|
||||
if $MODEL = (-sep)
|
||||
model = -b0:0 -b1:0
|
||||
rtso =
|
||||
if $RTSO = -.c
|
||||
rtso = $A/$ARCH/crtso.o
|
||||
libd = ; libc = ; libfp =
|
||||
if (-.c - $LIBS) = ()
|
||||
libd = $A/$ARCH/libd.a
|
||||
libc = $A/$ARCH/libc.a
|
||||
if (-fsoft - $LIBS) = ()
|
||||
libfp = $A/$ARCH/libfp.a
|
||||
libs = $libd $libc $libfp $A/$ARCH/libe.a
|
||||
ifndef OUT
|
||||
OUT = a.out
|
||||
if (-r - $MODEL) = ()
|
||||
# Combine to an object file.
|
||||
$ACK_LED -r -o $OUT $*
|
||||
else
|
||||
# Combine to an executable.
|
||||
mktemp EXE
|
||||
$ACK_LED $model -o $EXE $rtso $* $libs $A/$ARCH/libend.a
|
||||
$ACK_CV -x -m$ARCH $EXE $OUT
|
||||
|
||||
# Add object files to a library.
|
||||
combine (.o) .a
|
||||
if $> = $<.a
|
||||
ifdef OUT
|
||||
$> = $OUT
|
||||
$AAL cr $> $*
|
||||
|
||||
# Assembly conversions.
|
||||
|
||||
# ACK assembly to ACK Xenix assembly.
|
||||
transform .ack.s .ncc.s
|
||||
ifhash $*
|
||||
apply .c .i
|
||||
$ASMCONV -m$ARCH ack ncc $* $>
|
||||
|
||||
# ACK assembly to GNU assembly.
|
||||
transform .ack.s .gnu.s
|
||||
ifhash $*
|
||||
apply .c .i
|
||||
$ASMCONV -m$ARCH ack gnu $* $>
|
||||
|
||||
# ACK Xenix assembly to ACK assembly.
|
||||
transform .ncc.s .ack.s
|
||||
ifhash $*
|
||||
apply .c .i
|
||||
$ASMCONV -m$ARCH ncc ack $* $>
|
||||
|
||||
# ACK Xenix assembly to GNU assembly.
|
||||
transform .ncc.s .gnu.s
|
||||
ifhash $*
|
||||
apply .c .i
|
||||
$ASMCONV -m$ARCH ncc gnu $* $>
|
||||
|
||||
# BCC assembly to ACK assembly.
|
||||
transform .bas.s .ack.s
|
||||
ifhash $*
|
||||
apply .c .i
|
||||
$ASMCONV -m$ARCH bas ack $* $>
|
||||
|
||||
# BCC assembly to ACK Xenix assembly.
|
||||
transform .bas.s .ncc.s
|
||||
ifhash $*
|
||||
apply .c .i
|
||||
$ASMCONV -m$ARCH bas ncc $* $>
|
||||
|
||||
# BCC assembly to GNU assembly.
|
||||
transform .bas.s .gnu.s
|
||||
ifhash $*
|
||||
apply .c .i
|
||||
$ASMCONV -m$ARCH bas gnu $* $>
|
||||
|
||||
#ifdef ASDIALECT
|
||||
# Treat plain .s as being in the given dialect.
|
||||
transform .s .$ASDIALECT.s
|
||||
$> = $*
|
||||
@@ -1,4 +0,0 @@
|
||||
PROG= acknm
|
||||
MAN=
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
@@ -1,4 +0,0 @@
|
||||
PROG= ackstrip
|
||||
MAN=
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
@@ -1,6 +0,0 @@
|
||||
PROG= add_route
|
||||
MAN=
|
||||
|
||||
LINKS+= ${BINDIR}/add_route ${BINDIR}/del_route
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user