static void test_non_sync(void) { int tmpfile, ops; /* * Test a simple write without fsync */ printf("\nNon-Sync'ed %dkB writes:\n", XLOG_BLCKSZ_K); printf(LABEL_FORMAT, "write"); fflush(stdout); gettimeofday(&start_t, NULL); for (ops = 0; ops < ops_per_test; ops++) { if ((tmpfile = open(filename, O_RDWR, 0)) == -1) die("could not open output file"); if (write(tmpfile, buf, XLOG_BLCKSZ) != XLOG_BLCKSZ) die("write failed"); close(tmpfile); } gettimeofday(&stop_t, NULL); print_elapse(start_t, stop_t); }
/* * Test open_sync with different size files */ static void test_open_sync(const char *msg, int writes_size) { #ifdef OPEN_SYNC_FLAG int tmpfile, ops, writes; #endif printf(LABEL_FORMAT, msg); fflush(stdout); #ifdef OPEN_SYNC_FLAG if ((tmpfile = open(filename, O_RDWR | OPEN_SYNC_FLAG | PG_O_DIRECT, 0)) == -1) printf(NA_FORMAT, "n/a*\n"); else { gettimeofday(&start_t, NULL); for (ops = 0; ops < ops_per_test; ops++) { for (writes = 0; writes < 16 / writes_size; writes++) if (write(tmpfile, buf, writes_size * 1024) != writes_size * 1024) die("write failed"); if (lseek(tmpfile, 0, SEEK_SET) == -1) die("seek failed"); } gettimeofday(&stop_t, NULL); close(tmpfile); print_elapse(start_t, stop_t); } #else printf(NA_FORMAT, "n/a\n"); #endif }
int main(int argc, char *argv[]) { struct timeval start_t; struct timeval elapse_t; int tmpfile, i, loops = 1000; char *full_buf = (char *) malloc(XLOG_SEG_SIZE), *buf; char *filename = FSYNC_FILENAME; if (argc > 2 && strcmp(argv[1], "-f") == 0) { filename = argv[2]; argv += 2; argc -= 2; } if (argc > 1) loops = atoi(argv[1]); for (i = 0; i < XLOG_SEG_SIZE; i++) full_buf[i] = 'a'; if ((tmpfile = open(filename, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR, 0)) == -1) die("Cannot open output file."); if (write(tmpfile, full_buf, XLOG_SEG_SIZE) != XLOG_SEG_SIZE) die("write failed"); /* fsync so later fsync's don't have to do it */ if (fsync(tmpfile) != 0) die("fsync failed"); close(tmpfile); buf = (char *) TYPEALIGN(ALIGNOF_XLOG_BUFFER, full_buf); printf("Simple write timing:\n"); /* write only */ gettimeofday(&start_t, NULL); for (i = 0; i < loops; i++) { if ((tmpfile = open(filename, O_RDWR, 0)) == -1) die("Cannot open output file."); if (write(tmpfile, buf, WRITE_SIZE / 2) != WRITE_SIZE / 2) die("write failed"); close(tmpfile); } gettimeofday(&elapse_t, NULL); printf("\twrite "); print_elapse(start_t, elapse_t); printf("\n"); printf("\nCompare fsync times on write() and non-write() descriptor:\n"); printf("(If the times are similar, fsync() can sync data written\n on a different descriptor.)\n"); /* write, fsync, close */ gettimeofday(&start_t, NULL); for (i = 0; i < loops; i++) { if ((tmpfile = open(filename, O_RDWR, 0)) == -1) die("Cannot open output file."); if (write(tmpfile, buf, WRITE_SIZE / 2) != WRITE_SIZE / 2) die("write failed"); if (fsync(tmpfile) != 0) die("fsync failed"); close(tmpfile); if ((tmpfile = open(filename, O_RDWR, 0)) == -1) die("Cannot open output file."); /* do nothing but the open/close the tests are consistent. */ close(tmpfile); } gettimeofday(&elapse_t, NULL); printf("\twrite, fsync, close "); print_elapse(start_t, elapse_t); printf("\n"); /* write, close, fsync */ gettimeofday(&start_t, NULL); for (i = 0; i < loops; i++) { if ((tmpfile = open(filename, O_RDWR, 0)) == -1) die("Cannot open output file."); if (write(tmpfile, buf, WRITE_SIZE / 2) != WRITE_SIZE / 2) die("write failed"); close(tmpfile); /* reopen file */ if ((tmpfile = open(filename, O_RDWR, 0)) == -1) die("Cannot open output file."); if (fsync(tmpfile) != 0) die("fsync failed"); close(tmpfile); } gettimeofday(&elapse_t, NULL); printf("\twrite, close, fsync "); print_elapse(start_t, elapse_t); printf("\n"); printf("\nCompare one o_sync write to two:\n"); #ifdef OPEN_SYNC_FLAG /* 16k o_sync write */ if ((tmpfile = open(filename, O_RDWR | OPEN_SYNC_FLAG, 0)) == -1) die("Cannot open output file."); gettimeofday(&start_t, NULL); for (i = 0; i < loops; i++) if (write(tmpfile, buf, WRITE_SIZE) != WRITE_SIZE) die("write failed"); gettimeofday(&elapse_t, NULL); close(tmpfile); printf("\tone 16k o_sync write "); print_elapse(start_t, elapse_t); printf("\n"); /* 2*8k o_sync writes */ if ((tmpfile = open(filename, O_RDWR | OPEN_SYNC_FLAG, 0)) == -1) die("Cannot open output file."); gettimeofday(&start_t, NULL); for (i = 0; i < loops; i++) { if (write(tmpfile, buf, WRITE_SIZE / 2) != WRITE_SIZE / 2) die("write failed"); if (write(tmpfile, buf, WRITE_SIZE / 2) != WRITE_SIZE / 2) die("write failed"); } gettimeofday(&elapse_t, NULL); close(tmpfile); printf("\ttwo 8k o_sync writes "); print_elapse(start_t, elapse_t); printf("\n"); printf("\nCompare file sync methods with one 8k write:\n"); #else printf("\t(o_sync unavailable) "); #endif printf("\n"); #ifdef OPEN_DATASYNC_FLAG /* open_dsync, write */ if ((tmpfile = open(filename, O_RDWR | O_DSYNC, 0)) == -1) die("Cannot open output file."); gettimeofday(&start_t, NULL); for (i = 0; i < loops; i++) if (write(tmpfile, buf, WRITE_SIZE / 2) != WRITE_SIZE / 2) die("write failed"); gettimeofday(&elapse_t, NULL); close(tmpfile); printf("\topen o_dsync, write "); print_elapse(start_t, elapse_t); printf("\n"); #ifdef OPEN_SYNC_FLAG /* open_fsync, write */ if ((tmpfile = open(filename, O_RDWR | OPEN_SYNC_FLAG, 0)) == -1) die("Cannot open output file."); gettimeofday(&start_t, NULL); for (i = 0; i < loops; i++) if (write(tmpfile, buf, WRITE_SIZE / 2) != WRITE_SIZE / 2) die("write failed"); gettimeofday(&elapse_t, NULL); close(tmpfile); printf("\topen o_sync, write "); print_elapse(start_t, elapse_t); #endif #else printf("\t(o_dsync unavailable) "); #endif printf("\n"); #ifdef HAVE_FDATASYNC /* write, fdatasync */ if ((tmpfile = open(filename, O_RDWR, 0)) == -1) die("Cannot open output file."); gettimeofday(&start_t, NULL); for (i = 0; i < loops; i++) { if (write(tmpfile, buf, WRITE_SIZE / 2) != WRITE_SIZE / 2) die("write failed"); fdatasync(tmpfile); } gettimeofday(&elapse_t, NULL); close(tmpfile); printf("\twrite, fdatasync "); print_elapse(start_t, elapse_t); #else printf("\t(fdatasync unavailable)"); #endif printf("\n"); /* write, fsync, close */ if ((tmpfile = open(filename, O_RDWR, 0)) == -1) die("Cannot open output file."); gettimeofday(&start_t, NULL); for (i = 0; i < loops; i++) { if (write(tmpfile, buf, WRITE_SIZE / 2) != WRITE_SIZE / 2) die("write failed"); if (fsync(tmpfile) != 0) die("fsync failed"); } gettimeofday(&elapse_t, NULL); close(tmpfile); printf("\twrite, fsync, "); print_elapse(start_t, elapse_t); printf("\n"); printf("\nCompare file sync methods with 2 8k writes:\n"); #ifdef OPEN_DATASYNC_FLAG /* open_dsync, write */ if ((tmpfile = open(filename, O_RDWR | O_DSYNC, 0)) == -1) die("Cannot open output file."); gettimeofday(&start_t, NULL); for (i = 0; i < loops; i++) { if (write(tmpfile, buf, WRITE_SIZE / 2) != WRITE_SIZE / 2) die("write failed"); if (write(tmpfile, buf, WRITE_SIZE / 2) != WRITE_SIZE / 2) die("write failed"); } gettimeofday(&elapse_t, NULL); close(tmpfile); printf("\topen o_dsync, write "); print_elapse(start_t, elapse_t); #else printf("\t(o_dsync unavailable) "); #endif printf("\n"); #ifdef OPEN_SYNC_FLAG /* open_fsync, write */ if ((tmpfile = open(filename, O_RDWR | OPEN_SYNC_FLAG, 0)) == -1) die("Cannot open output file."); gettimeofday(&start_t, NULL); for (i = 0; i < loops; i++) { if (write(tmpfile, buf, WRITE_SIZE / 2) != WRITE_SIZE / 2) die("write failed"); if (write(tmpfile, buf, WRITE_SIZE / 2) != WRITE_SIZE / 2) die("write failed"); } gettimeofday(&elapse_t, NULL); close(tmpfile); printf("\topen o_sync, write "); print_elapse(start_t, elapse_t); printf("\n"); #endif #ifdef HAVE_FDATASYNC /* write, fdatasync */ if ((tmpfile = open(filename, O_RDWR, 0)) == -1) die("Cannot open output file."); gettimeofday(&start_t, NULL); for (i = 0; i < loops; i++) { if (write(tmpfile, buf, WRITE_SIZE / 2) != WRITE_SIZE / 2) die("write failed"); if (write(tmpfile, buf, WRITE_SIZE / 2) != WRITE_SIZE / 2) die("write failed"); fdatasync(tmpfile); } gettimeofday(&elapse_t, NULL); close(tmpfile); printf("\twrite, fdatasync "); print_elapse(start_t, elapse_t); #else printf("\t(fdatasync unavailable)"); #endif printf("\n"); /* write, fsync, close */ if ((tmpfile = open(filename, O_RDWR, 0)) == -1) die("Cannot open output file."); gettimeofday(&start_t, NULL); for (i = 0; i < loops; i++) { if (write(tmpfile, buf, WRITE_SIZE / 2) != WRITE_SIZE / 2) die("write failed"); if (write(tmpfile, buf, WRITE_SIZE / 2) != WRITE_SIZE / 2) die("write failed"); if (fsync(tmpfile) != 0) die("fsync failed"); } gettimeofday(&elapse_t, NULL); close(tmpfile); printf("\twrite, fsync, "); print_elapse(start_t, elapse_t); printf("\n"); free(full_buf); unlink(filename); return 0; }
int main(int argc, char *argv[]) { struct timeval start_t; struct timeval stop_t; int tmpfile, i; char *full_buf = (char *) malloc(XLOG_SEG_SIZE), *buf; char *filename = FSYNC_FILENAME; if (argc > 2 && strcmp(argv[1], "-f") == 0) { filename = argv[2]; argv += 2; argc -= 2; } if (argc > 1) loops = atoi(argv[1]); for (i = 0; i < XLOG_SEG_SIZE; i++) full_buf[i] = random(); if ((tmpfile = open(filename, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR, 0)) == -1) die("Cannot open output file."); if (write(tmpfile, full_buf, XLOG_SEG_SIZE) != XLOG_SEG_SIZE) die("write failed"); /* fsync now so later fsync's don't have to do it */ if (fsync(tmpfile) != 0) die("fsync failed"); close(tmpfile); buf = (char *) TYPEALIGN(ALIGNOF_XLOG_BUFFER, full_buf); printf("Loops = %d\n\n", loops); /* * Simple write */ printf("Simple write:\n"); printf(LABEL_FORMAT, "8k write"); fflush(stdout); gettimeofday(&start_t, NULL); for (i = 0; i < loops; i++) { if ((tmpfile = open(filename, O_RDWR, 0)) == -1) die("Cannot open output file."); if (write(tmpfile, buf, WRITE_SIZE) != WRITE_SIZE) die("write failed"); close(tmpfile); } gettimeofday(&stop_t, NULL); print_elapse(start_t, stop_t); /* * Compare file sync methods with one 8k write */ printf("\nCompare file sync methods using one write:\n"); #ifdef OPEN_DATASYNC_FLAG printf(LABEL_FORMAT, "open_datasync 8k write"); fflush(stdout); if ((tmpfile = open(filename, O_RDWR | O_DSYNC, 0)) == -1) die("Cannot open output file."); gettimeofday(&start_t, NULL); for (i = 0; i < loops; i++) { if (write(tmpfile, buf, WRITE_SIZE) != WRITE_SIZE) die("write failed"); if (lseek(tmpfile, 0, SEEK_SET) == -1) die("seek failed"); } gettimeofday(&stop_t, NULL); close(tmpfile); print_elapse(start_t, stop_t); #else printf("\t(unavailable: open_datasync)\n"); #endif #ifdef OPEN_SYNC_FLAG printf(LABEL_FORMAT, "open_sync 8k write"); fflush(stdout); if ((tmpfile = open(filename, O_RDWR | OPEN_SYNC_FLAG, 0)) == -1) die("Cannot open output file."); gettimeofday(&start_t, NULL); for (i = 0; i < loops; i++) { if (write(tmpfile, buf, WRITE_SIZE) != WRITE_SIZE) die("write failed"); if (lseek(tmpfile, 0, SEEK_SET) == -1) die("seek failed"); } gettimeofday(&stop_t, NULL); close(tmpfile); print_elapse(start_t, stop_t); #else printf("\t(unavailable: open_sync)\n"); #endif #ifdef HAVE_FDATASYNC printf(LABEL_FORMAT, "8k write, fdatasync"); fflush(stdout); if ((tmpfile = open(filename, O_RDWR, 0)) == -1) die("Cannot open output file."); gettimeofday(&start_t, NULL); for (i = 0; i < loops; i++) { if (write(tmpfile, buf, WRITE_SIZE) != WRITE_SIZE) die("write failed"); fdatasync(tmpfile); if (lseek(tmpfile, 0, SEEK_SET) == -1) die("seek failed"); } gettimeofday(&stop_t, NULL); close(tmpfile); print_elapse(start_t, stop_t); #else printf("\t(unavailable: fdatasync)\n"); #endif printf(LABEL_FORMAT, "8k write, fsync"); fflush(stdout); if ((tmpfile = open(filename, O_RDWR, 0)) == -1) die("Cannot open output file."); gettimeofday(&start_t, NULL); for (i = 0; i < loops; i++) { if (write(tmpfile, buf, WRITE_SIZE) != WRITE_SIZE) die("write failed"); if (fsync(tmpfile) != 0) die("fsync failed"); if (lseek(tmpfile, 0, SEEK_SET) == -1) die("seek failed"); } gettimeofday(&stop_t, NULL); close(tmpfile); print_elapse(start_t, stop_t); /* * Compare file sync methods with two 8k write */ printf("\nCompare file sync methods using two writes:\n"); #ifdef OPEN_DATASYNC_FLAG printf(LABEL_FORMAT, "2 open_datasync 8k writes"); fflush(stdout); if ((tmpfile = open(filename, O_RDWR | O_DSYNC, 0)) == -1) die("Cannot open output file."); gettimeofday(&start_t, NULL); for (i = 0; i < loops; i++) { if (write(tmpfile, buf, WRITE_SIZE) != WRITE_SIZE) die("write failed"); if (write(tmpfile, buf, WRITE_SIZE) != WRITE_SIZE) die("write failed"); if (lseek(tmpfile, 0, SEEK_SET) == -1) die("seek failed"); } gettimeofday(&stop_t, NULL); close(tmpfile); print_elapse(start_t, stop_t); #else printf("\t(unavailable: open_datasync)\n"); #endif #ifdef OPEN_SYNC_FLAG printf(LABEL_FORMAT, "2 open_sync 8k writes"); fflush(stdout); if ((tmpfile = open(filename, O_RDWR | OPEN_SYNC_FLAG, 0)) == -1) die("Cannot open output file."); gettimeofday(&start_t, NULL); for (i = 0; i < loops; i++) { if (write(tmpfile, buf, WRITE_SIZE) != WRITE_SIZE) die("write failed"); if (write(tmpfile, buf, WRITE_SIZE) != WRITE_SIZE) die("write failed"); if (lseek(tmpfile, 0, SEEK_SET) == -1) die("seek failed"); } gettimeofday(&stop_t, NULL); close(tmpfile); print_elapse(start_t, stop_t); #endif #ifdef HAVE_FDATASYNC printf(LABEL_FORMAT, "8k write, 8k write, fdatasync"); fflush(stdout); if ((tmpfile = open(filename, O_RDWR, 0)) == -1) die("Cannot open output file."); gettimeofday(&start_t, NULL); for (i = 0; i < loops; i++) { if (write(tmpfile, buf, WRITE_SIZE) != WRITE_SIZE) die("write failed"); if (write(tmpfile, buf, WRITE_SIZE) != WRITE_SIZE) die("write failed"); fdatasync(tmpfile); if (lseek(tmpfile, 0, SEEK_SET) == -1) die("seek failed"); } gettimeofday(&stop_t, NULL); close(tmpfile); print_elapse(start_t, stop_t); #else printf("\t(unavailable: fdatasync)\n"); #endif printf(LABEL_FORMAT, "8k write, 8k write, fsync"); fflush(stdout); if ((tmpfile = open(filename, O_RDWR, 0)) == -1) die("Cannot open output file."); gettimeofday(&start_t, NULL); for (i = 0; i < loops; i++) { if (write(tmpfile, buf, WRITE_SIZE) != WRITE_SIZE) die("write failed"); if (write(tmpfile, buf, WRITE_SIZE) != WRITE_SIZE) die("write failed"); if (fsync(tmpfile) != 0) die("fsync failed"); if (lseek(tmpfile, 0, SEEK_SET) == -1) die("seek failed"); } gettimeofday(&stop_t, NULL); close(tmpfile); print_elapse(start_t, stop_t); /* * Compare 1 to 2 writes */ printf("\nCompare open_sync with different sizes:\n"); #ifdef OPEN_SYNC_FLAG printf(LABEL_FORMAT, "open_sync 16k write"); fflush(stdout); if ((tmpfile = open(filename, O_RDWR | OPEN_SYNC_FLAG, 0)) == -1) die("Cannot open output file."); gettimeofday(&start_t, NULL); for (i = 0; i < loops; i++) { if (write(tmpfile, buf, WRITE_SIZE * 2) != WRITE_SIZE * 2) die("write failed"); if (lseek(tmpfile, 0, SEEK_SET) == -1) die("seek failed"); } gettimeofday(&stop_t, NULL); close(tmpfile); print_elapse(start_t, stop_t); printf(LABEL_FORMAT, "2 open_sync 8k writes"); fflush(stdout); if ((tmpfile = open(filename, O_RDWR | OPEN_SYNC_FLAG, 0)) == -1) die("Cannot open output file."); gettimeofday(&start_t, NULL); for (i = 0; i < loops; i++) { if (write(tmpfile, buf, WRITE_SIZE) != WRITE_SIZE) die("write failed"); if (write(tmpfile, buf, WRITE_SIZE) != WRITE_SIZE) die("write failed"); if (lseek(tmpfile, 0, SEEK_SET) == -1) die("seek failed"); } gettimeofday(&stop_t, NULL); close(tmpfile); print_elapse(start_t, stop_t); #else printf("\t(unavailable: open_sync)\n"); #endif /* * Fsync another file descriptor? */ printf("\nTest if fsync on non-write file descriptor is honored:\n"); printf("(If the times are similar, fsync() can sync data written\n"); printf("on a different descriptor.)\n"); printf(LABEL_FORMAT, "8k write, fsync, close"); fflush(stdout); gettimeofday(&start_t, NULL); for (i = 0; i < loops; i++) { if ((tmpfile = open(filename, O_RDWR, 0)) == -1) die("Cannot open output file."); if (write(tmpfile, buf, WRITE_SIZE) != WRITE_SIZE) die("write failed"); if (fsync(tmpfile) != 0) die("fsync failed"); close(tmpfile); if ((tmpfile = open(filename, O_RDWR, 0)) == -1) die("Cannot open output file."); /* do nothing but the open/close the tests are consistent. */ close(tmpfile); } gettimeofday(&stop_t, NULL); print_elapse(start_t, stop_t); printf(LABEL_FORMAT, "8k write, close, fsync"); fflush(stdout); gettimeofday(&start_t, NULL); for (i = 0; i < loops; i++) { if ((tmpfile = open(filename, O_RDWR, 0)) == -1) die("Cannot open output file."); if (write(tmpfile, buf, WRITE_SIZE) != WRITE_SIZE) die("write failed"); close(tmpfile); /* reopen file */ if ((tmpfile = open(filename, O_RDWR, 0)) == -1) die("Cannot open output file."); if (fsync(tmpfile) != 0) die("fsync failed"); close(tmpfile); } gettimeofday(&stop_t, NULL); print_elapse(start_t, stop_t); /* cleanup */ free(full_buf); unlink(filename); return 0; }
int main(int argc, char *argv[]) { struct timeval start_t; struct timeval stop_t; int tmpfile, i, loops = 5000; char *full_buf = (char *) malloc(XLOG_SEG_SIZE), *buf; char *filename = FSYNC_FILENAME; if (argc > 2 && strcmp(argv[1], "-f") == 0) { filename = argv[2]; argv += 2; argc -= 2; } if (argc > 1) loops = atoi(argv[1]); for (i = 0; i < XLOG_SEG_SIZE; i++) full_buf[i] = random(); if ((tmpfile = open(filename, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR, 0)) == -1) die("Cannot open output file."); if (write(tmpfile, full_buf, XLOG_SEG_SIZE) != XLOG_SEG_SIZE) die("write failed"); /* fsync now so later fsync's don't have to do it */ if (fsync(tmpfile) != 0) die("fsync failed"); close(tmpfile); // Page align the buffer //~ buf = (char *) TYPEALIGN(ALIGNOF_XLOG_BUFFER, full_buf); buf = full_buf; if (((intptr_t) full_buf & (PAGE_ALIGNMENT-1)) != 0) { buf = (void*) ((intptr_t) full_buf & ~(PAGE_ALIGNMENT-1)) + PAGE_ALIGNMENT; } printf("%p %p\n", full_buf, buf); assert(((intptr_t) buf & (PAGE_ALIGNMENT-1)) == 0); assert(XLOG_SEG_SIZE > WRITE_SIZE); /* * Simple write */ printf("Simple 8k write timing:\n"); /* write only */ gettimeofday(&start_t, NULL); for (i = 0; i < loops; i++) { if ((tmpfile = open(filename, O_RDWR, 0)) == -1) die("Cannot open output file."); if (write(tmpfile, buf, WRITE_SIZE) != WRITE_SIZE) die("write failed"); close(tmpfile); } gettimeofday(&stop_t, NULL); printf(LABEL_FORMAT, "write"); print_elapse(start_t, stop_t); /* * Compare file sync methods with one 8k write */ printf("\nCompare file sync methods using one 8k write:\n"); #ifdef OPEN_DATASYNC_FLAG /* open_dsync, write */ if ((tmpfile = open(filename, O_RDWR | O_DSYNC, 0)) == -1) die("Cannot open output file."); gettimeofday(&start_t, NULL); for (i = 0; i < loops; i++) { if (write(tmpfile, buf, WRITE_SIZE) != WRITE_SIZE) die("write failed"); if (lseek(tmpfile, 0, SEEK_SET) == -1) die("seek failed"); } gettimeofday(&stop_t, NULL); close(tmpfile); printf(LABEL_FORMAT, "open_datasync write"); print_elapse(start_t, stop_t); #else printf("\t(open_datasync unavailable)\n"); #endif #ifdef OPEN_SYNC_FLAG /* open_fsync, write */ if ((tmpfile = open(filename, O_RDWR | OPEN_SYNC_FLAG, 0)) == -1) die("Cannot open output file."); gettimeofday(&start_t, NULL); for (i = 0; i < loops; i++) { if (write(tmpfile, buf, WRITE_SIZE) != WRITE_SIZE) die("write failed"); if (lseek(tmpfile, 0, SEEK_SET) == -1) die("seek failed"); } gettimeofday(&stop_t, NULL); close(tmpfile); printf(LABEL_FORMAT, "open_sync write"); print_elapse(start_t, stop_t); #else printf("\t(open_sync unavailable)\n"); #endif #ifdef HAVE_FDATASYNC /* write, fdatasync */ if ((tmpfile = open(filename, O_RDWR, 0)) == -1) die("Cannot open output file."); gettimeofday(&start_t, NULL); for (i = 0; i < loops; i++) { if (write(tmpfile, buf, WRITE_SIZE) != WRITE_SIZE) die("write failed"); fdatasync(tmpfile); if (lseek(tmpfile, 0, SEEK_SET) == -1) die("seek failed"); } gettimeofday(&stop_t, NULL); close(tmpfile); printf(LABEL_FORMAT, "write, fdatasync"); print_elapse(start_t, stop_t); #else printf("\t(fdatasync unavailable)\n"); #endif /* write, fsync, close */ if ((tmpfile = open(filename, O_RDWR, 0)) == -1) die("Cannot open output file."); gettimeofday(&start_t, NULL); for (i = 0; i < loops; i++) { if (write(tmpfile, buf, WRITE_SIZE) != WRITE_SIZE) die("write failed"); if (fsync(tmpfile) != 0) die("fsync failed"); if (lseek(tmpfile, 0, SEEK_SET) == -1) die("seek failed"); } gettimeofday(&stop_t, NULL); close(tmpfile); printf(LABEL_FORMAT, "write, fsync"); print_elapse(start_t, stop_t); /* * Compare file sync methods with two 8k write */ printf("\nCompare file sync methods using two 8k writes:\n"); #ifdef OPEN_DATASYNC_FLAG /* open_dsync, write */ if ((tmpfile = open(filename, O_RDWR | O_DSYNC, 0)) == -1) die("Cannot open output file."); gettimeofday(&start_t, NULL); for (i = 0; i < loops; i++) { if (write(tmpfile, buf, WRITE_SIZE) != WRITE_SIZE) die("write failed"); if (write(tmpfile, buf, WRITE_SIZE) != WRITE_SIZE) die("write failed"); if (lseek(tmpfile, 0, SEEK_SET) == -1) die("seek failed"); } gettimeofday(&stop_t, NULL); close(tmpfile); printf(LABEL_FORMAT, "open_datasync write, write"); print_elapse(start_t, stop_t); #else printf("\t(open_datasync unavailable)\n"); #endif #ifdef OPEN_SYNC_FLAG /* open_fsync, write */ if ((tmpfile = open(filename, O_RDWR | OPEN_SYNC_FLAG, 0)) == -1) die("Cannot open output file."); gettimeofday(&start_t, NULL); for (i = 0; i < loops; i++) { if (write(tmpfile, buf, WRITE_SIZE) != WRITE_SIZE) die("write failed"); if (write(tmpfile, buf, WRITE_SIZE) != WRITE_SIZE) die("write failed"); if (lseek(tmpfile, 0, SEEK_SET) == -1) die("seek failed"); } gettimeofday(&stop_t, NULL); close(tmpfile); printf(LABEL_FORMAT, "open_sync write, write"); print_elapse(start_t, stop_t); #endif #ifdef HAVE_FDATASYNC /* write, fdatasync */ if ((tmpfile = open(filename, O_RDWR, 0)) == -1) die("Cannot open output file."); gettimeofday(&start_t, NULL); for (i = 0; i < loops; i++) { if (write(tmpfile, buf, WRITE_SIZE) != WRITE_SIZE) die("write failed"); if (write(tmpfile, buf, WRITE_SIZE) != WRITE_SIZE) die("write failed"); fdatasync(tmpfile); if (lseek(tmpfile, 0, SEEK_SET) == -1) die("seek failed"); } gettimeofday(&stop_t, NULL); close(tmpfile); printf(LABEL_FORMAT, "write, write, fdatasync"); print_elapse(start_t, stop_t); #else printf("\t(fdatasync unavailable)\n"); #endif /* write, fsync, close */ if ((tmpfile = open(filename, O_RDWR, 0)) == -1) die("Cannot open output file."); gettimeofday(&start_t, NULL); for (i = 0; i < loops; i++) { if (write(tmpfile, buf, WRITE_SIZE) != WRITE_SIZE) die("write failed"); if (write(tmpfile, buf, WRITE_SIZE) != WRITE_SIZE) die("write failed"); if (fsync(tmpfile) != 0) die("fsync failed"); if (lseek(tmpfile, 0, SEEK_SET) == -1) die("seek failed"); } gettimeofday(&stop_t, NULL); close(tmpfile); printf(LABEL_FORMAT, "write, write, fsync"); print_elapse(start_t, stop_t); /* * Compare 1 to 2 writes */ printf("\nCompare open_sync sizes:\n"); #ifdef OPEN_SYNC_FLAG /* 16k open_sync write */ if ((tmpfile = open(filename, O_RDWR | OPEN_SYNC_FLAG, 0)) == -1) die("Cannot open output file."); gettimeofday(&start_t, NULL); for (i = 0; i < loops; i++) { if (write(tmpfile, buf, WRITE_SIZE * 2) != WRITE_SIZE * 2) die("write failed"); if (lseek(tmpfile, 0, SEEK_SET) == -1) die("seek failed"); } gettimeofday(&stop_t, NULL); close(tmpfile); printf(LABEL_FORMAT, "16k open_sync write"); print_elapse(start_t, stop_t); /* Two 8k open_sync writes */ if ((tmpfile = open(filename, O_RDWR | OPEN_SYNC_FLAG, 0)) == -1) die("Cannot open output file."); gettimeofday(&start_t, NULL); for (i = 0; i < loops; i++) { if (write(tmpfile, buf, WRITE_SIZE) != WRITE_SIZE) die("write failed"); if (write(tmpfile, buf, WRITE_SIZE) != WRITE_SIZE) die("write failed"); if (lseek(tmpfile, 0, SEEK_SET) == -1) die("seek failed"); } gettimeofday(&stop_t, NULL); close(tmpfile); printf(LABEL_FORMAT, "2 8k open_sync writes"); print_elapse(start_t, stop_t); #else printf("\t(open_sync unavailable)\n"); #endif /* * Fsync another file descriptor? */ printf("\nCompare fsync times on write() and new file descriptors (if the times\n"); printf("are similar, fsync() can sync data written on a different descriptor):\n"); /* write, fsync, close */ gettimeofday(&start_t, NULL); for (i = 0; i < loops; i++) { if ((tmpfile = open(filename, O_RDWR, 0)) == -1) die("Cannot open output file."); if (write(tmpfile, buf, WRITE_SIZE) != WRITE_SIZE) die("write failed"); if (fsync(tmpfile) != 0) die("fsync failed"); close(tmpfile); if ((tmpfile = open(filename, O_RDWR, 0)) == -1) die("Cannot open output file."); /* do nothing but the open/close the tests are consistent. */ close(tmpfile); } gettimeofday(&stop_t, NULL); printf(LABEL_FORMAT, "write, fsync, close"); print_elapse(start_t, stop_t); /* write, close, fsync */ gettimeofday(&start_t, NULL); for (i = 0; i < loops; i++) { if ((tmpfile = open(filename, O_RDWR, 0)) == -1) die("Cannot open output file."); if (write(tmpfile, buf, WRITE_SIZE) != WRITE_SIZE) die("write failed"); close(tmpfile); /* reopen file */ if ((tmpfile = open(filename, O_RDWR, 0)) == -1) die("Cannot open output file."); if (fsync(tmpfile) != 0) die("fsync failed"); close(tmpfile); } gettimeofday(&stop_t, NULL); printf(LABEL_FORMAT, "write, close, fsync"); print_elapse(start_t, stop_t); /* cleanup */ free(full_buf); unlink(filename); return 0; }
static void test_file_descriptor_sync(void) { int tmpfile, ops; /* * Test whether fsync can sync data written on a different descriptor for * the same file. This checks the efficiency of multi-process fsyncs * against the same file. Possibly this should be done with writethrough * on platforms which support it. */ printf("\nTest if fsync on non-write file descriptor is honored:\n"); printf("(If the times are similar, fsync() can sync data written\n"); printf("on a different descriptor.)\n"); /* * first write, fsync and close, which is the normal behavior without * multiple descriptors */ printf(LABEL_FORMAT, "write, fsync, close"); fflush(stdout); gettimeofday(&start_t, NULL); for (ops = 0; ops < ops_per_test; ops++) { if ((tmpfile = open(filename, O_RDWR, 0)) == -1) die("could not open output file"); if (write(tmpfile, buf, XLOG_BLCKSZ) != XLOG_BLCKSZ) die("write failed"); if (fsync(tmpfile) != 0) die("fsync failed"); close(tmpfile); /* * open and close the file again to be consistent with the following * test */ if ((tmpfile = open(filename, O_RDWR, 0)) == -1) die("could not open output file"); close(tmpfile); } gettimeofday(&stop_t, NULL); print_elapse(start_t, stop_t); /* * Now open, write, close, open again and fsync This simulates processes * fsyncing each other's writes. */ printf(LABEL_FORMAT, "write, close, fsync"); fflush(stdout); gettimeofday(&start_t, NULL); for (ops = 0; ops < ops_per_test; ops++) { if ((tmpfile = open(filename, O_RDWR, 0)) == -1) die("could not open output file"); if (write(tmpfile, buf, XLOG_BLCKSZ) != XLOG_BLCKSZ) die("write failed"); close(tmpfile); /* reopen file */ if ((tmpfile = open(filename, O_RDWR, 0)) == -1) die("could not open output file"); if (fsync(tmpfile) != 0) die("fsync failed"); close(tmpfile); } gettimeofday(&stop_t, NULL); print_elapse(start_t, stop_t); }
static void test_sync(int writes_per_op) { int tmpfile, ops, writes; bool fs_warning = false; if (writes_per_op == 1) printf("\nCompare file sync methods using one %dkB write:\n", XLOG_BLCKSZ_K); else printf("\nCompare file sync methods using two %dkB writes:\n", XLOG_BLCKSZ_K); printf("(in wal_sync_method preference order, except fdatasync\n"); printf("is Linux's default)\n"); /* * Test open_datasync if available */ printf(LABEL_FORMAT, "open_datasync"); fflush(stdout); #ifdef OPEN_DATASYNC_FLAG if ((tmpfile = open(filename, O_RDWR | O_DSYNC | PG_O_DIRECT, 0)) == -1) { printf(NA_FORMAT, "n/a*\n"); fs_warning = true; } else { if ((tmpfile = open(filename, O_RDWR | O_DSYNC | PG_O_DIRECT, 0)) == -1) die("could not open output file"); gettimeofday(&start_t, NULL); for (ops = 0; ops < ops_per_test; ops++) { for (writes = 0; writes < writes_per_op; writes++) if (write(tmpfile, buf, XLOG_BLCKSZ) != XLOG_BLCKSZ) die("write failed"); if (lseek(tmpfile, 0, SEEK_SET) == -1) die("seek failed"); } gettimeofday(&stop_t, NULL); close(tmpfile); print_elapse(start_t, stop_t); } #else printf(NA_FORMAT, "n/a\n"); #endif /* * Test fdatasync if available */ printf(LABEL_FORMAT, "fdatasync"); fflush(stdout); #ifdef HAVE_FDATASYNC if ((tmpfile = open(filename, O_RDWR, 0)) == -1) die("could not open output file"); gettimeofday(&start_t, NULL); for (ops = 0; ops < ops_per_test; ops++) { for (writes = 0; writes < writes_per_op; writes++) if (write(tmpfile, buf, XLOG_BLCKSZ) != XLOG_BLCKSZ) die("write failed"); fdatasync(tmpfile); if (lseek(tmpfile, 0, SEEK_SET) == -1) die("seek failed"); } gettimeofday(&stop_t, NULL); close(tmpfile); print_elapse(start_t, stop_t); #else printf(NA_FORMAT, "n/a\n"); #endif /* * Test fsync */ printf(LABEL_FORMAT, "fsync"); fflush(stdout); if ((tmpfile = open(filename, O_RDWR, 0)) == -1) die("could not open output file"); gettimeofday(&start_t, NULL); for (ops = 0; ops < ops_per_test; ops++) { for (writes = 0; writes < writes_per_op; writes++) if (write(tmpfile, buf, XLOG_BLCKSZ) != XLOG_BLCKSZ) die("write failed"); if (fsync(tmpfile) != 0) die("fsync failed"); if (lseek(tmpfile, 0, SEEK_SET) == -1) die("seek failed"); } gettimeofday(&stop_t, NULL); close(tmpfile); print_elapse(start_t, stop_t); /* * If fsync_writethrough is available, test as well */ printf(LABEL_FORMAT, "fsync_writethrough"); fflush(stdout); #ifdef HAVE_FSYNC_WRITETHROUGH if ((tmpfile = open(filename, O_RDWR, 0)) == -1) die("could not open output file"); gettimeofday(&start_t, NULL); for (ops = 0; ops < ops_per_test; ops++) { for (writes = 0; writes < writes_per_op; writes++) if (write(tmpfile, buf, XLOG_BLCKSZ) != XLOG_BLCKSZ) die("write failed"); if (pg_fsync_writethrough(tmpfile) != 0) die("fsync failed"); if (lseek(tmpfile, 0, SEEK_SET) == -1) die("seek failed"); } gettimeofday(&stop_t, NULL); close(tmpfile); print_elapse(start_t, stop_t); #else printf(NA_FORMAT, "n/a\n"); #endif /* * Test open_sync if available */ printf(LABEL_FORMAT, "open_sync"); fflush(stdout); #ifdef OPEN_SYNC_FLAG if ((tmpfile = open(filename, O_RDWR | OPEN_SYNC_FLAG | PG_O_DIRECT, 0)) == -1) { printf(NA_FORMAT, "n/a*\n"); fs_warning = true; } else { gettimeofday(&start_t, NULL); for (ops = 0; ops < ops_per_test; ops++) { for (writes = 0; writes < writes_per_op; writes++) if (write(tmpfile, buf, XLOG_BLCKSZ) != XLOG_BLCKSZ) die("write failed"); if (lseek(tmpfile, 0, SEEK_SET) == -1) die("seek failed"); } gettimeofday(&stop_t, NULL); close(tmpfile); print_elapse(start_t, stop_t); } #else printf(NA_FORMAT, "n/a\n"); #endif if (fs_warning) { printf("* This file system and its mount options do not support direct\n"); printf("I/O, e.g. ext4 in journaled mode.\n"); } }