7.  C

      4.2BSD, while functi[equation] the perf[equation] a g[equation] the distributed system spent 10-20% m4.1BSD. This added user pr[equation] [equation] the system in a general timesharing envir

      Changes made teliminated m[equation] the added system The creduce the average c[equation] translating a pathname tThese changes reduce the percentage time spent running in the system by nearly 9%.

      The use silhas all[equation] stware interrupt pr[equation] field ab[equation] ewer interrupts than bef

      The kernel changes, c[equation] ixes, make the system much mrespThe 4.3BSD Berkeley UNIX system ncapable supp4.1BSD while prand file system facilities.

Ackn

      We w[equation] his c[equation] We thank Alan Smith f[equation] a capability based cache. We alsGe[equation] int[equation] ixes tdisasters that they caused. The buffer cache read-ahead trace package was based implemented several the C library changes. The versi[equation] the Internet daemIn additiwe wideas, inf

References

[Cabrera84]
Luis Felipe Cabrera, Eduard Hunter, Michael J. Karels, and David M``A User-Pr[equation] [equation] Ethernet NetwBerkeley UNIX 4.2BSD,'' Research Rep[equation] CalifBerkeley, December 1984.
[Cabrera85]
Luis Felipe Cabrera, Michael J. Karels, and David M``The Impact Buffer Management [equation] tware Perfin Berkeley UNIX 4.2BSD: A Case Study,'' Pr[equation] the Summer Usenix C[equation] erence, PJune 1985, pp. 507-517.
[GADS85]
GADS (Gateway Alg``T[equation] Netw[equation] April 1985.
[J
J``C[equation] [equation] UNIX CApril 1980.
[Kashtan80]
Kashtan, David L., ``UNIX and VMS, S[equation] SRI Internati
[Lankf
Jeffrey Lankf``UNIX System V and 4BSD PerfPr[equation] the Salt Lake City Usenix C[equation] erence, pp 228-236, June 1984.
[Leffler84]
Sam Leffler, Mike Karels, and M. Kirk McKusick, ``Measuring and Impr[equation] [equation] 4.2BSD,'' Pr[equation] the Salt Lake City Usenix C[equation] erence, pp 237-252, June 1984.
[McKusick85]
M. Kirk McKusick, Mike Karels, and Samual Leffler, ``PerfPr[equation] the P[equation] erence, pp 519-531, June 1985.
[M
Paul MNetw[equation] RFC-883, N
[M
Jeffrey MNetw[equation] Oct
[M
M``UNIX PerfPresented at the B[equation] erence, January 1980. C[equation] the paper are available frC
[Nagle84]
JNetw[equation] January 1984.
[Ritchie74]
Ritchie, D. M. and Th``The UNIX Time-Sharing System'', CACM 17, 7. July 1974. pp 365-375
[Shann
Shannprivate cJuly 1983
[Walsh84]
R``CPr[equation] the Salt Lake City Usenix C[equation] erence, pp 52-61, June 1984.































Appendix A - Benchmark s

The prfrwith a getpagesize r[equation] the rand[equation] P functi[equation] r[equation] Ivf[equation] P and vexecs pr[equation] r[equation] If[equation] P and execs prrespectively, by substituting calls t[equation] If[equation] P with calls tvf[equation] P.

syscall

/*
 * System call  */
                                                             mainmain(argc, argv)
char *argv[];
{
register int ncalls;

if (argc < 2) {
printf("usage: %s #syscalls\n", argv[0]);
exit(1);
}
ncalls = atwhile (ncalls-- > 0)
(v[equation]
P) getpid();
}

csw

/*
 * C *
 * F[equation]
I*nsigs
 * times by f * T[equation]
 * switch, the sign * with nsigs.  Overhead is then estimated by
 *t1 = time csw <n>
 *t2 = time sign *[equation]
I* t2;
 */
#include <signal.h>

intsigsub();
intintnsigs;

                                                             mainmain(argc, argv)
char *argv[];
{
int pid;

if (argc < 2) {
printf("usage: %s nsignals\n", argv[0]);
exit(1);
}
nsigs = atsignal(SIGALRM, sigsub);
pid = fif (pid != 0) {
kill(}
f[equation]
P (;;)
sigpause(0);
}

                                                           sigsubsigsub()
{

signal(SIGALRM, sigsub);
kill(if (--nsigs <= 0)
exit(0);
}

sign

/*
 * Signal with */
#include <signal.h>

intpid;
intnsigs;
intsigsub();

                                                             mainmain(argc, argv)
char *argv[];
{
register int i;

if (argc < 2) {
printf("usage: %s nsignals\n", argv[0]);
exit(1);
}
nsigs = atsignal(SIGALRM, sigsub);
pid = getpid();
f[equation]
P (i = 0; i < nsigs; i++)
kill(pid, SIGALRM);
}

                                                           sigsubsigsub()
{

signal(SIGALRM, sigsub);
}

pipeself

/*
 * IPC benchmark,
 * write t[equation]
 using pipes.
 */

                                                             mainmain(argc, argv)
char *argv[];
{
char buf[512];
int fd[2], msgsize;
register int i, iter;

if (argc < 3) {
printf("usage: %s iteratiexit(1);
}
argc--, argv++;
iter = at[equation]
I*argv);
argc--, argv++;
msgsize = at[equation]
I*argv);
if (msgsize > size (buf) || msgsize <= 0) {
printf("%s: Bad message size.\n", *argv);
exit(2);
}
if (pipe(fd) < 0) {
perrexit(3);
}
f[equation]
P (i = 0; i < iter; i++) {
write(fd[1], buf, msgsize);
read(fd[0], buf, msgsize);
}
}

pipediscard

/*
 * IPC benchmarkl,
 * write and discard using pipes.
 */

                                                             mainmain(argc, argv)
char *argv[];
{
char buf[512];
int fd[2], msgsize;
register int i, iter;

if (argc < 3) {
printf("usage: %s iteratiexit(1);
}
argc--, argv++;
iter = at[equation]
I*argv);
argc--, argv++;
msgsize = at[equation]
I*argv);
if (msgsize > size (buf) || msgsize <= 0) {
printf("%s: Bad message size.\n", *argv);
exit(2);
}
if (pipe(fd) < 0) {
perrexit(3);
}
if (ff[equation]
P (i = 0; i < iter; i++)
read(fd[0], buf, msgsize);
else
f[equation]
P (i = 0; i < iter; i++)
write(fd[1], buf, msgsize);
}

pipeback

/*
 * IPC benchmark,
 * read and reply using pipes.
 *
 * Pr[equation]
 * [equation]
ashi */

                                                             mainmain(argc, argv)
char *argv[];
{
char buf[512];
int fd[2], fd2[2], msgsize;
register int i, iter;

if (argc < 3) {
printf("usage: %s iteratiexit(1);
}
argc--, argv++;
iter = at[equation]
I*argv);
argc--, argv++;
msgsize = at[equation]
I*argv);
if (msgsize > size (buf) || msgsize <= 0) {
printf("%s: Bad message size.\n", *argv);
exit(2);
}
if (pipe(fd) < 0) {
perrexit(3);
}
if (pipe(fd2) < 0) {
perrexit(3);
}
if (ff[equation]
P (i = 0; i < iter; i++) {
read(fd[0], buf, msgsize);
write(fd2[1], buf, msgsize);
}
else
f[equation]
P (i = 0; i < iter; i++) {
write(fd[1], buf, msgsize);
read(fd2[0], buf, msgsize);
}
}

f

/*
 * Benchmark pr[equation]
 *  * f * The time t * in calculating exec  */

                                                             mainmain(argc, argv)
char *argv[];
{
register int nfchar *cp;
int pid, child, status, brksize;

if (argc < 2) {
printf("usage: %s number--fexit(1);
}
nfif (nf[equation]
3{
printf("%s: bad number  fexit(2);
}
brksize = atif (brksize < 0) {
printf("%s: bad size texit(3);
}
cp = (char *)sbrk(brksize);
if ((int)cp == -1) {
perrexit(4);
}
f[equation]
P (i = 0; i < brksize; i += 1024)
cp[i] = i;
while (nf[equation]
3{
child = fif (child == -1) {
perr[equation]
exit(-1);
}
if (child == 0)
-exit(-1);
while ((pid = wait(&status)) != -1 && pid != child)
;
}
exit(0);
}

execs

/*
 * Benchmark pr *  * f * The time t[equation]
 * then be deducted fr * estimate the [equation]
 */

                                                             mainmain(argc, argv)
char *argv[];
{
register int nexecs, i;
char *cp, *sbrk();
int pid, child, status, brksize;

if (argc < 3) {
printf("usage: %s number--execs sbrk-size j    argv[0]);
exit(1);
}
nexecs = atif (nexecs < 0) {
printf("%s: bad number  execs\n", argv[1]);
exit(2);
}
brksize = atif (brksize < 0) {
printf("%s: bad size texit(3);
}
cp = sbrk(brksize);
if ((int)cp == -1) {
perrexit(4);
}
f[equation]
P (i = 0; i < brksize; i += 1024)
cp[i] = i;
while (nexecs-- > 0) {
child = fif (child == -1) {
perr[equation]
exit(-1);
}
if (child == 0) {
execv(argv[3], argv);
perr-exit(-1);
}
while ((pid = wait(&status)) != -1 && pid != child)
;
}
exit(0);
}

nullj

/*
 * Benchmark "null j */

                                                             mainmain(argc, argv)
char *argv[];
{

exit(0);
}

bigj

/*
 * Benchmark "null big j */
/* 250 here is intended t[equation]
I*/
charspace[1024 * 250] = "f
                                                             mainmain(argc, argv)
char *argv[];
{

exit(0);
}

seqpage

/*
 * Sequential page access benchmark.
 */
#include <sys/vadvise.h>

char*vall
                                                             mainmain(argc, argv)
char *argv[];
{
register i, niter;
register char *pf, *lastpage;
int npages = 4096, pagesize, vflag = 0;
char *pages, *name;

name = argv[0];
argc--, argv++;
again:
if (argc < 1) {
usage:
printf("usage: %s [ -v ] [ -p #pages ] niter\n", name);
exit(1);
}
if (strcmp(*argv, "-p") == 0) {
argc--, argv++;
if (argc < 1)
g[equation]
P usage;
npages = at[equation]
I*argv);
if (npages <= 0) {
printf("%s: Bad page c[equation]
I*argv);
exit(2);
}
argc--, argv++;
g[equation]
P again;
}
if (strcmp(*argv, "-v") == 0) {
argc--, argv++;
vflag++;
g[equation]
P again;
}
niter = at[equation]
I*argv);
pagesize = getpagesize();
pages = vall[equation]
I* pagesize);
if (pages == (char *)0) {
printf("Can't all[equation]
 megabytes).\n",
    npages, (npages * pagesize) / (1024. * 1024.));
exit(3);
}
lastpage = pages + (npages * pagesize);
if (vflag)
vadvise(VA-SEQL);
f[equation]
P (i = 0; i < niter; i++)
f[equation]
P (pf = pages; pf < lastpage; pf += pagesize)
*pf = 1;
}

randpage

/*
 * Rand */
#include <sys/vadvise.h>

char*vallintrand();

                                                             mainmain(argc, argv)
char *argv[];
{
register int npages = 4096, pagesize, pn, i, niter;
int vflag = 0, debug = 0;
char *pages, *name;

name = argv[0];
argc--, argv++;
again:
if (argc < 1) {
usage:
printf("usage: %s [ -d ] [ -v ] [ -p #pages ] niter\n", name);
exit(1);
}
if (strcmp(*argv, "-p") == 0) {
argc--, argv++;
if (argc < 1)
g[equation]
P usage;
npages = at[equation]
I*argv);
if (npages <= 0) {
printf("%s: Bad page c[equation]
I*argv);
exit(2);
}
argc--, argv++;
g[equation]
P again;
}
if (strcmp(*argv, "-v") == 0) {
argc--, argv++;
vflag++;
g[equation]
P again;
}
if (strcmp(*argv, "-d") == 0) {
argc--, argv++;
debug++;
g[equation]
P again;
}
niter = at[equation]
I*argv);
pagesize = getpagesize();
pages = vall[equation]
I* pagesize);
if (pages == (char *)0) {
printf("Can't all[equation]
 megabytes).\n",
    npages, (npages * pagesize) / (1024. * 1024.));
exit(3);
}
if (vflag)
vadvise(VA-ANOM);
f[equation]
P (i = 0; i < niter; i++) {
pn = randif (debug)
printf("tpages[pagesize * pn] = 1;
}
}

gausspage

/*
 * Rand * a gaussian distributi *
 * All[equation]
ill  * space and fault the pages in a rand *  */

fl[equation]
Psqrt(), lchar*vallintrand();

                                                             mainmain(argc, argv)
char *argv[];
{
register int pn, i, niter, delta;
register char *pages;
fl[equation]
P sd = 10.0;
int npages = 4096, pagesize, debug = 0;
char *name;

name = argv[0];
argc--, argv++;
again:
if (argc < 1) {
usage:
printf(
"usage: %s [ -d ] [ -p #pages ] [ -s standard-deviatiexit(1);
}
if (strcmp(*argv, "-s") == 0) {
argc--, argv++;
if (argc < 1)
g[equation]
P usage;
sscanf(*argv, "%f", &sd);
if (sd <= 0) {
printf("%s: Bad standard deviati[equation]
I*argv);
exit(2);
}
argc--, argv++;
g[equation]
P again;
}
if (strcmp(*argv, "-p") == 0) {
argc--, argv++;
if (argc < 1)
g[equation]
P usage;
npages = at[equation]
I*argv);
if (npages <= 0) {
printf("%s: Bad page c[equation]
I*argv);
exit(2);
}
argc--, argv++;
g[equation]
P again;
}
if (strcmp(*argv, "-d") == 0) {
argc--, argv++;
debug++;
g[equation]
P again;
}
niter = at[equation]
I*argv);
pagesize = getpagesize();
pages = vall[equation]
I*pagesize);
if (pages == (char *)0) {
printf("Can't all[equation]
 megabytes).\n",
    npages, (npages*pagesize) / (1024. * 1024.));
exit(3);
}
pn = 0;
f[equation]
P (i = 0; i < niter; i++) {
delta = gauss(sd, 0.0);
while (pn + delta < 0 || pn + delta > npages)
delta = gauss(sd, 0.0);
pn += delta;
if (debug)
printf("telse
pages[pn * pagesize] = 1;
}
}

fl[equation]
P
                                                            gaussgauss(sd, mean)
fl[equation]
P sd, mean;
{
register fl[equation]
P qa, qb;

qa = sqrt(l[equation]
I* -2.0);
qb = 3.14159 * rnd();
return (qa * c[equation]
I* sd + mean);
}

fl[equation]
P
                                                              rndrnd()
{
static int seed = 1;
static int biggest = 0x7fffffff;

return ((fl[equation]
P)rand(seed) / (fl[equation]
P)biggest);
}





























run (shell script)

#! /bin/csh -fx
# Script t#
date
make clean; time make
time syscall 100000
time seqpage -p 7500 10
time seqpage -v -p 7500 10
time randpage -p 7500 30000
time randpage -v -p 7500 30000
time gausspage -p 7500 -s 1 30000
time gausspage -p 7500 -s 10 30000
time gausspage -p 7500 -s 30 30000
time gausspage -p 7500 -s 40 30000
time gausspage -p 7500 -s 50 30000
time gausspage -p 7500 -s 60 30000
time gausspage -p 7500 -s 80 30000
time gausspage -p 7500 -s 10000 30000
time csw 10000
time signtime pipeself 10000 512
time pipeself 10000 4
time udgself 10000 512
time udgself 10000 4
time pipediscard 10000 512
time pipediscard 10000 4
time udgdiscard 10000 512
time udgdiscard 10000 4
time pipeback 10000 512
time pipeback 10000 4
time udgback 10000 512
time udgback 10000 4
size ftime ftime ftime fsize vftime vftime vftime vfcsize nulljtime execs 1000 0 nulljtime execs 1000 1024 nulljtime execs 1000 102400 nulljtime vexecs 1000 0 nulljtime vexecs 1000 1024 nulljtime vexecs 1000 102400 nulljsize bigjtime execs 1000 0 bigjtime execs 1000 1024 bigjtime execs 1000 102400 bigjtime vexecs 1000 0 bigjtime vexecs 1000 1024 bigjtime vexecs 1000 102400 bigj# fill envirsetenv a 012345678901234567890123456789012345678901234567890123456780123456789
setenv b 012345678901234567890123456789012345678901234567890123456780123456789
setenv c 012345678901234567890123456789012345678901234567890123456780123456789
setenv d 012345678901234567890123456789012345678901234567890123456780123456789
setenv e 012345678901234567890123456789012345678901234567890123456780123456789
setenv f 012345678901234567890123456789012345678901234567890123456780123456789
setenv g 012345678901234567890123456789012345678901234567890123456780123456789
setenv h 012345678901234567890123456789012345678901234567890123456780123456789
setenv i 012345678901234567890123456789012345678901234567890123456780123456789
setenv j 012345678901234567890123456789012345678901234567890123456780123456789
setenv k 012345678901234567890123456789012345678901234567890123456780123456789
setenv l 012345678901234567890123456789012345678901234567890123456780123456789
setenv m 012345678901234567890123456789012345678901234567890123456780123456789
setenv n 012345678901234567890123456789012345678901234567890123456780123456789
setenv ctime execs 1000 0 nulljtime execs 1000 1024 nulljtime execs 1000 102400 nulljtime execs 1000 0 bigjtime execs 1000 1024 bigjtime execs 1000 102400 bigj