summaryrefslogtreecommitdiff
path: root/libgfortran
diff options
context:
space:
mode:
authorJanne Blomqvist <jb@gcc.gnu.org>2014-06-08 08:43:29 +0300
committerJanne Blomqvist <jb@gcc.gnu.org>2014-06-08 08:43:29 +0300
commit89a862b40a387ef42618176addf192b33c556f7d (patch)
treece7c2693e80de90ba4a312ca3616c556a673856e /libgfortran
parent136a5f4548a68455967a2f4b9eab4b3f78fff6d3 (diff)
downloadgcc-89a862b40a387ef42618176addf192b33c556f7d.tar.gz
PR 56981 Flush buffer at record boundary if possible.
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
Diffstat (limited to 'libgfortran')
-rw-r--r--libgfortran/ChangeLog17
-rw-r--r--libgfortran/io/transfer.c2
-rw-r--r--libgfortran/io/unix.c50
-rw-r--r--libgfortran/io/unix.h10
4 files changed, 56 insertions, 23 deletions
diff --git a/libgfortran/ChangeLog b/libgfortran/ChangeLog
index 5f9ddaf668f..9d753296445 100644
--- a/libgfortran/ChangeLog
+++ b/libgfortran/ChangeLog
@@ -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.
diff --git a/libgfortran/io/transfer.c b/libgfortran/io/transfer.c
index cfe92ca0655..cc0132c80f7 100644
--- a/libgfortran/io/transfer.c
+++ b/libgfortran/io/transfer.c
@@ -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);
}
diff --git a/libgfortran/io/unix.c b/libgfortran/io/unix.c
index 3721b71f994..c9866d3495a 100644
--- a/libgfortran/io/unix.c
+++ b/libgfortran/io/unix.c
@@ -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. */
diff --git a/libgfortran/io/unix.h b/libgfortran/io/unix.h
index 910f2c2e650..0f696df5dac 100644
--- a/libgfortran/io/unix.h
+++ b/libgfortran/io/unix.h
@@ -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);