c++/modules: Fallback to ftruncate if posix_fallocate fails [PR115008]

Depending on the libc and filesystem, in cases where posix_fallocate
cannot do an efficient preallocation it may return EINVAL.  In such a
case we should fall back to ftruncate instead.

Apparently, depending on the system the use of posix_fallocate can have
a noticeable speedup over ftruncate in general (depending on the system)
so it probably isn't worth it to use ftruncate in all cases.

	PR c++/100358
	PR c++/115008

gcc/cp/ChangeLog:

	* module.cc (elf_out::create_mapping): Fallback to ftruncate if
	posix_fallocate fails.

Signed-off-by: Nathaniel Shead <nathanieloshead@gmail.com>
This commit is contained in:
Nathaniel Shead 2024-12-21 23:42:28 +11:00
parent ce81cd2eac
commit 84aa7065de

View file

@ -1905,13 +1905,23 @@ elf_in::begin (location_t loc)
void
elf_out::create_mapping (unsigned ext, bool extending)
{
#ifndef HAVE_POSIX_FALLOCATE
#define posix_fallocate(fd,off,len) ftruncate (fd, off + len)
/* A wrapper around posix_fallocate, falling back to ftruncate
if the underlying filesystem does not support the operation. */
auto allocate = [](int fd, off_t offset, off_t length)
{
#ifdef HAVE_POSIX_FALLOCATE
int result = posix_fallocate (fd, offset, length);
if (result != EINVAL)
return result == 0;
/* Not supported by the underlying filesystem, fallback to ftruncate. */
#endif
return ftruncate (fd, offset + length) == 0;
};
void *mapping = MAP_FAILED;
if (extending && ext < 1024 * 1024)
{
if (!posix_fallocate (fd, offset, ext * 2))
if (allocate (fd, offset, ext * 2))
mapping = mmap (NULL, ext * 2, PROT_READ | PROT_WRITE,
MAP_SHARED, fd, offset);
if (mapping != MAP_FAILED)
@ -1919,7 +1929,7 @@ elf_out::create_mapping (unsigned ext, bool extending)
}
if (mapping == MAP_FAILED)
{
if (!extending || !posix_fallocate (fd, offset, ext))
if (!extending || allocate (fd, offset, ext))
mapping = mmap (NULL, ext, PROT_READ | PROT_WRITE,
MAP_SHARED, fd, offset);
if (mapping == MAP_FAILED)
@ -1929,7 +1939,6 @@ elf_out::create_mapping (unsigned ext, bool extending)
ext = 0;
}
}
#undef posix_fallocate
hdr.buffer = (char *)mapping;
extent = ext;
}