summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjb <jb@138bc75d-0d04-0410-961f-82ee72b054a4>2011-11-09 15:46:15 +0000
committerjb <jb@138bc75d-0d04-0410-961f-82ee72b054a4>2011-11-09 15:46:15 +0000
commit16b1d20fe3e61ea1bcf65909c9f92478f5234bdd (patch)
tree4142f4ba491843be305a43bdb525fc03d316eb91
parent094f84b512a0f7840d0a10aa26bf78b40b09b742 (diff)
downloadgcc-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/ChangeLog5
-rw-r--r--gcc/fortran/gfortran.texi76
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gfortran.dg/inquire_size.f904
-rw-r--r--libgfortran/ChangeLog6
-rw-r--r--libgfortran/io/inquire.c5
-rw-r--r--libgfortran/io/unix.c4
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;
}