diff options
author | Janne Blomqvist <jb@gcc.gnu.org> | 2014-06-08 08:43:29 +0300 |
---|---|---|
committer | Janne Blomqvist <jb@gcc.gnu.org> | 2014-06-08 08:43:29 +0300 |
commit | 89a862b40a387ef42618176addf192b33c556f7d (patch) | |
tree | ce7c2693e80de90ba4a312ca3616c556a673856e /libgfortran/io | |
parent | 136a5f4548a68455967a2f4b9eab4b3f78fff6d3 (diff) | |
download | gcc-89a862b40a387ef42618176addf192b33c556f7d.zip gcc-89a862b40a387ef42618176addf192b33c556f7d.tar.gz gcc-89a862b40a387ef42618176addf192b33c556f7d.tar.bz2 |
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/io')
-rw-r--r-- | libgfortran/io/transfer.c | 2 | ||||
-rw-r--r-- | libgfortran/io/unix.c | 50 | ||||
-rw-r--r-- | libgfortran/io/unix.h | 10 |
3 files changed, 39 insertions, 23 deletions
diff --git a/libgfortran/io/transfer.c b/libgfortran/io/transfer.c index cfe92ca..cc0132c8 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 3721b71..c9866d3 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 910f2c2..0f696df 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); |