diff options
author | jb <jb@138bc75d-0d04-0410-961f-82ee72b054a4> | 2011-11-09 15:46:15 +0000 |
---|---|---|
committer | jb <jb@138bc75d-0d04-0410-961f-82ee72b054a4> | 2011-11-09 15:46:15 +0000 |
commit | 16b1d20fe3e61ea1bcf65909c9f92478f5234bdd (patch) | |
tree | 4142f4ba491843be305a43bdb525fc03d316eb91 | |
parent | 094f84b512a0f7840d0a10aa26bf78b40b09b742 (diff) | |
download | gcc-16b1d20fe3e61ea1bcf65909c9f92478f5234bdd.tar.gz |
PR 50016 Slow I/O on MingW due to _commit
frontend ChangeLog:
2011-11-09 Janne Blomqvist <jb@gcc.gnu.org>
PR libfortran/50016
* gfortran.texi (Data consistency and durability): New section.
testsuite ChangeLog:
2011-11-09 Janne Blomqvist <jb@gcc.gnu.org>
PR libfortran/50016
* gfortran.dg/inquire_size.f90: Don't flush the unit.
libgfortran ChangeLog:
2011-11-09 Janne Blomqvist <jb@gcc.gnu.org>
PR libfortran/50016
* io/inquire.c (inquire_via_unit): Flush the unit and use ssize.
* io/unix.c (buf_flush): Don't call _commit.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@181207 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r-- | gcc/fortran/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/fortran/gfortran.texi | 76 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gfortran.dg/inquire_size.f90 | 4 | ||||
-rw-r--r-- | libgfortran/ChangeLog | 6 | ||||
-rw-r--r-- | libgfortran/io/inquire.c | 5 | ||||
-rw-r--r-- | libgfortran/io/unix.c | 4 |
7 files changed, 99 insertions, 6 deletions
diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index 6d7c35b1fe1..019680dfa1a 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,8 @@ +2011-11-09 Janne Blomqvist <jb@gcc.gnu.org> + + PR libfortran/50016 + * gfortran.texi (Data consistency and durability): New section. + 2011-11-09 Francois-Xavier Coudert <fxcoudert@gcc.gnu.org> PR fortran/50540 diff --git a/gcc/fortran/gfortran.texi b/gcc/fortran/gfortran.texi index 6a1c92b8da5..aac2d908b02 100644 --- a/gcc/fortran/gfortran.texi +++ b/gcc/fortran/gfortran.texi @@ -1090,6 +1090,7 @@ might in some way or another become visible to the programmer. * KIND Type Parameters:: * Internal representation of LOGICAL variables:: * Thread-safety of the runtime library:: +* Data consistency and durability:: @end menu @@ -1194,6 +1195,81 @@ Finally, for platforms not supporting thread-safe POSIX functions, further functionality might not be thread-safe. For details, please consult the documentation for your operating system. + +@node Data consistency and durability +@section Data consistency and durability +@cindex consistency, durability + +This section contains a brief overview of data and metadata +consistency and durability issues when doing I/O. + +With respect to durability, GNU Fortran makes no effort to ensure that +data is committed to stable storage. If this is required, the GNU +Fortran programmer can use the intrinsic @code{FNUM} to retrieve the +low level file descriptor corresponding to an open Fortran unit. Then, +using e.g. the @code{ISO_C_BINDING} feature, one can call the +underlying system call to flush dirty data to stable storage, such as +@code{fsync} on POSIX, @code{_commit} on MingW, or @code{fcntl(fd, +F_FULLSYNC, 0)} on Mac OS X. The following example shows how to call +fsync: + +@smallexample + ! Declare the interface for POSIX fsync function + interface + function fsync (fd) bind(c,name="fsync") + use iso_c_binding, only: c_int + integer(c_int), value :: fd + integer(c_int) :: fsync + end function fsync + end interface + + ! Variable declaration + integer :: ret + + ! Opening unit 10 + open (10,file="foo") + + ! ... + ! Perform I/O on unit 10 + ! ... + + ! Flush and sync + flush(10) + ret = fsync(fnum(10)) + + ! Handle possible error + if (ret /= 0) stop "Error calling FSYNC" +@end smallexample + +With respect to consistency, for regular files GNU Fortran uses +buffered I/O in order to improve performance. This buffer is flushed +automatically when full and in some other situations, e.g. when +closing a unit. It can also be explicitly flushed with the +@code{FLUSH} statement. Also, the buffering can be turned off with the +@code{GFORTRAN_UNBUFFERED_ALL} and +@code{GFORTRAN_UNBUFFERED_PRECONNECTED} environment variables. Special +files, such as terminals and pipes, are always unbuffered. Sometimes, +however, further things may need to be done in order to allow other +processes to see data that GNU Fortran has written, as follows. + +The Windows platform supports a relaxed metadata consistency model, +where file metadata is written to the directory lazily. This means +that, for instance, the @code{dir} command can show a stale size for a +file. One can force a directory metadata update by closing the unit, +or by calling @code{_commit} on the file descriptor. Note, though, +that @code{_commit} will force all dirty data to stable storage, which +is often a very slow operation. + +The Network File System (NFS) implements a relaxed consistency model +called open-to-close consistency. Closing a file forces dirty data and +metadata to be flushed to the server, and opening a file forces the +client to contact the server in order to revalidate cached +data. @code{fsync} will also force a flush of dirty data and metadata +to the server. Similar to @code{open} and @code{close}, acquiring and +releasing @code{fcntl} file locks, if the server supports them, will +also force cache validation and flushing dirty data and metadata. + + @c --------------------------------------------------------------------- @c Extensions @c --------------------------------------------------------------------- diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 2d4a6aab212..a0eeb32136a 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2011-11-09 Janne Blomqvist <jb@gcc.gnu.org> + + PR libfortran/50016 + * gfortran.dg/inquire_size.f90: Don't flush the unit. + 2011-11-09 Richard Guenther <rguenther@suse.de> PR tree-optimization/51039 diff --git a/gcc/testsuite/gfortran.dg/inquire_size.f90 b/gcc/testsuite/gfortran.dg/inquire_size.f90 index 568c3d6a0f3..13876cfb7fd 100644 --- a/gcc/testsuite/gfortran.dg/inquire_size.f90 +++ b/gcc/testsuite/gfortran.dg/inquire_size.f90 @@ -8,7 +8,9 @@ open(25, file="testfile", status="replace", access="stream", form="unformatted") do i=1,100 write(25) i, "abcdefghijklmnopqrstuvwxyz" enddo -flush(25) +! Gfortran implicitly flushes the buffer when doing a file size +! inquire on an open file. +! flush(25) inquire(unit=25, named=is_named, name=aname, size=i) if (.not.is_named) call abort diff --git a/libgfortran/ChangeLog b/libgfortran/ChangeLog index 3a2db6dd50c..d9d397bc1e0 100644 --- a/libgfortran/ChangeLog +++ b/libgfortran/ChangeLog @@ -1,3 +1,9 @@ +2011-11-09 Janne Blomqvist <jb@gcc.gnu.org> + + PR libfortran/50016 + * io/inquire.c (inquire_via_unit): Flush the unit and use ssize. + * io/unix.c (buf_flush): Don't call _commit. + 2011-11-08 Francois-Xavier Coudert <fxcoudert@gcc.gnu.org> PR libfortran/47972 diff --git a/libgfortran/io/inquire.c b/libgfortran/io/inquire.c index fb525caf863..a5423346db9 100644 --- a/libgfortran/io/inquire.c +++ b/libgfortran/io/inquire.c @@ -409,7 +409,10 @@ inquire_via_unit (st_parameter_inquire *iqp, gfc_unit * u) if (u == NULL) *iqp->size = -1; else - *iqp->size = file_size (u->file, (gfc_charlen_type) u->file_len); + { + sflush (u->s); + *iqp->size = ssize (u->s); + } } } diff --git a/libgfortran/io/unix.c b/libgfortran/io/unix.c index c87be134a69..f320733e859 100644 --- a/libgfortran/io/unix.c +++ b/libgfortran/io/unix.c @@ -451,10 +451,6 @@ buf_flush (unix_stream * s) if (s->ndirty != 0) return -1; -#ifdef _WIN32 - _commit (s->fd); -#endif - return 0; } |