aboutsummaryrefslogtreecommitdiff
path: root/libgfortran/io/unix.c
diff options
context:
space:
mode:
authorJanne Blomqvist <jb@gcc.gnu.org>2013-04-29 11:42:00 +0300
committerJanne Blomqvist <jb@gcc.gnu.org>2013-04-29 11:42:00 +0300
commitc033f5ae3270e34c40c7ef9e7168b9884e39b75a (patch)
tree3b1ca6b7cea4c26f9fb00330df1afd202ff6a6cb /libgfortran/io/unix.c
parent94dc53320e6c22ef0d3f8d8db83c2492de001f5b (diff)
downloadgcc-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.c39
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;
}