Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 30 Aug 2011 16:23:57 +0000 (UTC)
From:      Gabor Kovesdan <gabor@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-user@freebsd.org
Subject:   svn commit: r225264 - user/gabor/grep/trunk
Message-ID:  <201108301623.p7UGNvwq058409@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: gabor
Date: Tue Aug 30 16:23:57 2011
New Revision: 225264
URL: http://svn.freebsd.org/changeset/base/225264

Log:
  - Add back mmap support. It must be more efficient than read(2) if properly
    implemented. The prefetching problem has to be solved for mmap(2).
  
  Suggested by:	alc

Modified:
  user/gabor/grep/trunk/file.c
  user/gabor/grep/trunk/grep.c
  user/gabor/grep/trunk/grep.h

Modified: user/gabor/grep/trunk/file.c
==============================================================================
--- user/gabor/grep/trunk/file.c	Tue Aug 30 16:20:16 2011	(r225263)
+++ user/gabor/grep/trunk/file.c	Tue Aug 30 16:23:57 2011	(r225264)
@@ -34,8 +34,9 @@
 __FBSDID("$FreeBSD$");
 
 #include <sys/param.h>
-#include <sys/types.h>
+#include <sys/mman.h>
 #include <sys/stat.h>
+#include <sys/types.h>
 
 #include <bzlib.h>
 #include <err.h>
@@ -59,9 +60,10 @@ static gzFile gzbufdesc;
 static BZFILE* bzbufdesc;
 static lzma_stream lstrm = LZMA_STREAM_INIT;
 
-static unsigned char buffer[MAXBUFSIZ];
+static unsigned char *buffer;
 static unsigned char *bufpos;
 static size_t bufrem;
+static size_t fsiz;
 
 static unsigned char *lnbuf;
 static size_t lnbuflen;
@@ -72,6 +74,9 @@ grep_refill(struct file *f)
 	ssize_t nr;
 	int bzerr;
 
+	if (filebehave == FILE_MMAP)
+		return (0);
+
 	bufpos = buffer;
 	bufrem = 0;
 
@@ -235,6 +240,33 @@ grep_open(const char *path)
 	} else if ((f->fd = open(path, O_RDONLY)) == -1)
 		goto error1;
 
+	if (filebehave == FILE_MMAP) {
+		struct stat st;
+
+		if ((fstat(f->fd, &st) == -1) || (st.st_size > OFF_MAX) ||
+		    (!S_ISREG(st.st_mode)))
+			filebehave = FILE_STDIO;
+		else {
+			int flags = MAP_PRIVATE | MAP_NOCORE | MAP_NOSYNC;
+#ifdef MAP_PREFAULT_READ
+			flags |= MAP_PREFAULT_READ;
+#endif
+			fsiz = st.st_size;
+			buffer = mmap(NULL, fsiz, PROT_READ, flags,
+			     f->fd, (off_t)0);
+			if (buffer == MAP_FAILED)
+				filebehave = FILE_STDIO;
+			else {
+				bufrem = st.st_size;
+				bufpos = buffer;
+				madvise(buffer, st.st_size, MADV_SEQUENTIAL);
+			}
+		}
+	}
+
+	if ((buffer == NULL) || (buffer == MAP_FAILED))
+		buffer = grep_malloc(MAXBUFSIZ);
+
 	if (filebehave == FILE_GZIP &&
 	    (gzbufdesc = gzdopen(f->fd, "r")) == NULL)
 		goto error2;
@@ -244,7 +276,7 @@ grep_open(const char *path)
 		goto error2;
 
 	/* Fill read buffer, also catches errors early */
-	if (grep_refill(f) != 0)
+	if (bufrem == 0 && grep_refill(f) != 0)
 		goto error2;
 
 	/* Check for binary stuff, if necessary */
@@ -270,6 +302,10 @@ grep_close(struct file *f)
 	close(f->fd);
 
 	/* Reset read buffer and line buffer */
+	if (filebehave == FILE_MMAP) {
+		munmap(buffer, fsiz);
+		buffer = NULL;
+	}
 	bufpos = buffer;
 	bufrem = 0;
 

Modified: user/gabor/grep/trunk/grep.c
==============================================================================
--- user/gabor/grep/trunk/grep.c	Tue Aug 30 16:20:16 2011	(r225263)
+++ user/gabor/grep/trunk/grep.c	Tue Aug 30 16:23:57 2011	(r225264)
@@ -548,7 +548,7 @@ main(int argc, char *argv[])
 			break;
 		case 'u':
 		case MMAP_OPT:
-			/* noop, compatibility */
+			filebehave = FILE_MMAP;
 			break;
 		case 'V':
 			printf(getstr(9), __progname, VERSION);

Modified: user/gabor/grep/trunk/grep.h
==============================================================================
--- user/gabor/grep/trunk/grep.h	Tue Aug 30 16:20:16 2011	(r225263)
+++ user/gabor/grep/trunk/grep.h	Tue Aug 30 16:23:57 2011	(r225264)
@@ -60,10 +60,11 @@ extern const char		*errstr[];
 #define BINFILE_TEXT	2
 
 #define FILE_STDIO	0
-#define FILE_GZIP	1
-#define FILE_BZIP	2
-#define FILE_XZ		3
-#define FILE_LZMA	4
+#define FILE_MMAP	1
+#define FILE_GZIP	2
+#define FILE_BZIP	3
+#define FILE_XZ		4
+#define FILE_LZMA	5
 
 #define DIR_READ	0
 #define DIR_SKIP	1



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201108301623.p7UGNvwq058409>