diff options
author | Janne Blomqvist <jb@gcc.gnu.org> | 2011-10-19 20:27:03 +0300 |
---|---|---|
committer | Tobias Burnus <burnus@gcc.gnu.org> | 2011-10-19 19:27:03 +0200 |
commit | 5a46934217d80f8771a5d0297071750ce8d7f6a2 (patch) | |
tree | 2c0e99a5eb0de5b2015cc25717fdce1db477fdd2 /libgfortran | |
parent | 4f1c9a3f487eeda9d33ea47001b81dddbd8266fc (diff) | |
download | gcc-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/ChangeLog | 13 | ||||
-rw-r--r-- | libgfortran/io/file_pos.c | 6 | ||||
-rw-r--r-- | libgfortran/io/intrinsics.c | 14 | ||||
-rw-r--r-- | libgfortran/io/unix.c | 33 | ||||
-rw-r--r-- | libgfortran/io/unix.h | 3 |
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); |