IPC_HLE: Don't open/close file for every single file operation.
On the first boot of Pokemon Snap it copies a 144KB file to the Wii's NAND, but it only copies 32 bytes per IPC write call. This was causing dolphin to open and close the same file over 4000 times. This wouldn't usually be a huge issue, except some operating systems (namely Windows) allow 3rd party programs (namely antivirus software) to hook all accesses to the filesystem. This causes the antivirus software to scan the same file for viruses 4000+ times, which is kind of slow. This fix reduces the initial boot time of pokemon snap from 3+ min to just a few seconds. Could also improve other games which write things to NAND. Will break a few things, see the next commit for an improved fix.
This commit is contained in:
parent
03124ec3f0
commit
8b4734133e
|
@ -73,6 +73,7 @@ CWII_IPC_HLE_Device_FileIO::CWII_IPC_HLE_Device_FileIO(u32 _DeviceID, const std:
|
|||
: IWII_IPC_HLE_Device(_DeviceID, _rDeviceName, false) // not a real hardware
|
||||
, m_Mode(0)
|
||||
, m_SeekPos(0)
|
||||
, m_file()
|
||||
{
|
||||
Common::ReadReplacements(replacements);
|
||||
}
|
||||
|
@ -86,6 +87,8 @@ IPCCommandResult CWII_IPC_HLE_Device_FileIO::Close(u32 _CommandAddress, bool _bF
|
|||
INFO_LOG(WII_IPC_FILEIO, "FileIO: Close %s (DeviceID=%08x)", m_Name.c_str(), m_DeviceID);
|
||||
m_Mode = 0;
|
||||
|
||||
m_file.Close();
|
||||
|
||||
// Close always return 0 for success
|
||||
if (_CommandAddress && !_bForce)
|
||||
Memory::Write_U32(0, _CommandAddress + 4);
|
||||
|
@ -121,13 +124,15 @@ IPCCommandResult CWII_IPC_HLE_Device_FileIO::Open(u32 _CommandAddress, u32 _Mode
|
|||
ReturnValue = FS_FILE_NOT_EXIST;
|
||||
}
|
||||
|
||||
OpenFile();
|
||||
|
||||
if (_CommandAddress)
|
||||
Memory::Write_U32(ReturnValue, _CommandAddress+4);
|
||||
m_Active = true;
|
||||
return IPC_DEFAULT_REPLY;
|
||||
}
|
||||
|
||||
File::IOFile CWII_IPC_HLE_Device_FileIO::OpenFile()
|
||||
void CWII_IPC_HLE_Device_FileIO::OpenFile()
|
||||
{
|
||||
const char* open_mode = "";
|
||||
|
||||
|
@ -147,7 +152,7 @@ File::IOFile CWII_IPC_HLE_Device_FileIO::OpenFile()
|
|||
break;
|
||||
}
|
||||
|
||||
return File::IOFile(m_filepath, open_mode);
|
||||
m_file = File::IOFile(m_filepath, open_mode);
|
||||
}
|
||||
|
||||
IPCCommandResult CWII_IPC_HLE_Device_FileIO::Seek(u32 _CommandAddress)
|
||||
|
@ -156,11 +161,11 @@ IPCCommandResult CWII_IPC_HLE_Device_FileIO::Seek(u32 _CommandAddress)
|
|||
const s32 SeekPosition = Memory::Read_U32(_CommandAddress + 0xC);
|
||||
const s32 Mode = Memory::Read_U32(_CommandAddress + 0x10);
|
||||
|
||||
if (auto file = OpenFile())
|
||||
if (m_file)
|
||||
{
|
||||
ReturnValue = FS_RESULT_FATAL;
|
||||
|
||||
const s32 fileSize = (s32) file.GetSize();
|
||||
const s32 fileSize = (s32) m_file.GetSize();
|
||||
INFO_LOG(WII_IPC_FILEIO, "FileIO: Seek Pos: 0x%08x, Mode: %i (%s, Length=0x%08x)", SeekPosition, Mode, m_Name.c_str(), fileSize);
|
||||
|
||||
switch (Mode)
|
||||
|
@ -204,6 +209,7 @@ IPCCommandResult CWII_IPC_HLE_Device_FileIO::Seek(u32 _CommandAddress)
|
|||
break;
|
||||
}
|
||||
}
|
||||
m_file.Seek(m_SeekPos, SEEK_SET);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -221,7 +227,7 @@ IPCCommandResult CWII_IPC_HLE_Device_FileIO::Read(u32 _CommandAddress)
|
|||
const u32 Size = Memory::Read_U32(_CommandAddress + 0x10);
|
||||
|
||||
|
||||
if (auto file = OpenFile())
|
||||
if (m_file)
|
||||
{
|
||||
if (m_Mode == ISFS_OPEN_WRITE)
|
||||
{
|
||||
|
@ -230,9 +236,8 @@ IPCCommandResult CWII_IPC_HLE_Device_FileIO::Read(u32 _CommandAddress)
|
|||
else
|
||||
{
|
||||
INFO_LOG(WII_IPC_FILEIO, "FileIO: Read 0x%x bytes to 0x%08x from %s", Size, Address, m_Name.c_str());
|
||||
file.Seek(m_SeekPos, SEEK_SET);
|
||||
ReturnValue = (u32)fread(Memory::GetPointer(Address), 1, Size, file.GetHandle());
|
||||
if (ReturnValue != Size && ferror(file.GetHandle()))
|
||||
ReturnValue = (u32)fread(Memory::GetPointer(Address), 1, Size, m_file.GetHandle());
|
||||
if (ReturnValue != Size && ferror(m_file.GetHandle()))
|
||||
{
|
||||
ReturnValue = FS_EACCESS;
|
||||
}
|
||||
|
@ -259,7 +264,7 @@ IPCCommandResult CWII_IPC_HLE_Device_FileIO::Write(u32 _CommandAddress)
|
|||
const u32 Address = Memory::Read_U32(_CommandAddress + 0xC); // Write data from this memory address
|
||||
const u32 Size = Memory::Read_U32(_CommandAddress + 0x10);
|
||||
|
||||
if (auto file = OpenFile())
|
||||
if (m_file)
|
||||
{
|
||||
if (m_Mode == ISFS_OPEN_READ)
|
||||
{
|
||||
|
@ -268,8 +273,7 @@ IPCCommandResult CWII_IPC_HLE_Device_FileIO::Write(u32 _CommandAddress)
|
|||
else
|
||||
{
|
||||
INFO_LOG(WII_IPC_FILEIO, "FileIO: Write 0x%04x bytes from 0x%08x to %s", Size, Address, m_Name.c_str());
|
||||
file.Seek(m_SeekPos, SEEK_SET);
|
||||
if (file.WriteBytes(Memory::GetPointer(Address), Size))
|
||||
if (m_file.WriteBytes(Memory::GetPointer(Address), Size))
|
||||
{
|
||||
ReturnValue = Size;
|
||||
m_SeekPos += Size;
|
||||
|
@ -299,9 +303,9 @@ IPCCommandResult CWII_IPC_HLE_Device_FileIO::IOCtl(u32 _CommandAddress)
|
|||
{
|
||||
case ISFS_IOCTL_GETFILESTATS:
|
||||
{
|
||||
if (auto file = OpenFile())
|
||||
if (m_file)
|
||||
{
|
||||
u32 m_FileLength = (u32)file.GetSize();
|
||||
u32 m_FileLength = (u32)m_file.GetSize();
|
||||
|
||||
const u32 BufferOut = Memory::Read_U32(_CommandAddress + 0x18);
|
||||
INFO_LOG(WII_IPC_FILEIO, " File: %s, Length: %i, Pos: %i", m_Name.c_str(), m_FileLength, m_SeekPos);
|
||||
|
@ -337,4 +341,10 @@ void CWII_IPC_HLE_Device_FileIO::DoState(PointerWrap &p)
|
|||
p.Do(m_SeekPos);
|
||||
|
||||
m_filepath = HLE_IPC_BuildFilename(m_Name);
|
||||
|
||||
if (p.GetMode() == PointerWrap::MODE_READ)
|
||||
{
|
||||
OpenFile();
|
||||
m_file.Seek(m_SeekPos, SEEK_SET);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,7 +28,7 @@ public:
|
|||
IPCCommandResult IOCtl(u32 _CommandAddress) override;
|
||||
void DoState(PointerWrap &p) override;
|
||||
|
||||
File::IOFile OpenFile();
|
||||
void OpenFile();
|
||||
|
||||
private:
|
||||
enum
|
||||
|
@ -75,4 +75,5 @@ private:
|
|||
u32 m_SeekPos;
|
||||
|
||||
std::string m_filepath;
|
||||
File::IOFile m_file;
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue