Cache stat values, reduce syscalls

From-SVN: r166502
This commit is contained in:
Janne Blomqvist 2010-11-09 20:17:35 +02:00
parent f4a88680ab
commit 7debf73d34
2 changed files with 44 additions and 18 deletions

View File

@ -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> 2010-11-09 Jerry DeLisle <jvdelisle@gcc.gnu.org>
PR libgfortran/46373 PR libgfortran/46373

View File

@ -183,7 +183,11 @@ typedef struct
int ndirty; /* Dirty bytes starting at buffer_offset */ 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; unix_stream;
@ -940,18 +944,29 @@ fd_to_stream (int fd)
fstat (fd, &statbuf); fstat (fd, &statbuf);
if (lseek (fd, 0, SEEK_CUR) == (gfc_offset) -1) s->st_dev = statbuf.st_dev;
s->file_length = -1; s->st_ino = statbuf.st_ino;
else
s->file_length = S_ISREG (statbuf.st_mode) ? statbuf.st_size : -1;
s->special_file = !S_ISREG (statbuf.st_mode); 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 && ||(options.unbuffered_preconnected &&
(s->fd == STDIN_FILENO (s->fd == STDIN_FILENO
|| s->fd == STDOUT_FILENO || s->fd == STDOUT_FILENO
|| s->fd == STDERR_FILENO))) || s->fd == STDERR_FILENO))
|| isatty (s->fd))
raw_init (s); raw_init (s);
else else
buf_init (s); buf_init (s);
@ -1370,9 +1385,9 @@ int
compare_file_filename (gfc_unit *u, const char *name, int len) compare_file_filename (gfc_unit *u, const char *name, int len)
{ {
char path[PATH_MAX + 1]; char path[PATH_MAX + 1];
gfstat_t st1; gfstat_t st;
#ifdef HAVE_WORKING_STAT #ifdef HAVE_WORKING_STAT
gfstat_t st2; unix_stream *s;
#else #else
# ifdef __MINGW32__ # ifdef __MINGW32__
uint64_t id1, id2; 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 /* If the filename doesn't exist, then there is no match with the
* existing file. */ * existing file. */
if (stat (path, &st1) < 0) if (stat (path, &st) < 0)
return 0; return 0;
#ifdef HAVE_WORKING_STAT #ifdef HAVE_WORKING_STAT
fstat (((unix_stream *) (u->s))->fd, &st2); s = (unix_stream *) (u->s);
return (st1.st_dev == st2.st_dev) && (st1.st_ino == st2.st_ino); return (st.st_dev == s->st_dev) && (st.st_ino == s->st_ino);
#else #else
# ifdef __MINGW32__ # ifdef __MINGW32__
@ -1432,10 +1447,12 @@ find_file0 (gfc_unit *u, FIND_FILE0_DECL)
return NULL; return NULL;
#ifdef HAVE_WORKING_STAT #ifdef HAVE_WORKING_STAT
if (u->s != NULL 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) unix_stream *s = (unix_stream *) (u->s);
return u; if (st[0].st_dev == s->st_dev && st[0].st_ino == s->st_ino)
return u;
}
#else #else
# ifdef __MINGW32__ # ifdef __MINGW32__
if (u->s && ((id1 = id_from_fd (((unix_stream *) u->s)->fd)) || id1)) 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) find_file (const char *file, gfc_charlen_type file_len)
{ {
char path[PATH_MAX + 1]; char path[PATH_MAX + 1];
gfstat_t st[2]; gfstat_t st[1];
gfc_unit *u; gfc_unit *u;
#if defined(__MINGW32__) && !HAVE_WORKING_STAT #if defined(__MINGW32__) && !HAVE_WORKING_STAT
uint64_t id = 0ULL; uint64_t id = 0ULL;