#define _GNU_SOURCE #include #include #include #include #include #include #include #include #include #define BUFSIZE (8*1024*1024ul) static unsigned int maxbuf = ~0U; static int do_fadvise; static void parse_opt(int argc, char **argv) { int ch; while (1) { ch = getopt(argc, argv, "fb:"); if (ch == -1) break; switch (ch) { case 'f': do_fadvise = 1; fprintf(stderr, "using fadvise()\n"); break; case 'b': if (atoi(optarg) > 1) maxbuf = atoi(optarg); else fprintf(stderr, "invalid bufcount '%s'\n", optarg); break; default: fprintf(stderr, "invalid option 0%o (%c)\n", ch, isprint(ch) ? ch : '-'); break; } } } int main(int argc, char **argv) { static char buffer[BUFSIZE]; struct timeval start, now; unsigned int index; int fd; parse_opt(argc, argv); mlockall(MCL_CURRENT | MCL_FUTURE); fd = open("/dev/urandom", O_RDONLY); if (read(fd, buffer, BUFSIZE) != BUFSIZE) { perror("/dev/urandom"); exit(1); } close(fd); fd = open(argv[optind], O_RDWR | O_CREAT, 0666); if (fd < 0) { perror(argv[optind]); exit(1); } if (maxbuf != ~0U) fprintf(stderr, "writing %u buffers of size %lum\n", maxbuf, BUFSIZE / (1024 * 1024ul)); gettimeofday(&start, NULL); for (index = 0; index < maxbuf; index++) { double s; unsigned long MBps; unsigned long MB; if (write(fd, buffer, BUFSIZE) != BUFSIZE) break; sync_file_range(fd, index*BUFSIZE, BUFSIZE, SYNC_FILE_RANGE_WRITE); if (index) sync_file_range(fd, (index-1)*BUFSIZE, BUFSIZE, SYNC_FILE_RANGE_WAIT_BEFORE|SYNC_FILE_RANGE_WRITE|SYNC_FILE_RANGE_WAIT_AFTER); if (do_fadvise) posix_fadvise(fd, (index-1)*BUFSIZE, BUFSIZE, POSIX_FADV_DONTNEED); gettimeofday(&now, NULL); s = (now.tv_sec - start.tv_sec) + ((double) now.tv_usec - start.tv_usec)/ 1000000; MB = index * (BUFSIZE >> 20); MBps = MB; if (s > 1) MBps = MBps / s; printf("%8lu.%03lu GB written in %5.2f (%lu MB/s) \r", MB >> 10, (MB & 1023) * 1000 >> 10, s, MBps); fflush(stdout); } close(fd); printf("\n"); return 0; }