1
0
mirror of https://sourceware.org/git/glibc.git synced 2025-07-30 22:43:12 +03:00

2002-07-31 Roland McGrath <roland@frob.com>

* libio/fileops.c (decide_maybe_mmap): New static function.
	Code taken from libio/iofopen.c:__fopen_maybe_mmap to try to
	mmap the file contents.  Then switch the jump tables to the mmap
	tables if it worked, or the vanilla file tables if not.
	(_IO_file_underflow_maybe_mmap): New function.
	(_IO_file_seekoff_maybe_mmap): New function.
	(_IO_file_xsgetn_maybe_mmap): New function.
	(_IO_file_jumps_maybe_mmap): New variable, jump table using those.
	* libio/libioP.h: Declare those.
	* libio/wfileops.c (_IO_wfile_underflow_maybe_mmap): New function.
	(_IO_wfile_jumps_maybe_mmap): New variable, jump table using that.
	* libio/iofopen.c (__fopen_maybe_mmap): Don't try to mmap here.
	If the stream is read-only, set its jump tables to those new ones.
	* libio/iofdopen.c (_IO_new_fdopen) [_G_HAVE_MMAP]: Set the initial
	jump tables to the maybe_mmap ones, and don't call __fopen_maybe_mmap.
	We need the tables set before _IO_file_attach.
This commit is contained in:
Roland McGrath
2002-08-02 01:27:53 +00:00
parent 0950889b81
commit e42637b677
3 changed files with 28 additions and 46 deletions

View File

@ -124,8 +124,19 @@ _IO_new_fdopen (fd, mode)
#ifdef _IO_MTSAFE_IO #ifdef _IO_MTSAFE_IO
new_f->fp.file._lock = &new_f->lock; new_f->fp.file._lock = &new_f->lock;
#endif #endif
_IO_no_init (&new_f->fp.file, 0, 0, &new_f->wd, &INTUSE(_IO_wfile_jumps)); /* Set up initially to use the `maybe_mmap' jump tables rather than using
_IO_JUMPS (&new_f->fp) = &INTUSE(_IO_file_jumps); __fopen_maybe_mmap to do it, because we need them in place before we
call _IO_file_attach or else it will allocate a buffer immediately. */
_IO_no_init (&new_f->fp.file, 0, 0, &new_f->wd,
#ifdef _G_HAVE_MMAP
(read_write & _IO_NO_WRITES) ? &_IO_wfile_jumps_maybe_mmap :
#endif
&INTUSE(_IO_wfile_jumps));
_IO_JUMPS (&new_f->fp) =
#ifdef _G_HAVE_MMAP
(read_write & _IO_NO_WRITES) ? &_IO_file_jumps_maybe_mmap :
#endif
&INTUSE(_IO_file_jumps);
INTUSE(_IO_file_init) (&new_f->fp); INTUSE(_IO_file_init) (&new_f->fp);
#if !_IO_UNIFIED_JUMPTABLES #if !_IO_UNIFIED_JUMPTABLES
new_f->fp.vtable = NULL; new_f->fp.vtable = NULL;
@ -143,7 +154,7 @@ _IO_new_fdopen (fd, mode)
_IO_mask_flags (&new_f->fp.file, read_write, _IO_mask_flags (&new_f->fp.file, read_write,
_IO_NO_READS+_IO_NO_WRITES+_IO_IS_APPENDING); _IO_NO_READS+_IO_NO_WRITES+_IO_IS_APPENDING);
return __fopen_maybe_mmap (&new_f->fp.file); return &new_f->fp.file;
} }
INTDEF2(_IO_new_fdopen, _IO_fdopen) INTDEF2(_IO_new_fdopen, _IO_fdopen)

View File

@ -43,50 +43,16 @@ __fopen_maybe_mmap (fp)
#ifdef _G_HAVE_MMAP #ifdef _G_HAVE_MMAP
if (fp->_flags & _IO_NO_WRITES) if (fp->_flags & _IO_NO_WRITES)
{ {
/* We use the file in read-only mode. This could mean we can /* Since this is read-only, we might be able to mmap the contents
mmap the file and use it without any copying. But not all directly. We delay the decision until the first read attempt by
file descriptors are for mmap-able objects and on 32-bit giving it a jump table containing functions that choose mmap or
machines we don't want to map files which are too large since vanilla file operations and reset the jump table accordingly. */
this would require too much virtual memory. */
struct _G_stat64 st;
if (_IO_SYSSTAT (fp, &st) == 0 if (fp->_mode <= 0)
&& S_ISREG (st.st_mode) && st.st_size != 0 _IO_JUMPS ((struct _IO_FILE_plus *) fp) = &_IO_file_jumps_maybe_mmap;
/* Limit the file size to 1MB for 32-bit machines. */ else
&& (sizeof (ptrdiff_t) > 4 || st.st_size < 1*1024*1024) _IO_JUMPS ((struct _IO_FILE_plus *) fp) = &_IO_wfile_jumps_maybe_mmap;
/* Sanity check. */ fp->_wide_data->_wide_vtable = &_IO_wfile_jumps_maybe_mmap;
&& (fp->_offset == _IO_pos_BAD || fp->_offset <= st.st_size))
{
/* Try to map the file. */
void *p;
# ifdef _G_MMAP64
p = _G_MMAP64 (NULL, st.st_size, PROT_READ, MAP_PRIVATE,
fp->_fileno, 0);
# else
p = __mmap (NULL, st.st_size, PROT_READ, MAP_PRIVATE,
fp->_fileno, 0);
# endif
if (p != MAP_FAILED)
{
/* OK, we managed to map the file. Set the buffer up
and use a special jump table with simplified
underflow functions which never tries to read
anything from the file. */
INTUSE(_IO_setb) (fp, p, (char *) p + st.st_size, 0);
if (fp->_offset == _IO_pos_BAD)
fp->_offset = 0;
_IO_setg (fp, p, p + fp->_offset, p + fp->_offset);
if (fp->_mode <= 0)
_IO_JUMPS ((struct _IO_FILE_plus *) fp) = &_IO_file_jumps_mmap;
else
_IO_JUMPS ((struct _IO_FILE_plus *) fp) = &_IO_wfile_jumps_mmap;
fp->_wide_data->_wide_vtable = &_IO_wfile_jumps_mmap;
}
}
} }
#endif #endif
return fp; return fp;

