This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [gold] RFC: Add options for controlling mmap and fallocate of output file


Cary Coutant <ccoutant@google.com> writes:

> This patch adds --[no-]mmap-output-file and --[no-]posix-fallocate
> options to gold, to enable experimentation with alternative ways of
> writing the output file. On file systems that don't support the Linux
> fallocate() system call, posix_fallocate() resorts to single-byte
> writes to every block of the file, which is unacceptably slow for
> large output files. The --no-posix-fallocate option will disable this,
> and gold will instead try the fallocate() system call directly,
> falling back to ftruncate() when that fails. The --no-mmap-output-file
> option tells gold to use an anonymous block of memory to build the
> output file and use fwrite at the end of the link to write it to disk.
> In some preliminary experiments, this has actually shown to be faster
> than writing directly to the memory mapped file.

I don't understand why you are bothering with <linux/falloc.h> and
FALLOC_FL_KEEP_SIZE.  Why not just pass 0 as the mode argument to
fallocate?

Ian




>
> -cary
>
>
> 2012-06-05  Cary Coutant  <ccoutant@google.com>
>
> 	* configure.ac: Add check for <linux/falloc.h>.
> 	* configure: Regenerate.
> 	* config.in: Regenerate.
>
> 	* options.h (class General_options): Add --mmap-output-file and
> 	--posix-fallocate options.
> 	* output.cc: Include linux/falloc.h.
> 	(posix_fallocate): Remove; replace with...
> 	(gold_fallocate): New function.
> 	(Output_file::map_no_anonymous): Call gold_fallocate.
> 	(Output_file::map): Check --mmap-output-file option.
>
>
> commit 438f13c845cdf90ad8b84b3d1243b6a3ccce1ee7
> Author: Cary Coutant <ccoutant@google.com>
> Date:   Tue Jun 5 17:00:35 2012 -0700
>
>     Add --mmap-output-file and --posix-fallocate options.
>
> diff --git a/gold/configure.ac b/gold/configure.ac
> index a2c4875..dc096f7 100644
> --- a/gold/configure.ac
> +++ b/gold/configure.ac
> @@ -468,6 +468,7 @@ LFS_CFLAGS="-D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64"
>  AC_SUBST(LFS_CFLAGS)
>
>  AC_CHECK_HEADERS(sys/mman.h)
> +AC_CHECK_HEADERS(linux/falloc.h)
>  AC_CHECK_FUNCS(chsize mmap)
>  AC_REPLACE_FUNCS(pread ftruncate ffsll)
>
> diff --git a/gold/options.h b/gold/options.h
> index b244bd5..6463b80 100644
> --- a/gold/options.h
> +++ b/gold/options.h
> @@ -889,6 +889,10 @@ class General_options
>    DEFINE_string(m, options::EXACTLY_ONE_DASH, 'm', "",
>                  N_("Set GNU linker emulation; obsolete"), N_("EMULATION"));
>
> +  DEFINE_bool(mmap_output_file, options::TWO_DASHES, '\0', true,
> +              N_("Map the output file for writing (default)."),
> +              N_("Do not map the output file for writing."));
> +
>    DEFINE_bool(print_map, options::TWO_DASHES, 'M', false,
>  	      N_("Write map file on standard output"), NULL);
>    DEFINE_string(Map, options::ONE_DASH, '\0', NULL, N_("Write map file"),
> @@ -939,6 +943,11 @@ class General_options
>                   N_("Pass an option to the plugin"), N_("OPTION"));
>  #endif
>
> +  DEFINE_bool(posix_fallocate, options::TWO_DASHES, '\0', true,
> +              N_("Use posix_fallocate to reserve space in the output file"
> +		 " (default)."),
> +              N_("Use fallocate or ftruncate to reserve space."));
> +
>    DEFINE_bool(preread_archive_symbols, options::TWO_DASHES, '\0', false,
>                N_("Preread archive symbols when multi-threaded"), NULL);
>
> diff --git a/gold/output.cc b/gold/output.cc
> index 2236916..69ca8f2 100644
> --- a/gold/output.cc
> +++ b/gold/output.cc
> @@ -34,6 +34,10 @@
>  #include <sys/mman.h>
>  #endif
>
> +#ifdef HAVE_LINUX_FALLOC_H
> +#include <linux/falloc.h>
> +#endif
> +
>  #include "libiberty.h"
>
>  #include "dwarf.h"
> @@ -111,20 +115,6 @@ extern "C" void *gold_mremap(void *, size_t, size_t, int);
>  # define MREMAP_MAYMOVE 1
>  #endif
>
> -#ifndef HAVE_POSIX_FALLOCATE
> -// A dummy, non general, version of posix_fallocate.  Here we just set
> -// the file size and hope that there is enough disk space.  FIXME: We
> -// could allocate disk space by walking block by block and writing a
> -// zero byte into each block.
> -static int
> -posix_fallocate(int o, off_t offset, off_t len)
> -{
> -  if (ftruncate(o, offset + len) < 0)
> -    return errno;
> -  return 0;
> -}
> -#endif // !defined(HAVE_POSIX_FALLOCATE)
> -
>  // Mingw does not have S_ISLNK.
>  #ifndef S_ISLNK
>  # define S_ISLNK(mode) 0
> @@ -133,6 +123,27 @@ posix_fallocate(int o, off_t offset, off_t len)
>  namespace gold
>  {
>
> +// A wrapper around posix_fallocate.  If we don't have posix_fallocate,
> +// or the --no-posix-fallocate option is set, we try the fallocate
> +// system call directly.  If that fails, we use ftruncate to set
> +// the file size and hope that there is enough disk space.
> +
> +static int
> +gold_fallocate(int o, off_t offset, off_t len)
> +{
> +#ifdef HAVE_POSIX_FALLOCATE
> +  if (parameters->options().posix_fallocate())
> +    return ::posix_fallocate(o, offset, len);
> +#endif // !defined(HAVE_POSIX_FALLOCATE)
> +#ifdef FALLOC_FL_KEEP_SIZE
> +  if (::fallocate(o, FALLOC_FL_KEEP_SIZE, offset, len) == 0)
> +    return 0;
> +#endif // defined(FALLOC_FL_KEEP_SIZE)
> +  if (ftruncate(o, offset + len) < 0)
> +    return errno;
> +  return 0;
> +}
> +
>  // Output_data variables.
>
>  bool Output_data::allocated_sizes_are_fixed;
> @@ -5014,7 +5025,7 @@ Output_file::map_no_anonymous(bool writable)
>    // but that would be a more significant performance hit.
>    if (writable)
>      {
> -      int err = ::posix_fallocate(o, 0, this->file_size_);
> +      int err = gold_fallocate(o, 0, this->file_size_);
>        if (err != 0)
>         gold_fatal(_("%s: %s"), this->name_, strerror(err));
>      }
> @@ -5041,7 +5052,8 @@ Output_file::map_no_anonymous(bool writable)
>  void
>  Output_file::map()
>  {
> -  if (this->map_no_anonymous(true))
> +  if (parameters->options().mmap_output_file()
> +      && this->map_no_anonymous(true))
>      return;
>
>    // The mmap call might fail because of file system issues: the file


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]