From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 1062) id 758973858D20; Fri, 11 Aug 2023 03:33:46 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 758973858D20 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable From: Alan Modra To: bfd-cvs@sourceware.org Subject: [binutils-gdb/binutils-2_41-branch] PR30724, cygwin ld performance regression since 014a602b86 X-Act-Checkin: binutils-gdb X-Git-Author: Alan Modra X-Git-Refname: refs/heads/binutils-2_41-branch X-Git-Oldrev: ef1101524660146df9ea2fcb0b63c0a261af427b X-Git-Newrev: 226f2e6b924612ecbdb7dfe4f3ca611116ed77f4 Message-Id: <20230811033346.758973858D20@sourceware.org> Date: Fri, 11 Aug 2023 03:33:46 +0000 (GMT) X-BeenThere: binutils-cvs@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Binutils-cvs mailing list List-Unsubscribe: , List-Archive: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 11 Aug 2023 03:33:46 -0000 https://sourceware.org/git/gitweb.cgi?p=3Dbinutils-gdb.git;h=3D226f2e6b9246= 12ecbdb7dfe4f3ca611116ed77f4 commit 226f2e6b924612ecbdb7dfe4f3ca611116ed77f4 Author: Alan Modra Date: Mon Aug 7 08:28:55 2023 +0930 PR30724, cygwin ld performance regression since 014a602b86 =20 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. =20 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. =20 (cherry picked from commit f82ee0c8dc4ee32556e23e6cd83ef083618f704f) Diff: --- bfd/bfd-in2.h | 22 ++++++++++++++++++++++ bfd/bfd.c | 22 ++++++++++++++++++++++ bfd/bfdio.c | 23 +++++++++++++++++++++++ 3 files changed, 67 insertions(+) diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h index b34c8ef9fc9..4128972fe49 100644 --- a/bfd/bfd-in2.h +++ b/bfd/bfd-in2.h @@ -1913,6 +1913,14 @@ enum bfd_direction both_direction =3D 3 }; =20 +enum bfd_last_io + { + bfd_io_seek =3D 0, + bfd_io_read =3D 1, + bfd_io_write =3D 2, + bfd_io_force =3D 3 + }; + enum bfd_plugin_format { bfd_plugin_unknown =3D 0, @@ -2065,6 +2073,20 @@ struct bfd /* The direction with which the BFD was opened. */ ENUM_BITFIELD (bfd_direction) direction : 2; =20 + /* 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 =3D 3 . }; . +.enum bfd_last_io +. { +. bfd_io_seek =3D 0, +. bfd_io_read =3D 1, +. bfd_io_write =3D 2, +. bfd_io_force =3D 3 +. }; +. .enum bfd_plugin_format . { . bfd_plugin_unknown =3D 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; } =20 + if (abfd->last_io =3D=3D bfd_io_write) + { + abfd->last_io =3D bfd_io_force; + if (bfd_seek (abfd, 0, SEEK_CUR) !=3D 0) + return -1; + } + abfd->last_io =3D bfd_io_read; + nread =3D abfd->iovec->bread (abfd, ptr, size); if (nread !=3D -1) abfd->where +=3D nread; @@ -313,6 +321,14 @@ bfd_bwrite (const void *ptr, bfd_size_type size, bfd *= abfd) return -1; } =20 + if (abfd->last_io =3D=3D bfd_io_read) + { + abfd->last_io =3D bfd_io_force; + if (bfd_seek (abfd, 0, SEEK_CUR) !=3D 0) + return -1; + } + abfd->last_io =3D bfd_io_write; + nwrote =3D abfd->iovec->bwrite (abfd, ptr, size); if (nwrote !=3D -1) abfd->where +=3D nwrote; @@ -456,6 +472,13 @@ bfd_seek (bfd *abfd, file_ptr position, int direction) if (direction !=3D SEEK_CUR) position +=3D offset; =20 + if (((direction =3D=3D SEEK_CUR && position =3D=3D 0) + || (direction =3D=3D SEEK_SET && (ufile_ptr) position =3D=3D abfd->= where)) + && abfd->last_io !=3D bfd_io_force) + return 0; + + abfd->last_io =3D bfd_io_seek; + result =3D abfd->iovec->bseek (abfd, position, direction); if (result !=3D 0) {