View File

@ -425,8 +425,10 @@ extern void _IO_default_imbue __P ((_IO_FILE *, void *));
extern struct _IO_jump_t _IO_file_jumps; extern struct _IO_jump_t _IO_file_jumps;
extern struct _IO_jump_t _IO_file_jumps_mmap attribute_hidden; extern struct _IO_jump_t _IO_file_jumps_mmap attribute_hidden;
extern struct _IO_jump_t _IO_file_jumps_maybe_mmap attribute_hidden;
extern struct _IO_jump_t _IO_wfile_jumps attribute_hidden; extern struct _IO_jump_t _IO_wfile_jumps attribute_hidden;
extern struct _IO_jump_t _IO_wfile_jumps_mmap attribute_hidden; extern struct _IO_jump_t _IO_wfile_jumps_mmap attribute_hidden;
extern struct _IO_jump_t _IO_wfile_jumps_maybe_mmap attribute_hidden;
extern struct _IO_jump_t _IO_old_file_jumps attribute_hidden; extern struct _IO_jump_t _IO_old_file_jumps attribute_hidden;
extern struct _IO_jump_t _IO_streambuf_jumps; extern struct _IO_jump_t _IO_streambuf_jumps;
extern struct _IO_jump_t _IO_proc_jumps attribute_hidden; extern struct _IO_jump_t _IO_proc_jumps attribute_hidden;
@ -498,6 +500,8 @@ extern _IO_FILE* _IO_file_setbuf __P ((_IO_FILE *, char *, _IO_ssize_t));
extern _IO_off64_t _IO_file_seekoff __P ((_IO_FILE *, _IO_off64_t, int, int)); extern _IO_off64_t _IO_file_seekoff __P ((_IO_FILE *, _IO_off64_t, int, int));
extern _IO_off64_t _IO_file_seekoff_mmap __P ((_IO_FILE *, _IO_off64_t, int, extern _IO_off64_t _IO_file_seekoff_mmap __P ((_IO_FILE *, _IO_off64_t, int,
int)); int));
extern _IO_off64_t _IO_file_seekoff_maybe_mmap __P ((_IO_FILE *, _IO_off64_t,
int, int));
extern _IO_size_t _IO_file_xsputn __P ((_IO_FILE *, const void *, _IO_size_t)); extern _IO_size_t _IO_file_xsputn __P ((_IO_FILE *, const void *, _IO_size_t));
extern _IO_size_t _IO_file_xsgetn __P ((_IO_FILE *, void *, _IO_size_t)); extern _IO_size_t _IO_file_xsgetn __P ((_IO_FILE *, void *, _IO_size_t));
extern int _IO_file_stat __P ((_IO_FILE *, void *)); extern int _IO_file_stat __P ((_IO_FILE *, void *));
@ -505,6 +509,7 @@ extern int _IO_file_close __P ((_IO_FILE *));
extern int _IO_file_close_mmap __P ((_IO_FILE *)); extern int _IO_file_close_mmap __P ((_IO_FILE *));
extern int _IO_file_underflow __P ((_IO_FILE *)); extern int _IO_file_underflow __P ((_IO_FILE *));
extern int _IO_file_underflow_mmap __P ((_IO_FILE *)); extern int _IO_file_underflow_mmap __P ((_IO_FILE *));
extern int _IO_file_underflow_maybe_mmap __P ((_IO_FILE *));
extern int _IO_file_overflow __P ((_IO_FILE *, int)); extern int _IO_file_overflow __P ((_IO_FILE *, int));
#define _IO_file_is_open(__fp) ((__fp)->_fileno != -1) #define _IO_file_is_open(__fp) ((__fp)->_fileno != -1)
extern void _IO_file_init __P ((struct _IO_FILE_plus *)); extern void _IO_file_init __P ((struct _IO_FILE_plus *));