Use setvbuf() for log writing

Check if we have it - if we do, add a 1MB buffer for the file
output. This further speeds up the log writing.

Signed-off-by: Jens Axboe <axboe@fb.com>
diff --git a/configure b/configure
index 63aa02d..05f985b 100755
--- a/configure
+++ b/configure
@@ -1163,6 +1163,23 @@
 fi
 echo "Rados Block Device engine     $rbd"
 
+##########################################
+# Check whether we have setvbuf
+setvbuf="no"
+cat > $TMPC << EOF
+#include <stdio.h>
+int main(int argc, char **argv)
+{
+  FILE *f = NULL;
+  char buf[80];
+  setvbuf(f, buf, _IOFBF, sizeof(buf));
+  return 0;
+}
+EOF
+if compile_prog "" "" "setvbuf"; then
+  setvbuf="yes"
+fi
+echo "setvbuf                       $setvbuf"
 
 #############################################################################
 
@@ -1291,6 +1308,9 @@
 if test "$cpu_count" = "yes" ; then
   output_sym "CONFIG_CPU_COUNT"
 fi
+if test "$setvbuf" = "yes" ; then
+  output_sym "CONFIG_SETVBUF"
+fi
 
 echo "LIBS+=$LIBS" >> $config_host_mak
 echo "CFLAGS+=$CFLAGS" >> $config_host_mak
diff --git a/iolog.c b/iolog.c
index deec086..e805eae 100644
--- a/iolog.c
+++ b/iolog.c
@@ -516,9 +516,36 @@
 	*log = l;
 }
 
+#ifdef CONFIG_SETVBUF
+static void *set_file_buffer(FILE *f)
+{
+	size_t size = 1048576;
+	void *buf;
+
+	buf = malloc(size);
+	setvbuf(f, buf, _IOFBF, size);
+	return buf;
+}
+
+static void clear_file_buffer(void *buf)
+{
+	free(buf);
+}
+#else
+static void *set_file_buffer(FILE *f)
+{
+	return NULL;
+}
+
+static void clear_file_buffer(void *buf)
+{
+}
+#endif
+
 void __finish_log(struct io_log *log, const char *name)
 {
 	unsigned int i;
+	void *buf;
 	FILE *f;
 
 	f = fopen(name, "a");
@@ -527,6 +554,8 @@
 		return;
 	}
 
+	buf = set_file_buffer(f);
+
 	for (i = 0; i < log->nr_samples; i++) {
 		fprintf(f, "%lu, %lu, %u, %u\n",
 				(unsigned long) log->log[i].time,
@@ -535,6 +564,7 @@
 	}
 
 	fclose(f);
+	clear_file_buffer(buf);
 	free(log->log);
 	free(log);
 }