diff options
author | Bastien Bouclet | 2019-10-20 09:23:51 +0200 |
---|---|---|
committer | Bastien Bouclet | 2019-11-20 20:54:23 +0100 |
commit | f8d551803cfb6c1db3d24f7ef2731c652b9a5313 (patch) | |
tree | c955443ba2caef69eab51a969c4cb003ae3c8edb /backends | |
parent | be0304d9d618a48acaeff3ef8ecb2f73a510e926 (diff) | |
download | scummvm-rg350-f8d551803cfb6c1db3d24f7ef2731c652b9a5313.tar.gz scummvm-rg350-f8d551803cfb6c1db3d24f7ef2731c652b9a5313.tar.bz2 scummvm-rg350-f8d551803cfb6c1db3d24f7ef2731c652b9a5313.zip |
POSIX: Use fstat instead of fseek / ftell to retrieve file stream sizes
fstat is generally faster as is does not cause the IO buffer to be
invalidated / refilled.
Benchmark results for the startup time of the SCI engine with Gabriel
Knight 1 CD:
- Linux, glibc, spinning HDD, fseek/ftell: 140 ms
- Linux, glibc, spinning HDD, fstat: 100 ms
- 3DS, newlib, SD card, fseek/ftell: 68 s
- 3DS, newlib, SD card, fstat: 11 s
Diffstat (limited to 'backends')
-rw-r--r-- | backends/fs/posix/posix-fs.cpp | 6 | ||||
-rw-r--r-- | backends/fs/posix/posix-iostream.cpp | 56 | ||||
-rw-r--r-- | backends/fs/posix/posix-iostream.h | 39 | ||||
-rw-r--r-- | backends/module.mk | 2 |
4 files changed, 100 insertions, 3 deletions
diff --git a/backends/fs/posix/posix-fs.cpp b/backends/fs/posix/posix-fs.cpp index 82ae597745..a908729dd7 100644 --- a/backends/fs/posix/posix-fs.cpp +++ b/backends/fs/posix/posix-fs.cpp @@ -33,7 +33,7 @@ #define FORBIDDEN_SYMBOL_EXCEPTION_srandom #include "backends/fs/posix/posix-fs.h" -#include "backends/fs/stdiostream.h" +#include "backends/fs/posix/posix-iostream.h" #include "common/algorithm.h" #include <sys/param.h> @@ -312,11 +312,11 @@ AbstractFSNode *POSIXFilesystemNode::getParent() const { } Common::SeekableReadStream *POSIXFilesystemNode::createReadStream() { - return StdioStream::makeFromPath(getPath(), false); + return PosixIoStream::makeFromPath(getPath(), false); } Common::WriteStream *POSIXFilesystemNode::createWriteStream() { - return StdioStream::makeFromPath(getPath(), true); + return PosixIoStream::makeFromPath(getPath(), true); } bool POSIXFilesystemNode::createDirectory() { diff --git a/backends/fs/posix/posix-iostream.cpp b/backends/fs/posix/posix-iostream.cpp new file mode 100644 index 0000000000..59f14142b5 --- /dev/null +++ b/backends/fs/posix/posix-iostream.cpp @@ -0,0 +1,56 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * 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 2 + * 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#define FORBIDDEN_SYMBOL_ALLOW_ALL + +#include "backends/fs/posix/posix-iostream.h" + +#include <sys/stat.h> + +PosixIoStream *PosixIoStream::makeFromPath(const Common::String &path, bool writeMode) { + FILE *handle = fopen(path.c_str(), writeMode ? "wb" : "rb"); + + if (handle) + return new PosixIoStream(handle); + + return nullptr; +} + +PosixIoStream::PosixIoStream(void *handle) : + StdioStream(handle) { +} + +int32 PosixIoStream::size() const { + int fd = fileno((FILE *)_handle); + if (fd == -1) { + return StdioStream::size(); + } + + // Using fstat to obtain the file size is generally faster than fseek / ftell + // because it does not affect the IO buffer. + struct stat st; + if (fstat(fd, &st) == -1) { + return StdioStream::size(); + } + + return st.st_size; +} diff --git a/backends/fs/posix/posix-iostream.h b/backends/fs/posix/posix-iostream.h new file mode 100644 index 0000000000..638d7b17cd --- /dev/null +++ b/backends/fs/posix/posix-iostream.h @@ -0,0 +1,39 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * 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 2 + * 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#ifndef BACKENDS_FS_POSIX_POSIXIOSTREAM_H +#define BACKENDS_FS_POSIX_POSIXIOSTREAM_H + +#include "backends/fs/stdiostream.h" + +/** + * A file input / output stream using POSIX interfaces + */ +class PosixIoStream : public StdioStream { +public: + static PosixIoStream *makeFromPath(const Common::String &path, bool writeMode); + PosixIoStream(void *handle); + + int32 size() const override; +}; + +#endif diff --git a/backends/module.mk b/backends/module.mk index 0ed597882b..924164c03f 100644 --- a/backends/module.mk +++ b/backends/module.mk @@ -163,6 +163,8 @@ ifdef POSIX MODULE_OBJS += \ fs/posix/posix-fs.o \ fs/posix/posix-fs-factory.o \ + fs/posix/posix-fs-factory.o \ + fs/posix/posix-iostream.o \ fs/posix-drives/posix-drives-fs.o \ fs/posix-drives/posix-drives-fs-factory.o \ fs/chroot/chroot-fs-factory.o \ |