From c358e7c801e265ce07e909d75f3f3fd4e16c7f65 Mon Sep 17 00:00:00 2001 From: Joel Rosdahl Date: Thu, 26 Aug 2010 22:23:32 +0200 Subject: [PATCH] Read files into memory instead of using mmap() 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 | 27 ++++++++------------ ccache.h | 2 -- hashutil.c | 18 +++---------- unify.c | 16 +++++------- util.c | 74 ------------------------------------------------------ 5 files changed, 21 insertions(+), 116 deletions(-) diff --git a/ccache.c b/ccache.c index d5b292d65..36c7d7caf 100644 --- 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; } diff --git a/ccache.h b/ccache.h index 6f7430f0a..4455b27c2 100644 --- 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); diff --git a/hashutil.c b/hashutil.c index 23299d6f7..f7c72f03c 100644 --- a/hashutil.c +++ b/hashutil.c @@ -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 1f32603d5..4b5b868d5 100644 --- a/unify.c +++ b/unify.c @@ -37,6 +37,7 @@ #include #include #include +#include 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 31d497723..97bc96f0c 100644 --- 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). */ -- 2.47.3