git » drill.git » commit 8b32394

Use mmap() to create a region of '\0's

author Rodrigo Campos
2014-01-20 22:51:46 UTC
committer Rodrigo Campos
2014-01-21 00:09:30 UTC
parent 2354996d523b6a636507eea795bed8a195bee7a8

Use mmap() to create a region of '\0's

Using mmap() we can guarantee that the content is zero initialized, so for our
usage is the same using mmap() or calloc(). But the main difference is that when
using mmap() carefully, Linux can be smart and never allocate this memory.

This reduces program RSS mem by ~half, as only the buffer to read the file is
really allocated now.

Signed-off-by: Rodrigo Campos <rodrigo@sdfg.com.ar>

drill.c +14 -6

diff --git a/drill.c b/drill.c
index 9fd1287..03f8eb6 100644
--- a/drill.c
+++ b/drill.c
@@ -4,6 +4,7 @@
 #include <sys/stat.h>           /* open() */
 #include <stdio.h>              /* printf(), perror() */
 #include <stdlib.h>             /* strtoul(), malloc() and friends */
+#include <sys/mman.h>           /* mmap() */
 #include <unistd.h>             /* lseek(), pread(), getopt(), sleep() */
 #include <sys/types.h>          /* lseek() */
 #include <string.h>             /* memcmp() */
@@ -12,7 +13,6 @@
 /*
  *  TODO:
  *      Add tests
- *      Use mmap ?
  */
 
 void usage(void)
@@ -75,11 +75,16 @@ int dig_hole(int fd, off_t offset, off_t length)
 int drill(int fd, size_t hole_size)
 {
 	int ret = 0;
+	int err;
 
 	/* Create a buffer of '\0's to compare against */
-	void *zeros = calloc(1, hole_size);
-	if (zeros == NULL)
+	/* XXX: Use mmap() with MAP_PRIVATE so Linux can avoid this allocation */
+	void *zeros = mmap(NULL, hole_size, PROT_READ,
+	                   MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
+	if (zeros == MAP_FAILED) {
+		perror("mmap failed");
 		return 1;
+	}
 
 	/* buffer to read the file */
 	ssize_t buf_len = hole_size;
@@ -116,7 +121,11 @@ int drill(int fd, size_t hole_size)
 			goto out;
 	}
 out:
-	free(zeros);
+	err = munmap(zeros, hole_size);
+	if (err == -1) {
+		perror("munmap failed");
+		ret = 1;
+	}
 	free(buf);
 	return ret;
 }
@@ -149,8 +158,7 @@ int main(int argc, char **argv)
 	}
 
 	if (hole_size >= 100 * 1024 * 1024) {
-		/* We allocate two buffers of size hole_size */
-		size_t ram_mb = 2 * hole_size / 1024 / 1024;
+		size_t ram_mb = hole_size / 1024 / 1024;
 		printf("WARNING: %zu MB RAM will be used\n", ram_mb);
 		sleep(3);
 	}