aboutsummaryrefslogtreecommitdiff
path: root/libgfortran
diff options
context:
space:
mode:
authorJanne Blomqvist <jb@gcc.gnu.org>2011-10-19 20:27:03 +0300
committerTobias Burnus <burnus@gcc.gnu.org>2011-10-19 19:27:03 +0200
commit5a46934217d80f8771a5d0297071750ce8d7f6a2 (patch)
tree2c0e99a5eb0de5b2015cc25717fdce1db477fdd2 /libgfortran
parent4f1c9a3f487eeda9d33ea47001b81dddbd8266fc (diff)
downloadgcc-5a46934217d80f8771a5d0297071750ce8d7f6a2.zip
gcc-5a46934217d80f8771a5d0297071750ce8d7f6a2.tar.gz
gcc-5a46934217d80f8771a5d0297071750ce8d7f6a2.tar.bz2
re PR libfortran/50016 (Drastic I/O performance regression on Windows)
2011-10-19 Janne Blomqvist <jb@gcc.gnu.org> Kai Tietz <ktietz@redhat.com> Tobias Burnus <burnus@net-b.de> PR fortran/50016 * io/unix.h (flush_sync): Add new libgfortran-internal * prototype. * io/unix.c (flush_sync): New function, which calls sflush and on MinGW(-w64) also _commit. (flush_all_units, flush_all_units_1): Replace sflush/_commit by flush_sync. * io/file_pos.c (st_flush): Replace sflush/_commit by * flush_sync. * io/intrinsics.c (flush_i4, flush_i8): Ditto. Co-Authored-By: Kai Tietz <ktietz@redhat.com> Co-Authored-By: Tobias Burnus <burnus@net-b.de> From-SVN: r180199
Diffstat (limited to 'libgfortran')
-rw-r--r--libgfortran/ChangeLog13
-rw-r--r--libgfortran/io/file_pos.c6
-rw-r--r--libgfortran/io/intrinsics.c14
-rw-r--r--libgfortran/io/unix.c33
-rw-r--r--libgfortran/io/unix.h3
5 files changed, 38 insertions, 31 deletions
diff --git a/libgfortran/ChangeLog b/libgfortran/ChangeLog
index 55a7370..916887b 100644
--- a/libgfortran/ChangeLog
+++ b/libgfortran/ChangeLog
@@ -1,3 +1,16 @@
+2011-10-19 Janne Blomqvist <jb@gcc.gnu.org>
+ Kai Tietz <ktietz@redhat.com>
+ Tobias Burnus <burnus@net-b.de>
+
+ PR fortran/50016
+ * io/unix.h (flush_sync): Add new libgfortran-internal prototype.
+ * io/unix.c (flush_sync): New function, which calls sflush and
+ on MinGW(-w64) also _commit.
+ (flush_all_units, flush_all_units_1): Replace sflush/_commit by
+ flush_sync.
+ * io/file_pos.c (st_flush): Replace sflush/_commit by flush_sync.
+ * io/intrinsics.c (flush_i4, flush_i8): Ditto.
+
2011-10-18 Tobias Burnus <burnus@net-b.de>
Janne Blomqvist <jb@gcc.gnu.org>
diff --git a/libgfortran/io/file_pos.c b/libgfortran/io/file_pos.c
index 4efdc1f..da83aa5 100644
--- a/libgfortran/io/file_pos.c
+++ b/libgfortran/io/file_pos.c
@@ -451,11 +451,7 @@ st_flush (st_parameter_filepos *fpp)
if (u->flags.form == FORM_FORMATTED)
fbuf_flush (u, u->mode);
- sflush (u->s);
-#ifdef _WIN32
- /* Without _commit, changes are not visible to other file descriptors. */
- _commit (u->s->fd);
-#endif
+ flush_sync (u->s);
unlock_unit (u);
}
else
diff --git a/libgfortran/io/intrinsics.c b/libgfortran/io/intrinsics.c
index eaf2e17..2d00a66 100644
--- a/libgfortran/io/intrinsics.c
+++ b/libgfortran/io/intrinsics.c
@@ -206,12 +206,7 @@ flush_i4 (GFC_INTEGER_4 *unit)
us = find_unit (*unit);
if (us != NULL)
{
- sflush (us->s);
-#ifdef _WIN32
- /* Without _commit, changes are not visible
- to other file descriptors. */
- _commit (u->s->fd);
-#endif
+ flush_sync (us->s);
unlock_unit (us);
}
}
@@ -234,12 +229,7 @@ flush_i8 (GFC_INTEGER_8 *unit)
us = find_unit (*unit);
if (us != NULL)
{
- sflush (us->s);
-#ifdef _WIN32
- /* Without _commit, changes are not visible
- to other file descriptors. */
- _commit (u->s->fd);
-#endif
+ flush_sync (us->s);
unlock_unit (us);
}
}
diff --git a/libgfortran/io/unix.c b/libgfortran/io/unix.c
index 79bb9e9..26bb06a 100644
--- a/libgfortran/io/unix.c
+++ b/libgfortran/io/unix.c
@@ -1522,6 +1522,23 @@ retry:
return u;
}
+
+/* Flush dirty data, making sure that OS metadata is updated as
+ well. Note that this is VERY slow on mingw due to committing data
+ to stable storage. */
+int
+flush_sync (stream * s)
+{
+ if (sflush (s) == -1)
+ return -1;
+#ifdef __MINGW32__
+ if (_commit (((unix_stream *)s)->fd) == -1)
+ return -1;
+#endif
+ return 0;
+}
+
+
static gfc_unit *
flush_all_units_1 (gfc_unit *u, int min_unit)
{
@@ -1538,14 +1555,7 @@ flush_all_units_1 (gfc_unit *u, int min_unit)
if (__gthread_mutex_trylock (&u->lock))
return u;
if (u->s)
- {
- sflush (u->s);
-#ifdef _WIN32
- /* Without _commit, changes are not visible to other
- file descriptors. */
- _commit (u->s->fd);
-#endif
- }
+ flush_sync (u->s);
__gthread_mutex_unlock (&u->lock);
}
u = u->right;
@@ -1575,12 +1585,7 @@ flush_all_units (void)
if (u->closed == 0)
{
- sflush (u->s);
-#ifdef _WIN32
- /* Without _commit, changes are not visible to other
- file descriptors. */
- _commit (u->s->fd);
-#endif
+ flush_sync (u->s);
__gthread_mutex_lock (&unit_lock);
__gthread_mutex_unlock (&u->lock);
(void) predec_waiting_locked (u);
diff --git a/libgfortran/io/unix.h b/libgfortran/io/unix.h
index f7d6f08..5e42268 100644
--- a/libgfortran/io/unix.h
+++ b/libgfortran/io/unix.h
@@ -167,6 +167,9 @@ internal_proto(is_special);
extern void flush_if_preconnected (stream *);
internal_proto(flush_if_preconnected);
+extern int flush_sync (stream *);
+internal_proto(flush_sync);
+
extern int stream_isatty (stream *);
internal_proto(stream_isatty);