Commit d8fcafb2 by Carlos Martín Nieto Committed by Edward Thomson

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.
parent 9a668abd
......@@ -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)
......
......@@ -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)
{
......
......@@ -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
......
......@@ -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;
......
......@@ -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;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment