ref: 16a2cc57f9cd49f84db08e9c46478d8d0acfdf45
dir: /fsio.c/
#include <u.h>
#include <libc.h>
#include "bench.h"
char *benchdir;
char randbuf[128*IOUNIT];
#define Nfiles 8
#define Filesz 128*MiB
void
setup(void)
{
char path[512], buf[IOUNIT];
int i, j, n, nrd;
int rfd, wfd;
if((rfd = open("/dev/random", OREAD)) == -1)
sysfatal("open: %r");
readn(rfd, randbuf, sizeof(randbuf));
for(i = 0; i < Nfiles; i++){
snprint(path, sizeof(path), "%s/rfile.%d", benchdir, i);
if((wfd = create(path, OWRITE, 0666)) == -1)
sysfatal("create %s: %r", path);
for(j = 0; j < Filesz; j += n){
nrd = Filesz - j;
if(nrd > sizeof(buf))
nrd = sizeof(buf);
if((n = readn(rfd, buf, nrd)) != nrd)
sysfatal("short read");
if(write(wfd, buf, n) != n)
sysfatal("short write");
}
close(wfd);
}
close(rfd);
}
void
cleanup(void)
{
char buf[512];
int i, n, fd;
Dir *d;
if((fd = open(benchdir, OREAD)) == -1)
sysfatal("open %s: %r", benchdir);
n = dirreadall(fd, &d);
for(i = 0; i < n; i++){
snprint(buf, sizeof(buf), "%s/%s", benchdir, d[i].name);
remove(buf);
}
close(fd);
}
void
dowrite(int nops, int i, int fsz, int wsz)
{
int fd, j, k, n;
char path[512];
snprint(path, sizeof(path), "%s/write.%d.%d", benchdir, i, getpid());
if((fd = create(path, OWRITE, 0666)) == -1)
sysfatal("create: %r");
for(j = 0; j < nops; j++)
for(k = 0; k < fsz; k += n)
if((n = write(fd, randbuf, wsz)) != wsz)
sysfatal("write: %r");
close(fd);
remove(path);
}
void
writefile(B *b, int npar, int fsz)
{
int i, wsz;
wsz = fsz < IOUNIT ? fsz : IOUNIT;
for(i = 0; i < npar; i++){
switch(rfork(RFPROC|RFMEM)){
case -1:
sysfatal("fork: %r");
case 0:
dowrite(b->N/npar, i, fsz, wsz);
exits(nil);
default:
/* nothing */
break;
}
}
for(i = 0; i < npar; i++)
free(wait());
}
void
doread(int nops, int i, int fsz, int rsz)
{
char path[512], buf[IOUNIT];
int fd, j, k, n;
snprint(path, sizeof(path), "%s/rfile.%d", benchdir, i);
if((fd = open(path, OREAD)) == -1)
sysfatal("open: %r");
for(j = 0; j < nops; j++){
seek(fd, 0, 0);
for(k = 0; k < fsz; k += n)
if((n = readn(fd, buf, rsz)) != rsz)
sysfatal("read %s [%d < %d]: %r", path, n, rsz);
}
close(fd);
}
void
readfile(B *b, int npar, int fsz)
{
int i, rsz;
rsz = fsz < IOUNIT ? fsz : IOUNIT;
for(i = 0; i < npar; i++){
switch(rfork(RFPROC|RFMEM)){
case -1:
sysfatal("fork: %r");
case 0:
doread(b->N/npar, i, fsz, rsz);
exits(nil);
default:
/* nothing */
break;
}
}
for(i = 0; i < npar; i++)
free(wait());
}
void
mixedfile(B *b, int nrd, int nwr, int fsz)
{
int i, sz;
sz = fsz < IOUNIT ? fsz : IOUNIT;
for(i = 0; i < nrd+nwr; i++){
switch(rfork(RFPROC|RFMEM)){
case -1:
sysfatal("fork: %r");
case 0:
if(i < nrd)
doread(b->N/nrd, i, fsz, sz);
else
dowrite(b->N/nwr, i, fsz, sz);
exits(nil);
default:
/* nothing */
break;
}
}
for(i = 0; i < nrd+nwr; i++)
free(wait());
}
void writefile_p1_16b(B *b){ writefile(b, 1, 16); }
void writefile_p2_16b(B *b){ writefile(b, 2, 16); }
void writefile_p4_16b(B *b){ writefile(b, 4, 16); }
void writefile_p8_16b(B *b){ writefile(b, 8, 16); }
void writefile_p1_16k(B *b){ writefile(b, 1, 16*KiB); }
void writefile_p2_16k(B *b){ writefile(b, 2, 16*KiB); }
void writefile_p4_16k(B *b){ writefile(b, 4, 16*KiB); }
void writefile_p8_16k(B *b){ writefile(b, 8, 16*KiB); }
void writefile_p1_16m(B *b){ writefile(b, 1, 16*MiB); }
void writefile_p2_16m(B *b){ writefile(b, 2, 16*MiB); }
void writefile_p4_16m(B *b){ writefile(b, 4, 16*MiB); }
void writefile_p8_16m(B *b){ writefile(b, 8, 16*MiB); }
void readfile_p1_16b(B *b){ readfile(b, 1, 16); }
void readfile_p2_16b(B *b){ readfile(b, 2, 16); }
void readfile_p4_16b(B *b){ readfile(b, 4, 16); }
void readfile_p8_16b(B *b){ readfile(b, 8, 16); }
void readfile_p1_16k(B *b){ readfile(b, 1, 16*KiB); }
void readfile_p2_16k(B *b){ readfile(b, 2, 16*KiB); }
void readfile_p4_16k(B *b){ readfile(b, 4, 16*KiB); }
void readfile_p8_16k(B *b){ readfile(b, 8, 16*KiB); }
void readfile_p1_16m(B *b){ readfile(b, 1, 16*MiB); }
void readfile_p2_16m(B *b){ readfile(b, 2, 16*MiB); }
void readfile_p4_16m(B *b){ readfile(b, 4, 16*MiB); }
void readfile_p8_16m(B *b){ readfile(b, 8, 16*MiB); }
void mixedfile_p2(B *b){ mixedfile(b, 1, 1, 16); }
void mixedfile_p4(B *b){ mixedfile(b, 2, 2, 16); }
void mixedfile_p8(B *b){ mixedfile(b, 4, 4, 16); }
void
main(int argc, char **argv)
{
benchinit(argc, argv);
benchdir = getenv("benchdir");
if(benchdir == nil){
fprint(2, "no benchdir: skipping\n");
exits(nil);
}
setup();
print("== file writes (16b) ==\n");
BM(writefile_p1_16b);
BM(writefile_p2_16b);
BM(writefile_p4_16b);
BM(writefile_p8_16b);
print("== file writes (16k) ==\n");
BM(writefile_p1_16k);
BM(writefile_p2_16k);
BM(writefile_p4_16k);
BM(writefile_p8_16k);
print("== file writes (16m) ==\n");
BM(writefile_p1_16m);
BM(writefile_p2_16m);
BM(writefile_p4_16m);
BM(writefile_p8_16m);
print("== file reads (16b) ==\n");
BM(readfile_p1_16b);
BM(readfile_p2_16b);
BM(readfile_p4_16b);
BM(readfile_p8_16b);
print("== file reads (16k) ==\n");
BM(readfile_p1_16k);
BM(readfile_p2_16k);
BM(readfile_p4_16k);
BM(readfile_p8_16k);
print("== file reads (16m) ==\n");
BM(readfile_p1_16m);
BM(readfile_p2_16m);
BM(readfile_p4_16m);
BM(readfile_p8_16m);
print("== mixed ops ==\n");
BM(mixedfile_p2);
BM(mixedfile_p4);
BM(mixedfile_p8);
cleanup();
exits(nil);
}