mmap(win32): avoid expensive fstat() call

On Windows, we have to emulate the fstat() call to fill out information that takes extra effort to obtain, such as the file permissions/type. If all we want is the file size, we can use the much cheaper GetFileSizeEx() function (available since Windows XP). Suggested by Philip Kelley. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Johannes Schindelin committed Apr 22, 2016 at 16:31 UTC d5425d10ca68a297061f87f4460dd7e0b32b39a6
1 file changed +7 -9
compat/win32mmap.c
+7 -9
@@ -2,26 +2,24 @@
2
3 void *git_mmap(void *start, size_t length, int prot, int flags, int fd, off_t offset)
4 {
5 - HANDLE hmap;
5 + HANDLE osfhandle, hmap;
6 void *temp;
7 - off_t len;
8 - struct stat st;
7 + LARGE_INTEGER len;
8 uint64_t o = offset;
9 uint32_t l = o & 0xFFFFFFFF;
10 uint32_t h = (o >> 32) & 0xFFFFFFFF;
11
13 - if (!fstat(fd, &st))
14 - len = st.st_size;
15 - else
12 + osfhandle = (HANDLE)_get_osfhandle(fd);
13 + if (!GetFileSizeEx(osfhandle, &len))
14 die("mmap: could not determine filesize");
15
18 - if ((length + offset) > len)
19 - length = xsize_t(len - offset);
16 + if ((length + offset) > len.QuadPart)
17 + length = xsize_t(len.QuadPart - offset);
18
19 if (!(flags & MAP_PRIVATE))
20 die("Invalid usage of mmap when built with USE_WIN32_MMAP");
21
24 - hmap = CreateFileMapping((HANDLE)_get_osfhandle(fd), NULL,
22 + hmap = CreateFileMapping(osfhandle, NULL,
23 prot == PROT_READ ? PAGE_READONLY : PAGE_WRITECOPY, 0, 0, NULL);
24
25 if (!hmap) {