]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
c++/modules: Fallback to ftruncate if posix_fallocate fails [PR115008]
authorNathaniel Shead <nathanieloshead@gmail.com>
Sat, 21 Dec 2024 12:42:28 +0000 (23:42 +1100)
committerNathaniel Shead <nathanieloshead@gmail.com>
Sun, 29 Dec 2024 00:15:44 +0000 (11:15 +1100)
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>
gcc/cp/module.cc

index b9cf16433b5d5563de5030d4a4aee8ea6ec2d847..9ad587ebd6ac0f5b6401e637044342ed9354ab4e 100644 (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;
 }