https://gcc.gnu.org/g:84aa7065deec49bab9fb0b085cd0a0dcc42cc479

commit r15-6454-g84aa7065deec49bab9fb0b085cd0a0dcc42cc479
Author: Nathaniel Shead <nathanielosh...@gmail.com>
Date:   Sat Dec 21 23:42:28 2024 +1100

    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 <nathanielosh...@gmail.com>

Diff:
---
 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 b9cf16433b5d..9ad587ebd6ac 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;
 }

Reply via email to