//#define	WRITELOOP	1
#define	WRITEMMAP	1

#include <sys/types.h>
#include <sys/time.h>
#include <sys/mman.h>

#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>

#define	NLOG	5
#define	LOGSIZE	(16*1024*1024)
#define	CHUNK	8192


void die(char *s)
{
	perror(s);
	exit(1);
}

int main(int argc, char **argv)
{
int fd;
char nbuf[40];
int i;
struct timeval ot, nt;
#ifdef	WRITELOOP
char buf[CHUNK];
#endif
#ifdef	WRITEMMAP
char *map;
#endif

#ifdef	WRITELOOP
	memset(buf, 0, CHUNK);
#endif

#ifdef	WRITEMMAP
	{
		int zfd;
		if((zfd = open("/dev/zero", O_RDONLY)) < 0)
			die("can't open /dev/zero");
		if((map = mmap(NULL, LOGSIZE, PROT_READ, MAP_SHARED, zfd, 0))
			== MAP_FAILED)
			die("mmap /dev/zero");
		close(zfd);
	}
#endif

	if(argc != 2)
		die("usage: writetest directory");

	for(i=0; i<NLOG; i++) {
		sprintf(nbuf, "%s/%d", argv[1], i);
		gettimeofday(&ot, NULL);
		if((fd = open(nbuf, O_CREAT|O_RDWR, 0600)) < 0)
			die("create failed");
#ifdef	WRITELOOP
		{
		int o,w;

			for(o=0; o<LOGSIZE; o+=w)
				if((w = write(fd, buf, CHUNK)) < 0)
					die("write failed");
		}
#endif
#ifdef	WRITEMMAP
		if(write(fd, map, LOGSIZE) != LOGSIZE)
			die("write mmapped area");
#endif
		//fdatasync(fd);
		fsync(fd);
		close(fd);
		gettimeofday(&nt, NULL);

		if(nt.tv_usec < ot.tv_usec) {
			nt.tv_sec--;
			nt.tv_usec += 1000000;
		}
		nt.tv_sec -= ot.tv_sec;
		nt.tv_usec -= ot.tv_usec;
		fprintf(stderr, "%d: %d.%02d\n", i, nt.tv_sec, nt.tv_usec/10000);
	}

	return 0;
}
