From d8fcafb2ca384a9b5e89ea922c515145fb050e46 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn=20Nieto?= Date: Wed, 16 Mar 2016 19:05:11 +0100 Subject: Split the page size from the mmap alignment While often similar, these are not the same on Windows. We want to use the page size on Windows for the pools, but for mmap we need to use the allocation granularity as the alignment. On the other platforms these values remain the same. --- src/indexer.c | 8 ++++---- src/posix.c | 7 +++++++ src/posix.h | 1 + src/unix/map.c | 5 +++++ src/win32/map.c | 29 ++++++++++++++++++++++++----- 5 files changed, 41 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/indexer.c b/src/indexer.c index 6266bc888..a3a866989 100644 --- a/src/indexer.c +++ b/src/indexer.c @@ -449,7 +449,7 @@ static void hash_partially(git_indexer *idx, const uint8_t *data, size_t size) static int write_at(git_indexer *idx, const void *data, git_off_t offset, size_t size) { git_file fd = idx->pack->mwf.fd; - size_t page_size; + size_t mmap_alignment; size_t page_offset; git_off_t page_start; unsigned char *map_data; @@ -458,11 +458,11 @@ static int write_at(git_indexer *idx, const void *data, git_off_t offset, size_t assert(data && size); - if ((error = git__page_size(&page_size)) < 0) + if ((error = git__mmap_alignment(&mmap_alignment)) < 0) return error; - /* the offset needs to be at the beginning of the a page boundary */ - page_offset = offset % page_size; + /* the offset needs to be at the mmap boundary for the platform */ + page_offset = offset % mmap_alignment; page_start = offset - page_offset; if ((error = p_mmap(&map, page_offset + size, GIT_PROT_WRITE, GIT_MAP_SHARED, fd, page_start)) < 0) diff --git a/src/posix.c b/src/posix.c index c7201ba14..b3f1a1cd3 100644 --- a/src/posix.c +++ b/src/posix.c @@ -224,6 +224,13 @@ int git__page_size(size_t *page_size) return 0; } +int git__mmap_alignment(size_t *alignment) +{ + /* dummy; here we don't need any alignment anyway */ + *alignment = 4096; + return 0; +} + int p_mmap(git_map *out, size_t len, int prot, int flags, int fd, git_off_t offset) { diff --git a/src/posix.h b/src/posix.h index 8785a4c99..f204751cf 100644 --- a/src/posix.h +++ b/src/posix.h @@ -109,6 +109,7 @@ extern int p_getcwd(char *buffer_out, size_t size); extern int p_rename(const char *from, const char *to); extern int git__page_size(size_t *page_size); +extern int git__mmap_alignment(size_t *page_size); /** * Platform-dependent methods diff --git a/src/unix/map.c b/src/unix/map.c index 72abb3418..c55ad1aa7 100644 --- a/src/unix/map.c +++ b/src/unix/map.c @@ -24,6 +24,11 @@ int git__page_size(size_t *page_size) return 0; } +int git__mmap_alignment(size_t *alignment) +{ + return git__page_size(alignment); +} + int p_mmap(git_map *out, size_t len, int prot, int flags, int fd, git_off_t offset) { int mprot = PROT_READ; diff --git a/src/win32/map.c b/src/win32/map.c index a99c30f7e..03a3646a6 100644 --- a/src/win32/map.c +++ b/src/win32/map.c @@ -17,22 +17,41 @@ static DWORD get_page_size(void) if (!page_size) { GetSystemInfo(&sys); - page_size = sys.dwAllocationGranularity; + page_size = sys.dwPageSize; } return page_size; } +static DWORD get_allocation_granularity(void) +{ + static DWORD granularity; + SYSTEM_INFO sys; + + if (!granularity) { + GetSystemInfo(&sys); + granularity = sys.dwAllocationGranularity; + } + + return granularity; +} + int git__page_size(size_t *page_size) { *page_size = get_page_size(); return 0; } +int git__mmap_alignment(size_t *page_size) +{ + *page_size = get_allocation_granularity(); + return 0; +} + int p_mmap(git_map *out, size_t len, int prot, int flags, int fd, git_off_t offset) { HANDLE fh = (HANDLE)_get_osfhandle(fd); - DWORD page_size = get_page_size(); + DWORD alignment = get_allocation_granularity(); DWORD fmap_prot = 0; DWORD view_prot = 0; DWORD off_low = 0; @@ -62,12 +81,12 @@ int p_mmap(git_map *out, size_t len, int prot, int flags, int fd, git_off_t offs if (prot & GIT_PROT_READ) view_prot |= FILE_MAP_READ; - page_start = (offset / page_size) * page_size; + page_start = (offset / alignment) * alignment; page_offset = offset - page_start; - if (page_offset != 0) { /* offset must be multiple of page size */ + if (page_offset != 0) { /* offset must be multiple of the allocation granularity */ errno = EINVAL; - giterr_set(GITERR_OS, "Failed to mmap. Offset must be multiple of page size"); + giterr_set(GITERR_OS, "Failed to mmap. Offset must be multiple of allocation granularity"); return -1; } -- cgit v1.2.1