On 12/22/24 5:38 AM, Nathaniel Shead wrote:
Bootstrapped and regtested on x86_64-pc-linux-gnu, and also on
x86_64-unknown-freebsd13.3 by Gerald ([1], see also the discussion on
the PR); OK for trunk?
OK.
[1]: https://gcc.gnu.org/pipermail/gcc-testresults/2024-December/833487.html
-- >8 --
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 <nathanielosh...@gmail.com>
---
gcc/cp/module.cc | 19 ++++++++++++++-----
1 file changed, 14 insertions(+), 5 deletions(-)
diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc
index b9cf16433b5..9ad587ebd6a 100644
--- a/gcc/cp/module.cc
+++ b/gcc/cp/module.cc
@@ -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;
}