support O_DIRECT for file read/write benchmarks

This adds an option for enabling O_DIRECT for the uwrite, uread, and
ureadrand benchmarks and when we enable that we consequently disable
the "memory hog" code, which was unreliable on some platforms.

BUG=chrome-os-partner:30913
TEST=build punybench for link (x86) and veyron (armv7a) and -d flag
     works

Change-Id: I8270f2a58881675342fa54e730f98a8b72aae85b
Reviewed-on: https://chromium-review.googlesource.com/265475
Reviewed-by: Luigi Semenzato <semenzato@chromium.org>
Commit-Queue: Sonny Rao <sonnyrao@chromium.org>
Tested-by: Sonny Rao <sonnyrao@chromium.org>
diff --git a/file.m/uread.c b/file.m/uread.c
index 27638aa..2eef338 100644
--- a/file.m/uread.c
+++ b/file.m/uread.c
@@ -35,12 +35,14 @@
 
 u64 Bufsize_log2 = 12;
 bool Hog_memory = TRUE;
+bool Direct = FALSE;
 
 void usage (void)
 {
 	pr_usage("-m -f<file_name> -z<file_size> -i<num_iterations>"
 		" -b<bufsize_log2> -l<loops>\n"
 		"  -m - turns off memory hog\n"
+		"  -d - use O_DIRECT access (disables memory Hog)\n"
 		"  -f - path name of file\n"
 		"  -z - file size in bytes\n"
 		"  -b - buffer size - base 2 - 12->4096\n"
@@ -88,6 +90,10 @@
 	case 'b':
 		Bufsize_log2 = strtoll(optarg, NULL, 0);
 		break;
+	case 'd':
+		Direct = TRUE;
+		Hog_memory = FALSE;
+		break;
 	case 'm':
 		Hog_memory = FALSE;
 		break;
@@ -101,6 +107,7 @@
 {
 	u8		*buf;
 	int		fd;
+	int             flags;
 	ssize_t		haveRead;
 	size_t		toRead;
 	unsigned	i;
@@ -114,7 +121,7 @@
 	Option.file_size = 0;
 	Option.iterations = 1;
 	Option.loops = 1;
-	punyopt(argc, argv, myopt, "b:");
+	punyopt(argc, argv, myopt, "db:");
 	n = Option.iterations;
 	bufsize = 1 << Bufsize_log2;
 	buf = emalloc(bufsize);
@@ -125,7 +132,11 @@
 	if (Hog_memory) {
 		hog_leave_memory(size / FRACTION_OF_FILE_SIZE);
 	}
-	fd = open(Option.file, O_RDWR | O_CREAT | O_TRUNC, 0666);
+	flags = O_RDWR | O_CREAT | O_TRUNC;
+	if (Direct) {
+		flags |= O_DIRECT;
+	}
+	fd = open(Option.file, flags, 0666);
 	fill_file(fd, size);
 	for (l = 0; l < Option.loops; l++) {
 		startTimer();
diff --git a/file.m/ureadrand.c b/file.m/ureadrand.c
index 26cf624..c9c03ac 100644
--- a/file.m/ureadrand.c
+++ b/file.m/ureadrand.c
@@ -43,11 +43,15 @@
 
 u64 Bufsize_log2 = 12;
 
+bool Hog_memory = TRUE;
+bool Direct = FALSE;
+
 void usage (void)
 {
 	pr_usage("-f<file_name> -z<file_size> -i<num_iterations>"
 		" -b<bufsize_log2> -l<loops>\n"
 		"  -f - path name of file\n"
+		"  -d - use O_DIRECT access (disables memory Hog)\n"
 		"  -z - file size in bytes\n"
 		"  -b - buffer size - base 2 - 12->4096\n"
 		"  -i - number of inner iterations for one test\n"
@@ -94,6 +98,10 @@
 	case 'b':
 		Bufsize_log2 = strtoll(optarg, NULL, 0);
 		break;
+	case 'd':
+		Direct = TRUE;
+		Hog_memory = FALSE;
+		break;
 	default:
 		return FALSE;
 	}
@@ -104,6 +112,7 @@
 {
 	u8		*buf;
 	int		fd;
+	int             flags;
 	unsigned	i;
 	unsigned	bufsize;
 	unsigned	n;
@@ -116,15 +125,21 @@
 	Option.file_size = memtotal() / FRACTION_OF_MEMORY;
 	Option.iterations = 10000;
 	Option.loops = 2;
-	punyopt(argc, argv, myopt, "b:");
+	punyopt(argc, argv, myopt, "db:");
 	n = Option.iterations;
 	size = Option.file_size;
-	hog_leave_memory(size / FRACTION_OF_FILE_SIZE);
+	if (Hog_memory) {
+		hog_leave_memory(size / FRACTION_OF_FILE_SIZE);
+	}
 	bufsize = 1 << Bufsize_log2;
 	buf = emalloc(bufsize);
 	numbufs = size / bufsize;
 
-	fd = open(Option.file, O_RDWR | O_CREAT | O_TRUNC, 0666);
+	flags = O_RDWR | O_CREAT | O_TRUNC;
+	if (Direct) {
+		flags |= O_DIRECT;
+	}
+	fd = open(Option.file, flags, 0666);
 	fill_file(fd, size);
 	for (l = 0; l < Option.loops; l++) {
 		startTimer();
diff --git a/file.m/uwrite.c b/file.m/uwrite.c
index 6ebae7d..08c06f4 100644
--- a/file.m/uwrite.c
+++ b/file.m/uwrite.c
@@ -15,6 +15,8 @@
  * sequential write microbenchmark
  */
 
+/* #define _GNU_SOURCE */
+
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <fcntl.h>
@@ -35,12 +37,14 @@
 
 u64 Bufsize_log2 = 12;
 bool Hog_memory = TRUE;
+bool Direct = FALSE;
 
 void usage (void)
 {
 	pr_usage("-m -f<file_name> -z<file_size> -i<num_iterations>"
 		" -b<bufsize_log2> -l<loops>\n"
 		"  -m - turns off memory hog\n"
+		"  -d - use O_DIRECT access (disables memory Hog)\n"
 		"  -f - path name of file\n"
 		"  -z - file size in bytes\n"
 		"  -b - buffer size - base 2 - 12->4096\n"
@@ -54,6 +58,10 @@
 	case 'b':
 		Bufsize_log2 = strtoll(optarg, NULL, 0);
 		break;
+	case 'd':
+		Direct = TRUE;
+		Hog_memory = FALSE;
+		break;
 	case 'm':
 		Hog_memory = FALSE;
 		break;
@@ -80,7 +88,7 @@
 	Option.file_size = 0;
 	Option.iterations = 1;
 	Option.loops = 1;
-	punyopt(argc, argv, myopt, "mb:");
+	punyopt(argc, argv, myopt, "mdb:");
 
 	n = Option.iterations;
 	bufsize = 1 << Bufsize_log2;
@@ -103,8 +111,11 @@
 			 * overwriting it, recreating the file on each
 			 * iteration gives a more realistic value.
 			 */
+			int flags = O_RDWR | O_CREAT | O_TRUNC;
+			if (Direct)
+				flags |= O_DIRECT;
 			fd = open(Option.file,
-				O_RDWR | O_CREAT | O_TRUNC, 0666);
+				  flags, 0666);
 			if (fd == -1) fatal("open %s:", Option.file);
 			for (rest = size; rest; rest -= written) {
 				if (rest > bufsize) {