]> git.ipfire.org Git - thirdparty/ccache.git/commitdiff
Read files into memory instead of using mmap()
authorJoel Rosdahl <joel@rosdahl.net>
Thu, 26 Aug 2010 20:23:32 +0000 (22:23 +0200)
committerJoel Rosdahl <joel@rosdahl.net>
Thu, 26 Aug 2010 20:23:32 +0000 (22:23 +0200)
This has two benefits:

- It's more robust against file changes during reading.
- It improves performance on poor systems where mmap() doesn't use the disk
  cache.

ccache.c
ccache.h
hashutil.c
unify.c
util.c

index d5b292d651c79b6e2dcda3be33851734ce8ff702..36c7d7caf0695989fe0e3f0bd55aeaeac5028307 100644 (file)
--- a/ccache.c
+++ b/ccache.c
@@ -353,8 +353,8 @@ remember_include_file(char *path, size_t path_len)
        struct file_hash *h;
        struct mdfour fhash;
        struct stat st;
-       char *data = (char *)-1;
-       char *source;
+       char *source = NULL;
+       size_t size;
        int result;
 
        if (!included_files) {
@@ -398,16 +398,15 @@ remember_include_file(char *path, size_t path_len)
                hash_file(&fhash, path);
        } else {
                if (st.st_size > 0) {
-                       data = x_fmmap(path, &st.st_size, "include file");
-                       if (data == (char *)-1) {
+                       if (!read_file(path, st.st_size, &source, &size)) {
                                goto failure;
                        }
-                       source = data;
                } else {
-                       source = "";
+                       source = x_strdup("");
+                       size = 0;
                }
 
-               result = hash_source_code_string(&fhash, source, st.st_size, path);
+               result = hash_source_code_string(&fhash, source, size, path);
                if (result & HASH_SOURCE_CODE_ERROR
                    || result & HASH_SOURCE_CODE_FOUND_TIME) {
                        goto failure;
@@ -418,7 +417,6 @@ remember_include_file(char *path, size_t path_len)
        hash_result_as_bytes(&fhash, h->hash);
        h->size = fhash.totalN;
        hashtable_insert(included_files, path, h);
-       x_munmap(data, st.st_size);
        return;
 
 failure:
@@ -427,9 +425,7 @@ failure:
        /* Fall through. */
 ignore:
        free(path);
-       if (data != (char *)-1) {
-               x_munmap(data, st.st_size);
-       }
+       free(source);
 }
 
 /*
@@ -464,10 +460,9 @@ process_preprocessed_file(struct mdfour *hash, const char *path)
 {
        char *data;
        char *p, *q, *end;
-       off_t size;
+       size_t size;
 
-       data = x_fmmap(path, &size, "preprocessed file");
-       if (data == (void *)-1) {
+       if (!read_file(path, 32768, &data, &size)) {
                return 0;
        }
 
@@ -516,7 +511,7 @@ process_preprocessed_file(struct mdfour *hash, const char *path)
                        q++;
                        if (q >= end) {
                                cc_log("Failed to parse included file path");
-                               x_munmap(data, size);
+                               free(data);
                                return 0;
                        }
                        /* q points to the beginning of an include file path */
@@ -541,7 +536,7 @@ process_preprocessed_file(struct mdfour *hash, const char *path)
        }
 
        hash_buffer(hash, p, (end - p));
-       x_munmap(data, size);
+       free(data);
        return 1;
 }
 
index 6f7430f0ab3df892b07224a620f66c70df34179e..4455b27c23ecfee31484724e1e29415343fe020a 100644 (file)
--- a/ccache.h
+++ b/ccache.h
@@ -144,8 +144,6 @@ char *get_relative_path(const char *from, const char *to);
 int is_absolute_path(const char *path);
 int is_full_path(const char *path);
 void update_mtime(const char *path);
-void *x_fmmap(const char *fname, off_t *size, const char *errstr);
-int x_munmap(void *addr, size_t length);
 int x_rename(const char *oldpath, const char *newpath);
 char *x_readlink(const char *path);
 char *read_text_file(const char *path);
