PR 56981 Flush buffer at record boundary if possible.
authorJanne Blomqvist <jb@gcc.gnu.org>
Sun, 8 Jun 2014 05:43:29 +0000 (08:43 +0300)
committerJanne Blomqvist <jb@gcc.gnu.org>
Sun, 8 Jun 2014 05:43:29 +0000 (08:43 +0300)
2014-06-08  Janne Blomqvist  <jb@gcc.gnu.org>

PR libfortran/56981
* io/unix.h (struct stream_vtable): Add new member function,
markeor.
(smarkeor): New inline function.
(flush_if_unbuffered): Remove prototype.
* io/unix.c (raw_markeor): New function.
(raw_vtable): Initialize markeor member.
(buf_markeor): New function.
(buf_vtable): Initialize markeor member.
(mem_vtable): Likewise.
(mem4_vtable): Likewise.
(flush_if_unbuffered): Remove function.
* io/transfer.c (next_record): Call smarkeor instead of
flush_if_unbuffered.

From-SVN: r211353

libgfortran/ChangeLog
libgfortran/io/transfer.c
libgfortran/io/unix.c
libgfortran/io/unix.h

index 5f9ddaf..9d75329 100644 (file)
@@ -1,3 +1,20 @@
+2014-06-08  Janne Blomqvist  <jb@gcc.gnu.org>
+
+       PR libfortran/56981
+       * io/unix.h (struct stream_vtable): Add new member function,
+       markeor.
+       (smarkeor): New inline function.
+       (flush_if_unbuffered): Remove prototype.
+       * io/unix.c (raw_markeor): New function.
+       (raw_vtable): Initialize markeor member.
+       (buf_markeor): New function.
+       (buf_vtable): Initialize markeor member.
+       (mem_vtable): Likewise.
+       (mem4_vtable): Likewise.
+       (flush_if_unbuffered): Remove function.
+       * io/transfer.c (next_record): Call smarkeor instead of
+       flush_if_unbuffered.
+
 2014-05-27  Uros Bizjak  <ubizjak@gmail.com>
 
        * intrinsics/getcwd.c: Include stdlib.h.
index cfe92ca..cc0132c 100644 (file)
@@ -3512,7 +3512,7 @@ next_record (st_parameter_dt *dtp, int done)
     pre_position (dtp);
 
   fbuf_flush (dtp->u.p.current_unit, dtp->u.p.mode);
-  flush_if_unbuffered (dtp->u.p.current_unit->s);
+  smarkeor (dtp->u.p.current_unit->s);
 }
 
 
index 3721b71..c9866d3 100644 (file)
@@ -421,6 +421,12 @@ raw_close (unix_stream * s)
   return retval;
 }
 
+static int
+raw_markeor (unix_stream * s __attribute__ ((unused)))
+{
+  return 0;
+}
+
 static const struct stream_vtable raw_vtable = {
   .read = (void *) raw_read,
   .write = (void *) raw_write,
@@ -429,7 +435,8 @@ static const struct stream_vtable raw_vtable = {
   .size = (void *) raw_size,
   .trunc = (void *) raw_truncate,
   .close = (void *) raw_close,
-  .flush = (void *) raw_flush 
+  .flush = (void *) raw_flush,
+  .markeor = (void *) raw_markeor
 };
 
 static int
@@ -584,6 +591,23 @@ buf_write (unix_stream * s, const void * buf, ssize_t nbyte)
   return nbyte;
 }
 
+
+/* "Unbuffered" really means I/O statement buffering. For formatted
+   I/O, the fbuf manages this, and then uses raw I/O. For unformatted
+   I/O, buffered I/O is used, and the buffer is flushed at the end of
+   each I/O statement, where this function is called.  Alternatively,
+   the buffer is flushed at the end of the record if the buffer is
+   more than half full; this prevents needless seeking back and forth
+   when writing sequential unformatted.  */
+
+static int
+buf_markeor (unix_stream * s)
+{
+  if (s->unbuffered || s->ndirty >= BUFFER_SIZE / 2)
+    return buf_flush (s);
+  return 0;
+}
+
 static gfc_offset
 buf_seek (unix_stream * s, gfc_offset offset, int whence)
 {
@@ -651,7 +675,8 @@ static const struct stream_vtable buf_vtable = {
   .size = (void *) buf_size,
   .trunc = (void *) buf_truncate,
   .close = (void *) buf_close,
-  .flush = (void *) buf_flush 
+  .flush = (void *) buf_flush,
+  .markeor = (void *) buf_markeor
 };
 
 static int
@@ -910,7 +935,8 @@ static const struct stream_vtable mem_vtable = {
   .size = (void *) buf_size,
   .trunc = (void *) mem_truncate,
   .close = (void *) mem_close,
-  .flush = (void *) mem_flush 
+  .flush = (void *) mem_flush,
+  .markeor = (void *) raw_markeor
 };
 
 static const struct stream_vtable mem4_vtable = {
@@ -923,7 +949,8 @@ static const struct stream_vtable mem4_vtable = {
   .size = (void *) buf_size,
   .trunc = (void *) mem_truncate,
   .close = (void *) mem_close,
-  .flush = (void *) mem_flush 
+  .flush = (void *) mem_flush,
+  .markeor = (void *) raw_markeor
 };
 
 /*********************************************************************
@@ -972,21 +999,6 @@ open_internal4 (char *base, int length, gfc_offset offset)
 }
 
 
-/* "Unbuffered" really means I/O statement buffering. For formatted
-   I/O, the fbuf manages this, and then uses raw I/O. For unformatted
-   I/O, buffered I/O is used, and the buffer is flushed at the end of
-   each I/O statement, where this function is called.  */
-
-int
-flush_if_unbuffered (stream* s)
-{
-  unix_stream* us = (unix_stream*) s;
-  if (us->unbuffered)
-    return sflush (s);
-  return 0;
-}
-
-
 /* fd_to_stream()-- Given an open file descriptor, build a stream
  * around it. */
 
index 910f2c2..0f696df 100644 (file)
@@ -38,6 +38,7 @@ struct stream_vtable
   int (* const trunc) (struct stream *, gfc_offset);
   int (* const flush) (struct stream *);
   int (* const close) (struct stream *);
+  int (* const markeor) (struct stream *);
 };
 
 struct stream
@@ -94,6 +95,12 @@ sclose (stream * s)
   return s->vptr->close (s);
 }
 
+static inline int
+smarkeor (stream * s)
+{
+  return s->vptr->markeor (s);
+}
+
 
 extern int compare_files (stream *, stream *);
 internal_proto(compare_files);
@@ -167,9 +174,6 @@ internal_proto(inquire_readwrite);
 extern void flush_if_preconnected (stream *);
 internal_proto(flush_if_preconnected);
 
-extern int flush_if_unbuffered (stream*);
-internal_proto(flush_if_unbuffered);
-
 extern int stream_isatty (stream *);
 internal_proto(stream_isatty);