public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
From: "Clément Chigot" <chigot@adacore.com>
To: Alan Modra <amodra@gmail.com>
Cc: binutils@sourceware.org
Subject: Re: PR30724, cygwin ld performance regression since 014a602b86
Date: Wed, 9 Aug 2023 16:42:48 +0200	[thread overview]
Message-ID: <CAJ307EhaA4SnO+JaxWeYoO6mCmkUAEGdLQ+OEbB3X6kDMSD3ew@mail.gmail.com> (raw)
In-Reply-To: <ZNLN6eSxmIH86CSq@squeak.grove.modra.org>

On Wed, Aug 9, 2023 at 1:21 AM Alan Modra <amodra@gmail.com> wrote:
>
> According to the reporter of this bug the newlib fseek implementation
> is likely slowed down by locking and fflush, only attempting to
> optimise seeks when the file is opened read-only.  Thus when writing
> the output we get a dramatic slowdown due to commit 014a602b86.
>
> Clément would you please check that this doesn't regress anything on
> mingw.

I'm not seeing any and the issue fixed by 014a602b86 is still fixed so
it looks good.
However, I have a question regarding the purpose of bfd_io_force.
Unless bfd_seek fails, it would be overridden right away. So are there
cases where bfd_seek fails and bfd doesn't report an error, continuing
to perform inputs/outputs as if nothing happens  ?


>         PR 30724
>         * bfd.c (enum bfd_last_io): New.
>         (struct bfd): Add last_io field.
>         * bfd-in2.h: Regenerate.
>         * bfd-io.c (bfd_bread, bfd_bwrite): Force seek if last_io is
>         opposite direction.
>         (bfd_seek): Reinstate optimisation for seek to same position.
>
> diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
> index 5f49807d7f2..cc62ab19617 100644
> --- a/bfd/bfd-in2.h
> +++ b/bfd/bfd-in2.h
> @@ -1916,6 +1916,14 @@ enum bfd_direction
>      both_direction = 3
>    };
>
> +enum bfd_last_io
> +  {
> +    bfd_io_seek = 0,
> +    bfd_io_read = 1,
> +    bfd_io_write = 2,
> +    bfd_io_force = 3
> +  };
> +
>  enum bfd_plugin_format
>    {
>      bfd_plugin_unknown = 0,
> @@ -2068,6 +2076,20 @@ struct bfd
>    /* The direction with which the BFD was opened.  */
>    ENUM_BITFIELD (bfd_direction) direction : 2;
>
> +  /* POSIX.1-2017 (IEEE Std 1003.1) says of fopen : "When a file is
> +     opened with update mode ('+' as the second or third character in
> +     the mode argument), both input and output may be performed on
> +     the associated stream.  However, the application shall ensure
> +     that output is not directly followed by input without an
> +     intervening call to fflush() or to a file positioning function
> +     (fseek(), fsetpos(), or rewind()), and input is not directly
> +     followed by output without an intervening call to a file
> +     positioning function, unless the input operation encounters
> +     end-of-file."
> +     This field tracks the last IO operation, so that bfd can insert
> +     a seek when IO direction changes.  */
> +  ENUM_BITFIELD (bfd_last_io) last_io : 2;
> +
>    /* Is the file descriptor being cached?  That is, can it be closed as
>       needed, and re-opened when accessed later?  */
>    unsigned int cacheable : 1;
> diff --git a/bfd/bfd.c b/bfd/bfd.c
> index e43a388ac72..88943a042d6 100644
> --- a/bfd/bfd.c
> +++ b/bfd/bfd.c
> @@ -53,6 +53,14 @@ EXTERNAL
>  .    both_direction = 3
>  .  };
>  .
> +.enum bfd_last_io
> +.  {
> +.    bfd_io_seek = 0,
> +.    bfd_io_read = 1,
> +.    bfd_io_write = 2,
> +.    bfd_io_force = 3
> +.  };
> +.
>  .enum bfd_plugin_format
>  .  {
>  .    bfd_plugin_unknown = 0,
> @@ -208,6 +216,20 @@ CODE_FRAGMENT
>  .  {* The direction with which the BFD was opened.  *}
>  .  ENUM_BITFIELD (bfd_direction) direction : 2;
>  .
> +.  {* POSIX.1-2017 (IEEE Std 1003.1) says of fopen : "When a file is
> +.     opened with update mode ('+' as the second or third character in
> +.     the mode argument), both input and output may be performed on
> +.     the associated stream.  However, the application shall ensure
> +.     that output is not directly followed by input without an
> +.     intervening call to fflush() or to a file positioning function
> +.     (fseek(), fsetpos(), or rewind()), and input is not directly
> +.     followed by output without an intervening call to a file
> +.     positioning function, unless the input operation encounters
> +.     end-of-file."
> +.     This field tracks the last IO operation, so that bfd can insert
> +.     a seek when IO direction changes.  *}
> +.  ENUM_BITFIELD (bfd_last_io) last_io : 2;
> +.
>  .  {* Is the file descriptor being cached?  That is, can it be closed as
>  .     needed, and re-opened when accessed later?  *}
>  .  unsigned int cacheable : 1;
> diff --git a/bfd/bfdio.c b/bfd/bfdio.c
> index 22c39a7b0cc..e0d47b3ee1c 100644
> --- a/bfd/bfdio.c
> +++ b/bfd/bfdio.c
> @@ -279,6 +279,14 @@ bfd_bread (void *ptr, bfd_size_type size, bfd *abfd)
>        return -1;
>      }
>
> +  if (abfd->last_io == bfd_io_write)
> +    {
> +      abfd->last_io = bfd_io_force;
> +      if (bfd_seek (abfd, 0, SEEK_CUR) != 0)
> +       return -1;
> +    }
> +  abfd->last_io = bfd_io_read;
> +
>    nread = abfd->iovec->bread (abfd, ptr, size);
>    if (nread != -1)
>      abfd->where += nread;
> @@ -313,6 +321,14 @@ bfd_bwrite (const void *ptr, bfd_size_type size, bfd *abfd)
>        return -1;
>      }
>
> +  if (abfd->last_io == bfd_io_read)
> +    {
> +      abfd->last_io = bfd_io_force;
> +      if (bfd_seek (abfd, 0, SEEK_CUR) != 0)
> +       return -1;
> +    }
> +  abfd->last_io = bfd_io_write;
> +
>    nwrote = abfd->iovec->bwrite (abfd, ptr, size);
>    if (nwrote != -1)
>      abfd->where += nwrote;
> @@ -456,6 +472,13 @@ bfd_seek (bfd *abfd, file_ptr position, int direction)
>    if (direction != SEEK_CUR)
>      position += offset;
>
> +  if (((direction == SEEK_CUR && position == 0)
> +       || (direction == SEEK_SET && (ufile_ptr) position == abfd->where))
> +      && abfd->last_io != bfd_io_force)
> +    return 0;
> +
> +  abfd->last_io = bfd_io_seek;
> +
>    result = abfd->iovec->bseek (abfd, position, direction);
>    if (result != 0)
>      {
>
> --
> Alan Modra
> Australia Development Lab, IBM

  reply	other threads:[~2023-08-09 14:43 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-08-08 23:21 Alan Modra
2023-08-09 14:42 ` Clément Chigot [this message]
2023-08-09 22:21   ` Alan Modra

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=CAJ307EhaA4SnO+JaxWeYoO6mCmkUAEGdLQ+OEbB3X6kDMSD3ew@mail.gmail.com \
    --to=chigot@adacore.com \
    --cc=amodra@gmail.com \
    --cc=binutils@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).