diff options
author | Janne Blomqvist <jb@gcc.gnu.org> | 2013-04-29 11:42:00 +0300 |
---|---|---|
committer | Janne Blomqvist <jb@gcc.gnu.org> | 2013-04-29 11:42:00 +0300 |
commit | c033f5ae3270e34c40c7ef9e7168b9884e39b75a (patch) | |
tree | 3b1ca6b7cea4c26f9fb00330df1afd202ff6a6cb /libgfortran/io/unix.c | |
parent | 94dc53320e6c22ef0d3f8d8db83c2492de001f5b (diff) | |
download | gcc-c033f5ae3270e34c40c7ef9e7168b9884e39b75a.zip gcc-c033f5ae3270e34c40c7ef9e7168b9884e39b75a.tar.gz gcc-c033f5ae3270e34c40c7ef9e7168b9884e39b75a.tar.bz2 |
PR 56981 Improve unbuffered performance on special files.
2013-04-29 Janne Blomqvist <jb@gcc.gnu.org>
PR fortran/56981
* io/transfer.c (next_record_w_unf): First fix head marker, then
write tail.
(next_record): Call flush_if_unbuffered.
* io/unix.c (struct unix_stream): Add field unbuffered.
(flush_if_unbuffered): New function.
(fd_to_stream): New argument.
(open_external): Fix fd_to_stream call.
(input_stream): Likewise.
(output_stream): Likewise.
(error_stream): Likewise.
* io/unix.h (flush_if_unbuffered): New prototype.
From-SVN: r198390
Diffstat (limited to 'libgfortran/io/unix.c')
-rw-r--r-- | libgfortran/io/unix.c | 39 |
1 files changed, 32 insertions, 7 deletions
diff --git a/libgfortran/io/unix.c b/libgfortran/io/unix.c index 8b9d7a7..08fe4fe 100644 --- a/libgfortran/io/unix.c +++ b/libgfortran/io/unix.c @@ -212,6 +212,8 @@ typedef struct /* Cached stat(2) values. */ dev_t st_dev; ino_t st_ino; + + bool unbuffered; /* Buffer should be flushed after each I/O statement. */ } unix_stream; @@ -442,7 +444,7 @@ raw_init (unix_stream * s) Buffered I/O functions. These functions have the same semantics as the raw I/O functions above, except that they are buffered in order to improve performance. The buffer must be flushed when switching from -reading to writing and vice versa. Only supported for regular files. +reading to writing and vice versa. *********************************************************************/ static int @@ -968,11 +970,26 @@ 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. */ static stream * -fd_to_stream (int fd) +fd_to_stream (int fd, bool unformatted) { struct stat statbuf; unix_stream *s; @@ -998,7 +1015,15 @@ fd_to_stream (int fd) || s->fd == STDERR_FILENO))) buf_init (s); else - raw_init (s); + { + if (unformatted) + { + s->unbuffered = true; + buf_init (s); + } + else + raw_init (s); + } return (stream *) s; } @@ -1364,7 +1389,7 @@ open_external (st_parameter_open *opp, unit_flags *flags) return NULL; fd = fix_fd (fd); - return fd_to_stream (fd); + return fd_to_stream (fd, flags->form == FORM_UNFORMATTED); } @@ -1374,7 +1399,7 @@ open_external (st_parameter_open *opp, unit_flags *flags) stream * input_stream (void) { - return fd_to_stream (STDIN_FILENO); + return fd_to_stream (STDIN_FILENO, false); } @@ -1390,7 +1415,7 @@ output_stream (void) setmode (STDOUT_FILENO, O_BINARY); #endif - s = fd_to_stream (STDOUT_FILENO); + s = fd_to_stream (STDOUT_FILENO, false); return s; } @@ -1407,7 +1432,7 @@ error_stream (void) setmode (STDERR_FILENO, O_BINARY); #endif - s = fd_to_stream (STDERR_FILENO); + s = fd_to_stream (STDERR_FILENO, false); return s; } |