shithub: sysbench

ref: 16a2cc57f9cd49f84db08e9c46478d8d0acfdf45
dir: /fsio.c/

View raw version
#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);
}