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.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138
diff --git a/src/indexer.c b/src/indexer.c
index 6266bc8..a3a8669 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 c7201ba..b3f1a1c 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 8785a4c..f204751 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 72abb34..c55ad1a 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 a99c30f..03a3646 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;
}