All pastes #2106387 Raw Edit

Mine

public c v1 · immutable
#2106387 ·published 2012-01-26 12:00 UTC
rendered paste body
#define _GNU_SOURCE#include <ctype.h>#include <fcntl.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <sys/mman.h>#include <unistd.h>#define LARGE_CHUNK (32 * 1024)#define SMALL_CHUNK (1024)typedef unsigned long ulong;static char file_name[] = "test-mmio.bin";static ulong file_size = 32 * 1024 * 1024;static ulong page_size;static voiderror(const char *s){	perror(s);	exit(EXIT_FAILURE);}static intopen_file(int flags){	int fd = open(file_name, flags, 0666);	if (fd < 0) {		error(NULL);	}	return fd;}static void *mmap_file(int fd){	void *mm = mmap(0, file_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);	if (mm == MAP_FAILED) {		error(NULL);	}	return mm;}static voidsync_file(int fd){#ifdef F_FULLFSYNC	fcntl(fd, F_FULLFSYNC, 0);#else	fdatasync(fd);#endif}static voidsync_range(int fd, void *ptr, ulong off, ulong len){#ifdef __linux__	sync_file_range(fd, off, len, SYNC_FILE_RANGE_WAIT_BEFORE | SYNC_FILE_RANGE_WRITE | SYNC_FILE_RANGE_WAIT_AFTER);#else	msync(((char *) ptr) + off, len, MS_SYNC);#endif}voiddo_write(int fd, int len){	void *buf = alloca(len);	memset(buf, 0, len);	if (write(fd, buf, len) != len) {		error(NULL);	}}voiddo_mcopy(void *ptr, int len){	void *buf = alloca(len);	memset(buf, 0, len);	memcpy(ptr, buf, len);}voidtest(int fd, void *mm, int chunk, int sync, int advise){	ulong size;	for (size = 0; size < file_size; size += chunk) {		if (!mm) {			do_write(fd, chunk);		} else {			do_mcopy(((char*) mm) + size, chunk);		}		if (sync == 1) {			sync_file(fd);		} else if (mm && sync == 2) {			sync_range(fd, mm, size, chunk);		}		if (advise) {#ifdef __linux__			posix_fadvise(fd, 0, (size + chunk) & ~(page_size - 1), POSIX_FADV_DONTNEED);#endif		}		if (size % (1024 * 1024) == 0) {			printf(".");			fflush(stdout);		}	}	printf("\n");}voidusage(){}ulongparse_size(const char *s){	ulong value;	char *suffix;	value = strtoul(s, &suffix, 10);	if (*suffix) {		int c = toupper(*suffix);		if (c == 'K') {			value <<= 10;		} else if (c == 'M') {			value <<= 20;		} else {			usage();		}	}	return value;}intmain(int ac, char *av[]){	int c;	int prepare, use_mmap, use_write, sync, range, advise;	ulong chunk;	int fd;	void *mm;	prepare = use_mmap = use_write = sync = range = advise = 0;	chunk = 0;	while ((c = getopt(ac, av, "pmwfras:c:")) != -1) {		switch (c) {		case 'p':			prepare = 1;			break;		case 'm':			use_mmap = 1;			break;		case 'w':			use_write = 1;			break;		case 'f':			sync = 1;			break;		case 'r':			range = 1;			break;		case 'a':			advise = 1;			break;		case 's':			file_size = parse_size(optarg);			break;		case 'c':			chunk = parse_size(optarg);			break;		default:			usage();			exit(EXIT_FAILURE);		}	}	ac -= optind;	av += optind;	if ((prepare + use_mmap + use_write) != 1) {		usage();		exit(EXIT_FAILURE);	}	if ((sync + range) > 1) {		usage();		exit(EXIT_FAILURE);	}	if (chunk == 0) {		chunk = prepare ? LARGE_CHUNK : SMALL_CHUNK;	}	if (range == 1) {		sync = 2;	}	printf("file size: %ld\n", file_size);	printf("chunk size: %ld\n", chunk);	switch (sync) {	case 0:		printf("sync: no\n");		break;	case 1:		printf("sync: file\n");		break;	case 2:		printf("sync: range\n");		break;	}	page_size = getpagesize();	mm = NULL;	if (prepare) {		printf("prepare the file\n");		fd = open_file(O_CREAT | O_RDWR | O_TRUNC);	} else if (use_write) {		printf("write to the file\n");		fd = open_file(O_RDWR);	} else {		printf("copy to the file mmap\n");		fd = open_file(O_RDWR);		mm = mmap_file(fd);	}	test(fd, mm, chunk, sync, advise);	if (mm) {		munmap(mm, file_size);	}	fsync(fd);	close(fd);	return 0;}