aboutsummaryrefslogtreecommitdiff
path: root/libgfortran
diff options
context:
space:
mode:
authorJanne Blomqvist <jb@gcc.gnu.org>2010-11-09 20:17:35 +0200
committerJanne Blomqvist <jb@gcc.gnu.org>2010-11-09 20:17:35 +0200
commit7debf73d34ceba203a85b5ad381a5dd799cdc788 (patch)
tree5f46270611def44ed1e538e6693b2f0521a0d22a /libgfortran
parentf4a88680ab308f951699bdfb7b181013d434d151 (diff)
downloadgcc-7debf73d34ceba203a85b5ad381a5dd799cdc788.zip
gcc-7debf73d34ceba203a85b5ad381a5dd799cdc788.tar.gz
gcc-7debf73d34ceba203a85b5ad381a5dd799cdc788.tar.bz2
Cache stat values, reduce syscalls
From-SVN: r166502
Diffstat (limited to 'libgfortran')
-rw-r--r--libgfortran/ChangeLog9
-rw-r--r--libgfortran/io/unix.c53
2 files changed, 44 insertions, 18 deletions
diff --git a/libgfortran/ChangeLog b/libgfortran/ChangeLog
index 8e51190..bfbf015 100644
--- a/libgfortran/ChangeLog
+++ b/libgfortran/ChangeLog
@@ -1,3 +1,12 @@
+2010-11-09 Janne Blomqvist <jb@gcc.gnu.org>
+
+ * io/unix.c (struct unix_stream): Add st_dev and st_ino members.
+ (fd_to_stream): Avoid unnecessary lseek() call, test isatty()
+ last. Make a token effort to support block devices.
+ (compare_file_filename): Use cached stat values.
+ (find_file0): Likewise.
+ (find_file): Likewise.
+
2010-11-09 Jerry DeLisle <jvdelisle@gcc.gnu.org>
PR libgfortran/46373
diff --git a/libgfortran/io/unix.c b/libgfortran/io/unix.c
index e55af18..a384f7b 100644
--- a/libgfortran/io/unix.c
+++ b/libgfortran/io/unix.c
@@ -183,7 +183,11 @@ typedef struct
int ndirty; /* Dirty bytes starting at buffer_offset */
- int special_file; /* =1 if the fd refers to a special file */
+ int special_file; /* =1 if the fd refers to a special file */
+
+ /* Cached stat(2) values. */
+ dev_t st_dev;
+ ino_t st_ino;
}
unix_stream;
@@ -940,18 +944,29 @@ fd_to_stream (int fd)
fstat (fd, &statbuf);
- if (lseek (fd, 0, SEEK_CUR) == (gfc_offset) -1)
- s->file_length = -1;
- else
- s->file_length = S_ISREG (statbuf.st_mode) ? statbuf.st_size : -1;
-
+ s->st_dev = statbuf.st_dev;
+ s->st_ino = statbuf.st_ino;
s->special_file = !S_ISREG (statbuf.st_mode);
- if (isatty (s->fd) || options.all_unbuffered
+ if (S_ISREG (statbuf.st_mode))
+ s->file_length = statbuf.st_size;
+ else if (S_ISBLK (statbuf.st_mode))
+ {
+ /* Hopefully more portable than ioctl(fd, BLKGETSIZE64, &size)? */
+ gfc_offset cur = lseek (fd, 0, SEEK_CUR);
+ s->file_length = lseek (fd, 0, SEEK_END);
+ lseek (fd, cur, SEEK_SET);
+ }
+ else
+ s->file_length = -1;
+
+ if (!(S_ISREG (statbuf.st_mode) || S_ISBLK (statbuf.st_mode))
+ || options.all_unbuffered
||(options.unbuffered_preconnected &&
(s->fd == STDIN_FILENO
|| s->fd == STDOUT_FILENO
- || s->fd == STDERR_FILENO)))
+ || s->fd == STDERR_FILENO))
+ || isatty (s->fd))
raw_init (s);
else
buf_init (s);
@@ -1370,9 +1385,9 @@ int
compare_file_filename (gfc_unit *u, const char *name, int len)
{
char path[PATH_MAX + 1];
- gfstat_t st1;
+ gfstat_t st;
#ifdef HAVE_WORKING_STAT
- gfstat_t st2;
+ unix_stream *s;
#else
# ifdef __MINGW32__
uint64_t id1, id2;
@@ -1385,12 +1400,12 @@ compare_file_filename (gfc_unit *u, const char *name, int len)
/* If the filename doesn't exist, then there is no match with the
* existing file. */
- if (stat (path, &st1) < 0)
+ if (stat (path, &st) < 0)
return 0;
#ifdef HAVE_WORKING_STAT
- fstat (((unix_stream *) (u->s))->fd, &st2);
- return (st1.st_dev == st2.st_dev) && (st1.st_ino == st2.st_ino);
+ s = (unix_stream *) (u->s);
+ return (st.st_dev == s->st_dev) && (st.st_ino == s->st_ino);
#else
# ifdef __MINGW32__
@@ -1432,10 +1447,12 @@ find_file0 (gfc_unit *u, FIND_FILE0_DECL)
return NULL;
#ifdef HAVE_WORKING_STAT
- if (u->s != NULL
- && fstat (((unix_stream *) u->s)->fd, &st[1]) >= 0 &&
- st[0].st_dev == st[1].st_dev && st[0].st_ino == st[1].st_ino)
- return u;
+ if (u->s != NULL)
+ {
+ unix_stream *s = (unix_stream *) (u->s);
+ if (st[0].st_dev == s->st_dev && st[0].st_ino == s->st_ino)
+ return u;
+ }
#else
# ifdef __MINGW32__
if (u->s && ((id1 = id_from_fd (((unix_stream *) u->s)->fd)) || id1))
@@ -1468,7 +1485,7 @@ gfc_unit *
find_file (const char *file, gfc_charlen_type file_len)
{
char path[PATH_MAX + 1];
- gfstat_t st[2];
+ gfstat_t st[1];
gfc_unit *u;
#if defined(__MINGW32__) && !HAVE_WORKING_STAT
uint64_t id = 0ULL;