index 23299d6f7072e440bc347ed07d9e7874c3a98c11..f7c72f03c0467d18f11860dccfdb7656342573b2 100644 (file)
@@ -207,18 +207,10 @@ end:
 int
 hash_source_code_file(struct mdfour *hash, const char *path)
 {
-       struct stat st;
        char *data;
+       size_t size;
        int result;
 
-       if (stat(path, &st) == -1) {
-               cc_log("Failed to stat %s", path);
-               return HASH_SOURCE_CODE_ERROR;
-       }
-       if (st.st_size == 0) {
-               return HASH_SOURCE_CODE_OK;
-       }
-
        if (is_precompiled_header(path)) {
                if (hash_file(hash, path)) {
                        return HASH_SOURCE_CODE_OK;
@@ -226,13 +218,11 @@ hash_source_code_file(struct mdfour *hash, const char *path)
                        return HASH_SOURCE_CODE_ERROR;
                }
        } else {
-               data = x_fmmap(path, &st.st_size, "source code file");
-               if (data == (void *)-1) {
+               if (!read_file(path, 0, &data, &size)) {
                        return HASH_SOURCE_CODE_ERROR;
                }
-
-               result = hash_source_code_string(hash, data, st.st_size, path);
-               x_munmap(data, st.st_size);
+               result = hash_source_code_string(hash, data, size, path);
+               free(data);
                return result;
        }
 }
diff --git a/unify.c b/unify.c
index 1f32603d5721747a86b2bdac41d5c59c2309f572..4b5b868d5843cf7f2b67328919ffdbf3385bae96 100644 (file)
--- a/unify.c
+++ b/unify.c
@@ -37,6 +37,7 @@
 #include <fcntl.h>
 #include <string.h>
 #include <unistd.h>
+#include <stdlib.h>
 
 static const char *const s_tokens[] = {
        "...", ">>=", "<<=", "+=", "-=", "*=", "/=", "%=", "&=", "^=",
@@ -246,19 +247,14 @@ unify(struct mdfour *hash, unsigned char *p, size_t size)
 int
 unify_hash(struct mdfour *hash, const char *fname)
 {
-       off_t size;
-       char *map;
+       char *data;
+       size_t size;
 
-       map = x_fmmap(fname, &size, "preprocessor output");
-       if (map == (void *) -1) {
+       if (!read_file(fname, 0, &data, &size)) {
                stats_update(STATS_PREPROCESSOR);
                return -1;
        }
-
-       /* pass it through the unifier */
-       unify(hash, (unsigned char *)map, size);
-
-       x_munmap(map, size);
-
+       unify(hash, (unsigned char *)data, size);
+       free(data);
        return 0;
 }
diff --git a/util.c b/util.c
index 31d49772394db992292db45a8cee349d889b7b55..97bc96f0cc5dc40e4cce14e1f6526d5f35731536 100644 (file)
--- a/util.c
+++ b/util.c
@@ -1043,80 +1043,6 @@ update_mtime(const char *path)
 #endif
 }
 
-/*
- * Map file into memory. Return a pointer to the mapped area if successful or
- * -1 if any error occurred. The file size is also returned,
- */
-void *
-x_fmmap(const char *fname, off_t *size, const char *errstr)
-{
-       struct stat st;
-       void *data = (void *) -1;
-       int fd = -1;
-#ifdef _WIN32
-       HANDLE section;
-       HANDLE file;
-       file = CreateFile(fname, GENERIC_READ, FILE_SHARE_READ, NULL,
-                         OPEN_EXISTING, 0, NULL);
-       if (file == INVALID_HANDLE_VALUE) {
-               cc_log("Failed to open %s %s", errstr, fname);
-               goto error;
-       }
-       fd = _open_osfhandle((intptr_t) file, O_RDONLY | O_BINARY);
-       if (fd == -1) {
-               cc_log("Failed to open %s %s", errstr, fname);
-               CloseHandle(file);
-               goto error;
-       }
-       if (fstat(fd, &st) == -1) {
-               cc_log("Failed to fstat %s %s", errstr, fname);
-               CloseHandle(file);
-               goto error;
-       }
-       section = CreateFileMapping(file, NULL, PAGE_READONLY, 0, 0, NULL);
-       CloseHandle(file);
-       if (!section) {
-               cc_log("Failed to mmap %s %s", errstr, fname);
-               goto error;
-       }
-       data = MapViewOfFile(section, FILE_MAP_READ, 0, 0, 0);
-       CloseHandle(section);
-#else
-       fd = open(fname, O_RDONLY | O_BINARY);
-       if (fd == -1) {
-               cc_log("Failed to open %s %s", errstr, fname);
-               goto error;
-       }
-       if (fstat(fd, &st) == -1) {
-               cc_log("Failed to fstat %s %s", errstr, fname);
-               close(fd);
-               goto error;
-       }
-       data = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
-       close(fd);
-       if (data == (void *) -1) {
-               cc_log("Failed to mmap %s %s", errstr, fname);
-       }
-#endif
-       *size = st.st_size;
-error:
-       return data;
-}
-
-/*
- * Unmap file from memory.
- */
-int
-x_munmap(void *addr, size_t length)
-{
-#ifdef _WIN32
-       (void) length;
-       return UnmapViewOfFile(addr) ? 0 : -1;
-#else
-       return munmap(addr, length);
-#endif
-}
-
 /*
  * Rename oldpath to newpath (deleting newpath).
  */