shithub: sysbench

ref: a1c8da91f18c8bd3cdc7ce36c70538969e0c5602
dir: /rdwr.c/

View raw version
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <pthread.h>
#include <sys/syscall.h>
#include <string.h>
#include <errno.h>

#include "bench.h"

#define IOUNIT 32768

struct pipe_data {
	int fd;
	int n;
	int count;
	char *buf;
};

void
benchsysr1(B *b)
{
	int i;

	for(i = 0; i < b->N; i++)
		syscall(SYS_getpid);
}

void
benchread(B *b, char *path, int n)
{
	int i, fd;
	char buf[128*IOUNIT];

	if((fd = open(path, O_RDONLY)) == -1) {
		fprintf(stderr, "open %s: %s\n", path, strerror(errno));
		exit(1);
	}
	for(i = 0; i < b->N; i++)
		pread(fd, buf, n, 0);
	close(fd);
}

void
benchwrite(B *b, char *path, int n)
{
	int i, fd;
	char buf[128*IOUNIT];

	if((fd = open(path, O_WRONLY)) == -1) {
		fprintf(stderr, "open %s: %s\n", path, strerror(errno));
		exit(1);
	}
	for(i = 0; i < b->N; i++)
		pwrite(fd, buf, n, 0);
	close(fd);
}

static void *
pipe_writer(void *arg)
{
	struct pipe_data *pd = arg;
	int i;
	
	for(i = 0; i < pd->count; i++)
		if(write(pd->fd, pd->buf, pd->n) == -1) {
			fprintf(stderr, "write: %s\n", strerror(errno));
			exit(1);
		}
	return NULL;
}

void
benchpipe(B *b, int n)
{
	char buf[128*IOUNIT];
	int i, pfd[2];
	pthread_t writer_thread;
	struct pipe_data pd;

	if(pipe(pfd) == -1) {
		fprintf(stderr, "pipe: %s\n", strerror(errno));
		exit(1);
	}

	pd.fd = pfd[1];
	pd.n = n;
	pd.count = b->N;
	pd.buf = buf;

	if(pthread_create(&writer_thread, NULL, pipe_writer, &pd) != 0) {
		fprintf(stderr, "pthread_create failed\n");
		exit(1);
	}

	for(i = 0; i < b->N; i++)
		if(read(pfd[0], buf, n) == -1) {
			fprintf(stderr, "read: %s\n", strerror(errno));
			exit(1);
		}

	pthread_join(writer_thread, NULL);
	close(pfd[0]);
	close(pfd[1]);
}	

void	benchreadzero(B *b)	{ benchread(b, "/dev/zero", 4); }
void	benchwritenull(B *b)	{ benchwrite(b, "/dev/null", 4); }
void	benchreaddir(B *b)	{ benchread(b, "/tmp", 4); }  // Reading directory fails with EISDIR
void	benchwritefull(B *b)	{ benchwrite(b, "/dev/full", 4); }
void	benchpipe1(B *b)	{ benchpipe(b, 1); }
void	benchpipe16(B *b)	{ benchpipe(b, 16); }
void	benchpipe256(B *b)	{ benchpipe(b, 256); }
void	benchpipe4096(B *b)	{ benchpipe(b, 4096); }
void	benchpipe4097(B *b)	{ benchpipe(b, 4097); }
void	benchpipe32768(B *b)	{ benchpipe(b, 32768); }

int
main(int argc, char **argv)
{
	benchinit(argc, argv);

	printf("== nop io ==\n");
	BM(benchsysr1);
	BM(benchreadzero);
	BM(benchwritenull);
	BM(benchreaddir);
	BM(benchwritefull);

	printf("== pipe io ==\n");
	BM(benchpipe1);
	BM(benchpipe16);
	BM(benchpipe256);
	BM(benchpipe4096);
	BM(benchpipe4097);
	BM(benchpipe32768);
	return 0;
}