#include #include #include #include #include #include #include #include #include #include #define GB (1024 * 1024 * 1024) int do_posix_fallocate(char *name, off_t len) { int r, fd; struct timeval tv1, tv2; unlink(name); fd = open(name, O_RDWR|O_CREAT, S_IRUSR|S_IWUSR); if (fd < 0) { perror("open"); return -1; } printf("posix-fallocate run time:\n"); gettimeofday(&tv1, NULL); r = posix_fallocate(fd, 0, len); close(fd); gettimeofday(&tv2, NULL); if (r < 0) return r; printf("\tseconds:microseconds: %llu:%llu\n", tv1.tv_sec, tv1.tv_usec); printf("\tseconds:microseconds: %llu:%llu\n", tv2.tv_sec, tv2.tv_usec); printf("\t(approx %us)\n", tv2.tv_sec - tv1.tv_sec); return 0; } #if 1 int do_fallocate(char *name, off_t len) { int r, fd; struct timeval tv1, tv2; unlink(name); fd = open(name, O_RDWR|O_CREAT, S_IRUSR|S_IWUSR); if (fd < 0) { perror("open"); return -1; } printf("fallocate run time:\n"); gettimeofday(&tv1, NULL); r = syscall(__NR_fallocate, fd, 0, len); close(fd); gettimeofday(&tv2, NULL); if (r < 0) { perror("fallocate"); return r; } printf("\tseconds:microseconds: %llu:%llu\n", tv1.tv_sec, tv1.tv_usec); printf("\tseconds:microseconds: %llu:%llu\n", tv2.tv_sec, tv2.tv_usec); printf("\t(approx %us)\n", tv2.tv_sec - tv1.tv_sec); return 0; } #endif int do_mmap(char *name, off_t len) { int fd; struct timeval tv1, tv2; char *addr; unlink(name); fd = open(name, O_RDWR|O_CREAT, S_IRUSR|S_IWUSR); if (fd < 0) { perror("open"); return -1; } /* memset has to have the mmap'ed file backed by something on * disk -- bus error otherwise */ lseek(fd, len - 1, SEEK_SET); write(fd, "0", 1); addr = mmap(NULL, len, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); if (addr == MAP_FAILED) { perror("mmap"); return -2; } printf("mmap run time:\n"); gettimeofday(&tv1, NULL); memset(addr, 0, len); munmap(addr, len); close(fd); gettimeofday(&tv2, NULL); printf("\tseconds:microseconds: %llu:%llu\n", tv1.tv_sec, tv1.tv_usec); printf("\tseconds:microseconds: %llu:%llu\n", tv2.tv_sec, tv2.tv_usec); printf("\t(approx %us)\n", tv2.tv_sec - tv1.tv_sec); return 0; } int do_write_chunks(char *name, off_t len, size_t chunk_size) { int fd; struct timeval tv1, tv2; unsigned long long remain = len; char *zeros; zeros = calloc(1, len); unlink(name); fd = open(name, O_RDWR|O_CREAT, S_IRUSR|S_IWUSR); if (fd < 0) { perror("open"); return -1; } printf("%llu-sized chunk run time:\n", chunk_size); gettimeofday(&tv1, NULL); while (remain) { int bytes = chunk_size; if (bytes > remain) bytes = remain; if ((bytes = write(fd, zeros, bytes)) < 0) { perror("write"); return -2; } remain -= bytes; } close(fd); gettimeofday(&tv2, NULL); printf("\tseconds:microseconds: %llu:%llu\n", tv1.tv_sec, tv1.tv_usec); printf("\tseconds:microseconds: %llu:%llu\n", tv2.tv_sec, tv2.tv_usec); printf("\t(approx %us)\n", tv2.tv_sec - tv1.tv_sec); free(zeros); return 0; } int main(int argc, char **argv) { char *basename; char *filename; if (argc < 2) { printf("usage: %s base-dir\n", argv[0]); return -1; } basename = argv[1]; sprintf(filename, "%s/file-pf", basename); do_posix_fallocate(filename, 1 * GB); #if 0 sprintf(filename, "%s/file-pf", basename); do_fallocate(filename, 1 * GB); #endif sprintf(filename, "%s/file-mmap", basename); do_mmap(filename, 1 * GB); sprintf(filename, "%s/file-chunk4", basename); do_write_chunks(filename, 1 * GB, 4 * 1024); sprintf(filename, "%s/file-chunk8", basename); do_write_chunks(filename, 1 * GB, 8 * 1024); return 0; }