* [PATCH 2/7] Switch git_mmap to use pread. [not found] <487c7d0ea81f2f82f330e277e0aea38a66ca7cfe.1166939109.git.spearce@spearce.org> @ 2006-12-24 5:45 ` Shawn O. Pearce 2006-12-24 13:09 ` Johannes Schindelin 2006-12-24 5:46 ` [PATCH 3/7] Ensure packed_git.next is initialized to NULL Shawn O. Pearce ` (4 subsequent siblings) 5 siblings, 1 reply; 13+ messages in thread From: Shawn O. Pearce @ 2006-12-24 5:45 UTC (permalink / raw) To: Junio C Hamano; +Cc: git Now that Git depends on pread in index-pack its safe to say we can also depend on it within the git_mmap emulation we activate when NO_MMAP is set. On most systems pread should be slightly faster than an lseek/read/lseek sequence as its one system call vs. three system calls. We also now honor EAGAIN and EINTR error codes from pread and restart the prior read. Signed-off-by: Shawn O. Pearce <spearce@spearce.org> --- compat/mmap.c | 17 ++++------------- 1 files changed, 4 insertions(+), 13 deletions(-) diff --git a/compat/mmap.c b/compat/mmap.c index bb34c7e..98056f0 100644 --- a/compat/mmap.c +++ b/compat/mmap.c @@ -2,17 +2,11 @@ void *git_mmap(void *start, size_t length, int prot, int flags, int fd, off_t offset) { - int n = 0; - off_t current_offset = lseek(fd, 0, SEEK_CUR); + size_t n = 0; if (start != NULL || !(flags & MAP_PRIVATE)) die("Invalid usage of mmap when built with NO_MMAP"); - if (lseek(fd, offset, SEEK_SET) < 0) { - errno = EINVAL; - return MAP_FAILED; - } - start = xmalloc(length); if (start == NULL) { errno = ENOMEM; @@ -20,7 +14,7 @@ void *git_mmap(void *start, size_t length, int prot, int flags, int fd, off_t of } while (n < length) { - int count = read(fd, start+n, length-n); + ssize_t count = pread(fd, start + n, length - n, offset + n); if (count == 0) { memset(start+n, 0, length-n); @@ -28,6 +22,8 @@ void *git_mmap(void *start, size_t length, int prot, int flags, int fd, off_t of } if (count < 0) { + if (errno == EAGAIN || errno == EINTR) + continue; free(start); errno = EACCES; return MAP_FAILED; @@ -36,11 +32,6 @@ void *git_mmap(void *start, size_t length, int prot, int flags, int fd, off_t of n += count; } - if (current_offset != lseek(fd, current_offset, SEEK_SET)) { - errno = EINVAL; - return MAP_FAILED; - } - return start; } -- 1.4.4.3.g2e63 ^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: [PATCH 2/7] Switch git_mmap to use pread. 2006-12-24 5:45 ` [PATCH 2/7] Switch git_mmap to use pread Shawn O. Pearce @ 2006-12-24 13:09 ` Johannes Schindelin 2006-12-24 19:30 ` Alon Ziv ` (2 more replies) 0 siblings, 3 replies; 13+ messages in thread From: Johannes Schindelin @ 2006-12-24 13:09 UTC (permalink / raw) To: Shawn O. Pearce; +Cc: Junio C Hamano, git Hi, On Sun, 24 Dec 2006, Shawn O. Pearce wrote: > Now that Git depends on pread in index-pack its safe to say we can > also depend on it within the git_mmap emulation we activate when > NO_MMAP is set. On most systems pread should be slightly faster > than an lseek/read/lseek sequence as its one system call vs. three > system calls. I don't think it matters much. The _only_ platform we really use NO_MMAP (other than for testing) is Windows, and AFAICT it does not have pread(), so it is emulated by lseek/read/lseek anyway. But it's a cleanup, and it deletes more lines than it adds, so Ack from me. Ciao, Dscho ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH 2/7] Switch git_mmap to use pread. 2006-12-24 13:09 ` Johannes Schindelin @ 2006-12-24 19:30 ` Alon Ziv 2006-12-24 20:13 ` Shawn Pearce 2006-12-24 20:14 ` Linus Torvalds 2 siblings, 0 replies; 13+ messages in thread From: Alon Ziv @ 2006-12-24 19:30 UTC (permalink / raw) To: Johannes Schindelin; +Cc: Shawn O. Pearce, Junio C Hamano, git [-- Attachment #1: Type: text/plain, Size: 522 bytes --] On Sun, 2006-12-24 at 14:09 +0100, Johannes Schindelin wrote: > I don't think it matters much. The _only_ platform we really use NO_MMAP > (other than for testing) is Windows, and AFAICT it does not have pread(), > so it is emulated by lseek/read/lseek anyway. > Well, Win32 does have a pread()-like behavior in its generic ReadFile() system call (using a curiously-named "lpOverlapped" parameter). I would have expected Cygwin to use it, but unfortunately from the CVS sources it appears not to :( -az [-- Attachment #2: smime.p7s --] [-- Type: application/x-pkcs7-signature, Size: 2156 bytes --] ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH 2/7] Switch git_mmap to use pread. 2006-12-24 13:09 ` Johannes Schindelin 2006-12-24 19:30 ` Alon Ziv @ 2006-12-24 20:13 ` Shawn Pearce 2006-12-24 20:14 ` Linus Torvalds 2 siblings, 0 replies; 13+ messages in thread From: Shawn Pearce @ 2006-12-24 20:13 UTC (permalink / raw) To: Johannes Schindelin; +Cc: Junio C Hamano, git Johannes Schindelin <Johannes.Schindelin@gmx.de> wrote: > On Sun, 24 Dec 2006, Shawn O. Pearce wrote: > > Now that Git depends on pread in index-pack its safe to say we can > > also depend on it within the git_mmap emulation we activate when > > NO_MMAP is set. On most systems pread should be slightly faster > > than an lseek/read/lseek sequence as its one system call vs. three > > system calls. > > I don't think it matters much. The _only_ platform we really use NO_MMAP > (other than for testing) is Windows, and AFAICT it does not have pread(), > so it is emulated by lseek/read/lseek anyway. > > But it's a cleanup, and it deletes more lines than it adds, so Ack from > me. Right - that's why I did it. I was already in there doing other work and discovered that we had a lot of lines just to avoid using pread. Initially that may have been because we were trying to avoid using it, but now that one of our more important tools (index-pack) depends on it... ;-) I'm actually thinking of doing a NO_PACK_MMAP, especially for systems like Mac OS X where the mmap() of small chunks appears to perform so poorly. Setting NO_PACK_MMAP and just using smaller windows (1 MiB) might be worthwhile. Though in that case we may just want to compile with NO_MMAP. -- Shawn. ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH 2/7] Switch git_mmap to use pread. 2006-12-24 13:09 ` Johannes Schindelin 2006-12-24 19:30 ` Alon Ziv 2006-12-24 20:13 ` Shawn Pearce @ 2006-12-24 20:14 ` Linus Torvalds 2 siblings, 0 replies; 13+ messages in thread From: Linus Torvalds @ 2006-12-24 20:14 UTC (permalink / raw) To: Johannes Schindelin; +Cc: Shawn O. Pearce, Junio C Hamano, git On Sun, 24 Dec 2006, Johannes Schindelin wrote: > > I don't think it matters much. The _only_ platform we really use NO_MMAP > (other than for testing) is Windows, and AFAICT it does not have pread(), > so it is emulated by lseek/read/lseek anyway. Windows definitely has pread(). It is, of course, possible that Cygwin emulates it some other way (including doing a "lseek/read/lseek" combination), but pread() should still be better - because maybe some future cygwin release ends up using the native interfaces. Linus ^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH 3/7] Ensure packed_git.next is initialized to NULL. [not found] <487c7d0ea81f2f82f330e277e0aea38a66ca7cfe.1166939109.git.spearce@spearce.org> 2006-12-24 5:45 ` [PATCH 2/7] Switch git_mmap to use pread Shawn O. Pearce @ 2006-12-24 5:46 ` Shawn O. Pearce 2006-12-24 5:46 ` [PATCH 4/7] Default core.packdGitWindowSize to 1 MiB if NO_MMAP Shawn O. Pearce ` (3 subsequent siblings) 5 siblings, 0 replies; 13+ messages in thread From: Shawn O. Pearce @ 2006-12-24 5:46 UTC (permalink / raw) To: Junio C Hamano; +Cc: git Junio noticed while reviewing this patch series that I removed the initialization of packed_git.next = NULL in 88078baa. That removal was not intended so I'm restoring the initialization where necessary. Signed-off-by: Shawn O. Pearce <spearce@spearce.org> --- sha1_file.c | 2 ++ 1 files changed, 2 insertions(+), 0 deletions(-) diff --git a/sha1_file.c b/sha1_file.c index 1a87f95..8de8ce0 100644 --- a/sha1_file.c +++ b/sha1_file.c @@ -676,6 +676,7 @@ struct packed_git *add_packed_git(char *path, int path_len, int local) p->index_size = idx_size; p->pack_size = st.st_size; p->index_base = idx_map; + p->next = NULL; p->windows = NULL; p->pack_fd = -1; p->pack_local = local; @@ -707,6 +708,7 @@ struct packed_git *parse_pack_index_file(const unsigned char *sha1, char *idx_pa p->index_size = idx_size; p->pack_size = 0; p->index_base = idx_map; + p->next = NULL; p->windows = NULL; p->pack_fd = -1; hashcpy(p->sha1, sha1); -- 1.4.4.3.g2e63 ^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 4/7] Default core.packdGitWindowSize to 1 MiB if NO_MMAP. [not found] <487c7d0ea81f2f82f330e277e0aea38a66ca7cfe.1166939109.git.spearce@spearce.org> 2006-12-24 5:45 ` [PATCH 2/7] Switch git_mmap to use pread Shawn O. Pearce 2006-12-24 5:46 ` [PATCH 3/7] Ensure packed_git.next is initialized to NULL Shawn O. Pearce @ 2006-12-24 5:46 ` Shawn O. Pearce 2006-12-24 5:46 ` [PATCH 5/7] Don't exit successfully on EPIPE in read_or_die Shawn O. Pearce ` (2 subsequent siblings) 5 siblings, 0 replies; 13+ messages in thread From: Shawn O. Pearce @ 2006-12-24 5:46 UTC (permalink / raw) To: Junio C Hamano; +Cc: git If the compiler has asked us to disable use of mmap() on their platform then we are forced to use git_mmap and its emulation via pread. In this case large (e.g. 32 MiB) windows for pack access are simply too big as a command will wind up reading a lot more data than it will ever need, significantly reducing response time. To prevent a high latency when NO_MMAP has been selected we now use a default of 1 MiB for core.packedGitWindowSize. Credit goes to Linus and Junio for recommending this more reasonable setting. Signed-off-by: Shawn O. Pearce <spearce@spearce.org> --- environment.c | 2 +- git-compat-util.h | 2 ++ 2 files changed, 3 insertions(+), 1 deletions(-) diff --git a/environment.c b/environment.c index 289fc84..e89aab4 100644 --- a/environment.c +++ b/environment.c @@ -22,7 +22,7 @@ char git_commit_encoding[MAX_ENCODING_LENGTH] = "utf-8"; int shared_repository = PERM_UMASK; const char *apply_default_whitespace; int zlib_compression_level = Z_DEFAULT_COMPRESSION; -size_t packed_git_window_size = 32 * 1024 * 1024; +size_t packed_git_window_size = DEFAULT_packed_git_window_size; size_t packed_git_limit = 256 * 1024 * 1024; int pager_in_use; int pager_use_color = 1; diff --git a/git-compat-util.h b/git-compat-util.h index 5d9eb26..e056339 100644 --- a/git-compat-util.h +++ b/git-compat-util.h @@ -87,6 +87,7 @@ extern void set_warn_routine(void (*routine)(const char *warn, va_list params)); #define MAP_FAILED ((void*)-1) #endif +#define DEFAULT_packed_git_window_size (1 * 1024 * 1024) #define mmap git_mmap #define munmap git_munmap extern void *git_mmap(void *start, size_t length, int prot, int flags, int fd, off_t offset); @@ -95,6 +96,7 @@ extern int git_munmap(void *start, size_t length); #else /* NO_MMAP */ #include <sys/mman.h> +#define DEFAULT_packed_git_window_size (32 * 1024 * 1024) #endif /* NO_MMAP */ -- 1.4.4.3.g2e63 ^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 5/7] Don't exit successfully on EPIPE in read_or_die. [not found] <487c7d0ea81f2f82f330e277e0aea38a66ca7cfe.1166939109.git.spearce@spearce.org> ` (2 preceding siblings ...) 2006-12-24 5:46 ` [PATCH 4/7] Default core.packdGitWindowSize to 1 MiB if NO_MMAP Shawn O. Pearce @ 2006-12-24 5:46 ` Shawn O. Pearce 2006-12-24 5:47 ` [PATCH 6/7] Release pack windows before reporting out of memory Shawn O. Pearce 2006-12-24 5:47 ` [PATCH 7/7] Replace mmap with xmmap, better handling MAP_FAILED Shawn O. Pearce 5 siblings, 0 replies; 13+ messages in thread From: Shawn O. Pearce @ 2006-12-24 5:46 UTC (permalink / raw) To: Junio C Hamano; +Cc: git Junio pointed out to me that read() won't return EPIPE like write() does, so there is no reason for us to exit successfully if we get an EPIPE error while in read_or_die. Instead we should just die if we get any error from read() while in read_or_die as there is no reasonable recovery. Signed-off-by: Shawn O. Pearce <spearce@spearce.org> --- write_or_die.c | 5 +---- 1 files changed, 1 insertions(+), 4 deletions(-) diff --git a/write_or_die.c b/write_or_die.c index a56d992..8cf6486 100644 --- a/write_or_die.c +++ b/write_or_die.c @@ -9,11 +9,8 @@ void read_or_die(int fd, void *buf, size_t count) loaded = xread(fd, p, count); if (loaded == 0) die("unexpected end of file"); - else if (loaded < 0) { - if (errno == EPIPE) - exit(0); + else if (loaded < 0) die("read error (%s)", strerror(errno)); - } count -= loaded; p += loaded; } -- 1.4.4.3.g2e63 ^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 6/7] Release pack windows before reporting out of memory. [not found] <487c7d0ea81f2f82f330e277e0aea38a66ca7cfe.1166939109.git.spearce@spearce.org> ` (3 preceding siblings ...) 2006-12-24 5:46 ` [PATCH 5/7] Don't exit successfully on EPIPE in read_or_die Shawn O. Pearce @ 2006-12-24 5:47 ` Shawn O. Pearce 2006-12-24 13:10 ` Johannes Schindelin 2006-12-24 5:47 ` [PATCH 7/7] Replace mmap with xmmap, better handling MAP_FAILED Shawn O. Pearce 5 siblings, 1 reply; 13+ messages in thread From: Shawn O. Pearce @ 2006-12-24 5:47 UTC (permalink / raw) To: Junio C Hamano; +Cc: git If we are about to fail because this process has run out of memory we should first try to automatically control our appetite for address space by releasing enough least-recently-used pack windows to gain back enough memory such that we might actually be able to meet the current allocation request. This should help users who have fairly large repositories but are working on systems with relatively small virtual address space. Many times we see reports on the mailing list of these users running out of memory during various Git operations. Dynamically decreasing the amount of pack memory used when the demand for heap memory is increasing is an intelligent solution to this problem. Signed-off-by: Shawn O. Pearce <spearce@spearce.org> --- git-compat-util.h | 40 ++++++++++++++++++++++++++++++++-------- sha1_file.c | 7 +++++++ 2 files changed, 39 insertions(+), 8 deletions(-) diff --git a/git-compat-util.h b/git-compat-util.h index e056339..4a417be 100644 --- a/git-compat-util.h +++ b/git-compat-util.h @@ -120,11 +120,17 @@ extern char *gitstrcasestr(const char *haystack, const char *needle); extern size_t gitstrlcpy(char *, const char *, size_t); #endif +extern void release_pack_memory(size_t); + static inline char* xstrdup(const char *str) { char *ret = strdup(str); - if (!ret) - die("Out of memory, strdup failed"); + if (!ret) { + release_pack_memory(strlen(str) + 1); + ret = strdup(str); + if (!ret) + die("Out of memory, strdup failed"); + } return ret; } @@ -133,8 +139,14 @@ static inline void *xmalloc(size_t size) void *ret = malloc(size); if (!ret && !size) ret = malloc(1); - if (!ret) - die("Out of memory, malloc failed"); + if (!ret) { + release_pack_memory(size); + ret = malloc(size); + if (!ret && !size) + ret = malloc(1); + if (!ret) + die("Out of memory, malloc failed"); + } #ifdef XMALLOC_POISON memset(ret, 0xA5, size); #endif @@ -146,8 +158,14 @@ static inline void *xrealloc(void *ptr, size_t size) void *ret = realloc(ptr, size); if (!ret && !size) ret = realloc(ptr, 1); - if (!ret) - die("Out of memory, realloc failed"); + if (!ret) { + release_pack_memory(size); + ret = realloc(ptr, size); + if (!ret && !size) + ret = realloc(ptr, 1); + if (!ret) + die("Out of memory, realloc failed"); + } return ret; } @@ -156,8 +174,14 @@ static inline void *xcalloc(size_t nmemb, size_t size) void *ret = calloc(nmemb, size); if (!ret && (!nmemb || !size)) ret = calloc(1, 1); - if (!ret) - die("Out of memory, calloc failed"); + if (!ret) { + release_pack_memory(nmemb * size); + ret = calloc(nmemb, size); + if (!ret && (!nmemb || !size)) + ret = calloc(1, 1); + if (!ret) + die("Out of memory, calloc failed"); + } return ret; } diff --git a/sha1_file.c b/sha1_file.c index 8de8ce0..fb1032b 100644 --- a/sha1_file.c +++ b/sha1_file.c @@ -522,6 +522,13 @@ static int unuse_one_window(struct packed_git *current) return 0; } +void release_pack_memory(size_t need) +{ + size_t cur = pack_mapped; + while (need >= (cur - pack_mapped) && unuse_one_window(NULL)) + ; /* nothing */ +} + void unuse_pack(struct pack_window **w_cursor) { struct pack_window *w = *w_cursor; -- 1.4.4.3.g2e63 ^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: [PATCH 6/7] Release pack windows before reporting out of memory. 2006-12-24 5:47 ` [PATCH 6/7] Release pack windows before reporting out of memory Shawn O. Pearce @ 2006-12-24 13:10 ` Johannes Schindelin 0 siblings, 0 replies; 13+ messages in thread From: Johannes Schindelin @ 2006-12-24 13:10 UTC (permalink / raw) To: Shawn O. Pearce; +Cc: Junio C Hamano, git Hi, a very cute idea that having x*alloc() in place you can just pluck in some garbage collection. I like it. Ciao, Dscho ^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH 7/7] Replace mmap with xmmap, better handling MAP_FAILED. [not found] <487c7d0ea81f2f82f330e277e0aea38a66ca7cfe.1166939109.git.spearce@spearce.org> ` (4 preceding siblings ...) 2006-12-24 5:47 ` [PATCH 6/7] Release pack windows before reporting out of memory Shawn O. Pearce @ 2006-12-24 5:47 ` Shawn O. Pearce 2006-12-24 13:22 ` Johannes Schindelin 5 siblings, 1 reply; 13+ messages in thread From: Shawn O. Pearce @ 2006-12-24 5:47 UTC (permalink / raw) To: Junio C Hamano; +Cc: git In some cases we did not even bother to check the return value of mmap() and just assume it worked. This is bad, because if we are out of virtual address space the kernel returned MAP_FAILED and we would attempt to dereference that address, segfaulting without any real error output to the user. We are replacing all calls to mmap() with xmmap() and moving all MAP_FAILED checking into that single location. If a mmap call fails we try to release enough least-recently-used pack windows to possibly succeed, then retry the mmap() attempt. If we cannot mmap even after releasing pack memory then we die() as none of our callers have any reasonable recovery strategy for a failed mmap. Signed-off-by: Shawn O. Pearce <spearce@spearce.org> --- config.c | 2 +- diff.c | 4 +--- git-compat-util.h | 13 +++++++++++++ read-cache.c | 2 +- refs.c | 2 +- sha1_file.c | 18 +++++------------- 6 files changed, 22 insertions(+), 19 deletions(-) diff --git a/config.c b/config.c index edc42f4..410d5e9 100644 --- a/config.c +++ b/config.c @@ -698,7 +698,7 @@ int git_config_set_multivar(const char* key, const char* value, } fstat(in_fd, &st); - contents = mmap(NULL, st.st_size, PROT_READ, + contents = xmmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, in_fd, 0); close(in_fd); diff --git a/diff.c b/diff.c index f14288b..244292a 100644 --- a/diff.c +++ b/diff.c @@ -1341,10 +1341,8 @@ int diff_populate_filespec(struct diff_filespec *s, int size_only) fd = open(s->path, O_RDONLY); if (fd < 0) goto err_empty; - s->data = mmap(NULL, s->size, PROT_READ, MAP_PRIVATE, fd, 0); + s->data = xmmap(NULL, s->size, PROT_READ, MAP_PRIVATE, fd, 0); close(fd); - if (s->data == MAP_FAILED) - goto err_empty; s->should_munmap = 1; } else { diff --git a/git-compat-util.h b/git-compat-util.h index 4a417be..51e8d7a 100644 --- a/git-compat-util.h +++ b/git-compat-util.h @@ -185,6 +185,19 @@ static inline void *xcalloc(size_t nmemb, size_t size) return ret; } +static inline void *xmmap(void *start, size_t length, + int prot, int flags, int fd, off_t offset) +{ + void *ret = mmap(start, length, prot, flags, fd, offset); + if (ret == MAP_FAILED) { + release_pack_memory(length); + ret = mmap(start, length, prot, flags, fd, offset); + if (ret == MAP_FAILED) + die("Out of memory? mmap failed: %s", strerror(errno)); + } + return ret; +} + static inline ssize_t xread(int fd, void *buf, size_t len) { ssize_t nr; diff --git a/read-cache.c b/read-cache.c index b8d83cc..ca3efbb 100644 --- a/read-cache.c +++ b/read-cache.c @@ -798,7 +798,7 @@ int read_cache_from(const char *path) cache_mmap_size = st.st_size; errno = EINVAL; if (cache_mmap_size >= sizeof(struct cache_header) + 20) - cache_mmap = mmap(NULL, cache_mmap_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0); + cache_mmap = xmmap(NULL, cache_mmap_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0); } close(fd); if (cache_mmap == MAP_FAILED) diff --git a/refs.c b/refs.c index a101ff3..286ae45 100644 --- a/refs.c +++ b/refs.c @@ -1025,7 +1025,7 @@ int read_ref_at(const char *ref, unsigned long at_time, int cnt, unsigned char * fstat(logfd, &st); if (!st.st_size) die("Log %s is empty.", logfile); - logdata = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, logfd, 0); + logdata = xmmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, logfd, 0); close(logfd); lastrec = NULL; diff --git a/sha1_file.c b/sha1_file.c index fb1032b..84037fe 100644 --- a/sha1_file.c +++ b/sha1_file.c @@ -355,10 +355,8 @@ static void read_info_alternates(const char * relative_base, int depth) close(fd); return; } - map = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0); + map = xmmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0); close(fd); - if (map == MAP_FAILED) - return; link_alt_odb_entries(map, map + st.st_size, '\n', relative_base, depth); @@ -442,10 +440,8 @@ static int check_packed_git_idx(const char *path, unsigned long *idx_size_, return -1; } idx_size = st.st_size; - idx_map = mmap(NULL, idx_size, PROT_READ, MAP_PRIVATE, fd, 0); + idx_map = xmmap(NULL, idx_size, PROT_READ, MAP_PRIVATE, fd, 0); close(fd); - if (idx_map == MAP_FAILED) - return -1; index = idx_map; *idx_map_ = idx_map; @@ -630,7 +626,7 @@ unsigned char* use_pack(struct packed_git *p, while (packed_git_limit < pack_mapped && unuse_one_window(p)) ; /* nothing */ - win->base = mmap(NULL, win->len, + win->base = xmmap(NULL, win->len, PROT_READ, MAP_PRIVATE, p->pack_fd, win->offset); if (win->base == MAP_FAILED) @@ -828,10 +824,8 @@ void *map_sha1_file(const unsigned char *sha1, unsigned long *size) */ sha1_file_open_flag = 0; } - map = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0); + map = xmmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0); close(fd); - if (map == MAP_FAILED) - return NULL; *size = st.st_size; return map; } @@ -1987,10 +1981,8 @@ int index_fd(unsigned char *sha1, int fd, struct stat *st, int write_object, con buf = ""; if (size) - buf = mmap(NULL, size, PROT_READ, MAP_PRIVATE, fd, 0); + buf = xmmap(NULL, size, PROT_READ, MAP_PRIVATE, fd, 0); close(fd); - if (buf == MAP_FAILED) - return -1; if (!type) type = blob_type; -- 1.4.4.3.g2e63 ^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: [PATCH 7/7] Replace mmap with xmmap, better handling MAP_FAILED. 2006-12-24 5:47 ` [PATCH 7/7] Replace mmap with xmmap, better handling MAP_FAILED Shawn O. Pearce @ 2006-12-24 13:22 ` Johannes Schindelin 2006-12-24 20:34 ` Shawn Pearce 0 siblings, 1 reply; 13+ messages in thread From: Johannes Schindelin @ 2006-12-24 13:22 UTC (permalink / raw) To: Shawn O. Pearce; +Cc: Junio C Hamano, git Hi, On Sun, 24 Dec 2006, Shawn O. Pearce wrote: > diff --git a/diff.c b/diff.c > index f14288b..244292a 100644 > --- a/diff.c > +++ b/diff.c > @@ -1341,10 +1341,8 @@ int diff_populate_filespec(struct diff_filespec *s, int size_only) > fd = open(s->path, O_RDONLY); > if (fd < 0) > goto err_empty; > - s->data = mmap(NULL, s->size, PROT_READ, MAP_PRIVATE, fd, 0); > + s->data = xmmap(NULL, s->size, PROT_READ, MAP_PRIVATE, fd, 0); > close(fd); > - if (s->data == MAP_FAILED) > - goto err_empty; The only gripe I have here is that the old code could actually say where the problem occurred ("cannot read data blob for <blabla>"), but that probably does not matter so much, now that we can hardly run out of memory on a decent machine, even using big packfiles. > diff --git a/read-cache.c b/read-cache.c > index b8d83cc..ca3efbb 100644 > --- a/read-cache.c > +++ b/read-cache.c > @@ -798,7 +798,7 @@ int read_cache_from(const char *path) > cache_mmap_size = st.st_size; > errno = EINVAL; > if (cache_mmap_size >= sizeof(struct cache_header) + 20) > - cache_mmap = mmap(NULL, cache_mmap_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0); > + cache_mmap = xmmap(NULL, cache_mmap_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0); > } > close(fd); > if (cache_mmap == MAP_FAILED) This MAP_FAILED no longer has anything to do with MAP_FAILED, but rather with fstat failed, so you probably want to move that into an else construct just before "close(fd);". All in all it is a good change -- for the builtin programs. But it is less good for the libification. Maybe it is time for a discussion about the possible strategies to avoid dying in libgit.a? Ciao, Dscho ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH 7/7] Replace mmap with xmmap, better handling MAP_FAILED. 2006-12-24 13:22 ` Johannes Schindelin @ 2006-12-24 20:34 ` Shawn Pearce 0 siblings, 0 replies; 13+ messages in thread From: Shawn Pearce @ 2006-12-24 20:34 UTC (permalink / raw) To: Johannes Schindelin; +Cc: Junio C Hamano, git Johannes Schindelin <Johannes.Schindelin@gmx.de> wrote: > All in all it is a good change -- for the builtin programs. > > But it is less good for the libification. Maybe it is time for a > discussion about the possible strategies to avoid dying in libgit.a? Well we have the same problem with xmalloc. All I've done is move the MAP_FAILED cases which tend to wind up die()'ing later anyway into the same scope of area where the xmalloc issue is. We die() all over the place. ~1312 times according to 'git grep die'. Git isn't a program for the living. :-) To properly libify we have a few issues: - we cannot just exit this process when we run into an error; - routines need to cleanup temporary resources (memory, file descriptors) when returning an error; - static variables like environment.c need to be reorganized to support multiple repositories in the same program; - objects need to be able to be deallocated, especially if the revision walking machinary has done rewriting Though the die() is the largest issue. -- Shawn. ^ permalink raw reply [flat|nested] 13+ messages in thread
end of thread, other threads:[~2006-12-24 20:34 UTC | newest]
Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <487c7d0ea81f2f82f330e277e0aea38a66ca7cfe.1166939109.git.spearce@spearce.org>
2006-12-24 5:45 ` [PATCH 2/7] Switch git_mmap to use pread Shawn O. Pearce
2006-12-24 13:09 ` Johannes Schindelin
2006-12-24 19:30 ` Alon Ziv
2006-12-24 20:13 ` Shawn Pearce
2006-12-24 20:14 ` Linus Torvalds
2006-12-24 5:46 ` [PATCH 3/7] Ensure packed_git.next is initialized to NULL Shawn O. Pearce
2006-12-24 5:46 ` [PATCH 4/7] Default core.packdGitWindowSize to 1 MiB if NO_MMAP Shawn O. Pearce
2006-12-24 5:46 ` [PATCH 5/7] Don't exit successfully on EPIPE in read_or_die Shawn O. Pearce
2006-12-24 5:47 ` [PATCH 6/7] Release pack windows before reporting out of memory Shawn O. Pearce
2006-12-24 13:10 ` Johannes Schindelin
2006-12-24 5:47 ` [PATCH 7/7] Replace mmap with xmmap, better handling MAP_FAILED Shawn O. Pearce
2006-12-24 13:22 ` Johannes Schindelin
2006-12-24 20:34 ` Shawn Pearce
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).