mirror of
https://github.com/coreutils/coreutils.git
synced 2024-11-24 02:17:22 +08:00
fadvise: new module providing a simpler interface to posix_fadvise
* bootstrap.conf: Include the new module * gl/lib/fadvise.c: Provide a simpler interface to posix_fadvise. (fadvise): Provide hint to the whole file associated with a stream. (fdadvise): Provide hint to the specific portion of a file associated with a file descriptor. * gl/lib/fadvise.h: Redefine POSIX_FADV_* to FADVISE_* enums. * gl/modules/fadvise: New file. * m4/jm-macros.m4: Remove the no longer needed posix_fadvise check. * .x-sc_program_name: Exclude test-fadvise.c from this check. * gl/tests/test-fadvise (main): New test program. * gl/modules/fadvise-testss: A new index to reference the tests. * src/sort.c (stream_open): Use the new interface. * src/dd.c (iwrite): Likewise.
This commit is contained in:
parent
c88cfffb6c
commit
63b5e81648
@ -1,3 +1,4 @@
|
||||
gl/lib/randint.c
|
||||
lib/euidaccess-stat.c
|
||||
gl/tests/test-mbsalign.c
|
||||
gl/tests/test-fadvise.c
|
||||
|
@ -81,6 +81,7 @@ gnulib_modules="
|
||||
exclude
|
||||
exitfail
|
||||
faccessat
|
||||
fadvise
|
||||
fchdir
|
||||
fcntl
|
||||
fcntl-safer
|
||||
|
37
gl/lib/fadvise.c
Normal file
37
gl/lib/fadvise.c
Normal file
@ -0,0 +1,37 @@
|
||||
/* Declare an access pattern hint for files.
|
||||
Copyright (C) 2010 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <config.h>
|
||||
#include "fadvise.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <fcntl.h>
|
||||
#include "ignore-value.h"
|
||||
|
||||
void
|
||||
fdadvise (int fd, off_t offset, off_t len, fadvice_t advice)
|
||||
{
|
||||
#if HAVE_POSIX_FADVISE
|
||||
ignore_value (posix_fadvise (fd, offset, len, advice));
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
fadvise (FILE *fp, fadvice_t advice)
|
||||
{
|
||||
if (fp)
|
||||
fdadvise (fileno (fp), 0, 0, advice);
|
||||
}
|
72
gl/lib/fadvise.h
Normal file
72
gl/lib/fadvise.h
Normal file
@ -0,0 +1,72 @@
|
||||
/* Declare an access pattern hint for files.
|
||||
Copyright (C) 2010 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <config.h>
|
||||
#include <stdio.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
/* There are a few hints one can provide, which have the
|
||||
following characteristics on Linux 2.6.31 at least.
|
||||
|
||||
POSIX_FADV_SEQUENTIAL
|
||||
Doubles the size of read ahead done for file
|
||||
POSIX_FADV_WILLNEED
|
||||
_synchronously_ prepopulate the buffer cache with the file
|
||||
POSIX_FADV_NOREUSE
|
||||
Could lower priority of data in buffer caches,
|
||||
but currently does nothing.
|
||||
POSIX_FADV_DONTNEED
|
||||
Drop the file from cache.
|
||||
Note this is automatically done when files are unlinked.
|
||||
|
||||
We use this enum "type" both to make it explicit that
|
||||
these options are mutually exclusive, and to discourage
|
||||
the passing of the possibly undefined POSIX_FADV_... values.
|
||||
Note we could #undef the POSIX_FADV_ values, but that would
|
||||
preclude using the posix_fadvise() function with its standard
|
||||
constants. Using posix_fadvise() might be required if the return
|
||||
value is needed, but it must be guarded by appropriate #ifdefs. */
|
||||
|
||||
#if HAVE_POSIX_FADVISE
|
||||
typedef enum {
|
||||
FADVISE_NORMAL = POSIX_FADV_NORMAL,
|
||||
FADVISE_SEQUENTIAL = POSIX_FADV_SEQUENTIAL,
|
||||
FADVISE_NOREUSE = POSIX_FADV_NOREUSE,
|
||||
FADVISE_DONTNEED = POSIX_FADV_DONTNEED,
|
||||
FADVISE_WILLNEED = POSIX_FADV_WILLNEED,
|
||||
FADVISE_RANDOM = POSIX_FADV_RANDOM,
|
||||
} fadvice_t;
|
||||
#else
|
||||
typedef enum {
|
||||
FADVISE_NORMAL,
|
||||
FADVISE_SEQUENTIAL,
|
||||
FADVISE_NOREUSE,
|
||||
FADVISE_DONTNEED,
|
||||
FADVISE_WILLNEED,
|
||||
FADVISE_RANDOM,
|
||||
} fadvice_t;
|
||||
#endif
|
||||
|
||||
/* We ignore any errors as these hints are only advisory.
|
||||
There is the chance one can pass invalid ADVICE, which will
|
||||
not be indicated, but given the simplicity of the interface
|
||||
this is unlikely. Also not returning errors allows the
|
||||
unconditional passing of descriptors to non standard files,
|
||||
which will just be ignored if unsupported. */
|
||||
|
||||
void fdadvise (int fd, off_t offset, off_t len, fadvice_t advice);
|
||||
void fadvise (FILE *fp, fadvice_t advice);
|
24
gl/modules/fadvise
Normal file
24
gl/modules/fadvise
Normal file
@ -0,0 +1,24 @@
|
||||
Description:
|
||||
Declare an access pattern hint for files.
|
||||
|
||||
Files:
|
||||
lib/fadvise.c
|
||||
lib/fadvise.h
|
||||
|
||||
Depends-on:
|
||||
ignore-value
|
||||
|
||||
configure.ac:
|
||||
AC_CHECK_FUNCS_ONCE([posix_fadvise])
|
||||
|
||||
Makefile.am:
|
||||
lib_SOURCES += fadvise.c fadvise.h
|
||||
|
||||
Include:
|
||||
"fadvise.h"
|
||||
|
||||
License:
|
||||
LGPL
|
||||
|
||||
Maintainer:
|
||||
Pádraig Brady
|
43
gl/tests/test-fadvise.c
Normal file
43
gl/tests/test-fadvise.c
Normal file
@ -0,0 +1,43 @@
|
||||
/* Test that fadvise works as advertised.
|
||||
Copyright (C) 2010 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
/* Written by Pádraig Brady. */
|
||||
|
||||
#include <config.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "fadvise.h"
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
/* Valid. */
|
||||
fadvise (stdin, FADVISE_SEQUENTIAL);
|
||||
fdadvise (fileno (stdin), 0, 0, FADVISE_RANDOM);
|
||||
|
||||
/* Ignored. */
|
||||
fadvise (NULL, FADVISE_RANDOM);
|
||||
|
||||
/* Invalid. */
|
||||
fdadvise (42, 0, 0, FADVISE_RANDOM);
|
||||
/* Unfortunately C enums are not types.
|
||||
One could hack type safety by wrapping in a struct,
|
||||
but it's probably not worth the complexity in this case. */
|
||||
fadvise (stdin, FADVISE_SEQUENTIAL + FADVISE_RANDOM);
|
||||
fadvise (stdin, 4242);
|
||||
|
||||
return 0;
|
||||
}
|
@ -64,7 +64,6 @@ AC_DEFUN([coreutils_MACROS],
|
||||
LIBS=$coreutils_saved_libs
|
||||
|
||||
# Used by sort.c.
|
||||
AC_CHECK_FUNCS_ONCE([posix_fadvise])
|
||||
AC_CHECK_FUNCS_ONCE([nl_langinfo])
|
||||
|
||||
# Used by tail.c.
|
||||
|
7
src/dd.c
7
src/dd.c
@ -27,10 +27,10 @@
|
||||
#include "system.h"
|
||||
#include "close-stream.h"
|
||||
#include "error.h"
|
||||
#include "fadvise.h"
|
||||
#include "fd-reopen.h"
|
||||
#include "gethrxtime.h"
|
||||
#include "human.h"
|
||||
#include "ignore-value.h"
|
||||
#include "long-options.h"
|
||||
#include "quote.h"
|
||||
#include "quotearg.h"
|
||||
@ -849,12 +849,9 @@ iwrite (int fd, char const *buf, size_t size)
|
||||
posix_fadvise to tell the system not to pollute the buffer
|
||||
cache with this data. Don't bother to diagnose lseek or
|
||||
posix_fadvise failure. */
|
||||
#ifdef POSIX_FADV_DONTNEED
|
||||
off_t off = lseek (STDOUT_FILENO, 0, SEEK_CUR);
|
||||
if (0 <= off)
|
||||
ignore_value (posix_fadvise (STDOUT_FILENO,
|
||||
off, 0, POSIX_FADV_DONTNEED));
|
||||
#endif
|
||||
fdadvise (STDOUT_FILENO, off, 0, FADVISE_DONTNEED);
|
||||
|
||||
/* Attempt to ensure that that final block is committed
|
||||
to disk as quickly as possible. */
|
||||
|
30
src/sort.c
30
src/sort.c
@ -30,11 +30,11 @@
|
||||
#include "system.h"
|
||||
#include "argmatch.h"
|
||||
#include "error.h"
|
||||
#include "fadvise.h"
|
||||
#include "filevercmp.h"
|
||||
#include "hard-locale.h"
|
||||
#include "hash.h"
|
||||
#include "heap.h"
|
||||
#include "ignore-value.h"
|
||||
#include "md5.h"
|
||||
#include "mbswidth.h"
|
||||
#include "nproc.h"
|
||||
@ -856,9 +856,13 @@ create_temp_file (int *pfd, bool survive_fd_exhaustion)
|
||||
return node;
|
||||
}
|
||||
|
||||
/* Predeclare an access pattern for input files.
|
||||
Ignore any errors -- this is only advisory.
|
||||
/* Return a stream for FILE, opened with mode HOW. A null FILE means
|
||||
standard output; HOW should be "w". When opening for input, "-"
|
||||
means standard input. To avoid confusion, do not return file
|
||||
descriptors STDIN_FILENO, STDOUT_FILENO, or STDERR_FILENO when
|
||||
opening an ordinary FILE. Return NULL if unsuccessful.
|
||||
|
||||
fadvise() is used to specify an access pattern for input files.
|
||||
There are a few hints we could possibly provide,
|
||||
and after careful testing it was decided that
|
||||
specifying POSIX_FADV_SEQUENTIAL was not detrimental
|
||||
@ -899,24 +903,6 @@ create_temp_file (int *pfd, bool survive_fd_exhaustion)
|
||||
cache immediately after processing. This is done implicitly
|
||||
however when the files are unlinked. */
|
||||
|
||||
static void
|
||||
fadvise_input (FILE *fp)
|
||||
{
|
||||
#if HAVE_POSIX_FADVISE
|
||||
if (fp)
|
||||
{
|
||||
int fd = fileno (fp);
|
||||
ignore_value (posix_fadvise (fd, 0, 0, POSIX_FADV_SEQUENTIAL));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Return a stream for FILE, opened with mode HOW. A null FILE means
|
||||
standard output; HOW should be "w". When opening for input, "-"
|
||||
means standard input. To avoid confusion, do not return file
|
||||
descriptors STDIN_FILENO, STDOUT_FILENO, or STDERR_FILENO when
|
||||
opening an ordinary FILE. Return NULL if unsuccessful. */
|
||||
|
||||
static FILE *
|
||||
stream_open (const char *file, const char *how)
|
||||
{
|
||||
@ -932,7 +918,7 @@ stream_open (const char *file, const char *how)
|
||||
}
|
||||
else
|
||||
fp = fopen (file, how);
|
||||
fadvise_input (fp);
|
||||
fadvise (fp, FADVISE_SEQUENTIAL);
|
||||
return fp;
|
||||
}
|
||||
return fopen (file, how);
|
||||
|
Loading…
Reference in New Issue
Block a user