mirror of
https://github.com/crosstool-ng/crosstool-ng.git
synced 2025-01-18 02:39:46 +00:00
binutils: Bring in upstream performance fix
Bring in an upstream fix for a performance issue in the 2.41 release. Signed-off-by: Chris Packham <judge.packham@gmail.com>
This commit is contained in:
parent
d5694c660f
commit
4a2a9c3699
156
packages/binutils/2.41/0008-PR30724-cygwin-ld-performance-regression-since-014a6.patch
vendored
Normal file
156
packages/binutils/2.41/0008-PR30724-cygwin-ld-performance-regression-since-014a6.patch
vendored
Normal file
@ -0,0 +1,156 @@
|
||||
From 226f2e6b924612ecbdb7dfe4f3ca611116ed77f4 Mon Sep 17 00:00:00 2001
|
||||
From: Alan Modra <amodra@gmail.com>
|
||||
Date: Mon, 7 Aug 2023 08:28:55 +0930
|
||||
Subject: [PATCH] PR30724, cygwin ld performance regression since 014a602b86
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
(cherry picked from commit f82ee0c8dc4ee32556e23e6cd83ef083618f704f)
|
||||
---
|
||||
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 = 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,
|
||||
@@ -2065,6 +2073,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)
|
||||
{
|
||||
--
|
||||
2.43.0
|
||||
|
Loading…
Reference in New Issue
Block a user