From 1b838c4403fbd2273237d7129c07c7bcbebedaf2 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sat, 10 Aug 2013 09:08:31 -0700 Subject: [PATCH 1/7] Move ThreadEventQueue to its own file. --- CMakeLists.txt | 1 + Core/Core.vcxproj | 1 + Core/Core.vcxproj.filters | 3 + Core/ThreadEventQueue.h | 116 ++++++++++++++++++++++++++++++++++++++ GPU/GPUCommon.h | 97 +------------------------------ 5 files changed, 122 insertions(+), 96 deletions(-) create mode 100644 Core/ThreadEventQueue.h diff --git a/CMakeLists.txt b/CMakeLists.txt index aba6a9d71..36f71bfb8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -746,6 +746,7 @@ add_library(${CoreLibName} ${CoreLinkType} Core/CwCheat.h Core/HDRemaster.cpp Core/HDRemaster.h + Core/ThreadEventQueue.h Core/Debugger/Breakpoints.cpp Core/Debugger/Breakpoints.h Core/Debugger/DebugInterface.h diff --git a/Core/Core.vcxproj b/Core/Core.vcxproj index 2ac6129b6..1416bbb4d 100644 --- a/Core/Core.vcxproj +++ b/Core/Core.vcxproj @@ -486,6 +486,7 @@ + diff --git a/Core/Core.vcxproj.filters b/Core/Core.vcxproj.filters index ae1395a95..d9861b0b9 100644 --- a/Core/Core.vcxproj.filters +++ b/Core/Core.vcxproj.filters @@ -837,6 +837,9 @@ FileSystems + + Core + diff --git a/Core/ThreadEventQueue.h b/Core/ThreadEventQueue.h new file mode 100644 index 000000000..11231ea6a --- /dev/null +++ b/Core/ThreadEventQueue.h @@ -0,0 +1,116 @@ +// Copyright (c) 2013- PPSSPP Project. + +// 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, version 2.0 or later versions. + +// 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 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official git repository and contact information can be found at +// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. + +#pragma once + +#include "native/base/mutex.h" +#include "Core/CoreTiming.h" +#include + +template +struct ThreadEventQueue : public B { + void SetThreadEnabled(bool threadEnabled) { + threadEnabled_ = threadEnabled; + } + + void ScheduleEvent(Event ev) { + { + lock_guard guard(eventsLock_); + events_.push_back(ev); + eventsWait_.notify_one(); + } + + if (!threadEnabled_) { + RunEventsUntil(0); + } + } + + bool HasEvents() { + lock_guard guard(eventsLock_); + return !events_.empty(); + } + + Event GetNextEvent() { + lock_guard guard(eventsLock_); + if (events_.empty()) { + eventsDrain_.notify_one(); + return EVENT_INVALID; + } + + Event ev = events_.front(); + events_.pop_front(); + return ev; + } + + void RunEventsUntil(u64 globalticks) { + do { + for (Event ev = GetNextEvent(); EventType(ev) != EVENT_INVALID; ev = GetNextEvent()) { + switch (EventType(ev)) { + case EVENT_FINISH: + // Stop waiting. + globalticks = 0; + break; + + case EVENT_SYNC: + break; + + default: + ProcessEvent(ev); + } + } + + // Quit the loop if the queue is drained and coreState has tripped, or threading is disabled. + if (coreState != CORE_RUNNING || !threadEnabled_) { + return; + } + + // coreState changes won't wake us, so recheck periodically. + eventsWait_.wait_for(eventsWaitLock_, 1); + } while (CoreTiming::GetTicks() < globalticks); + } + + void SyncThread() { + if (!threadEnabled_) { + return; + } + + // While processing the last event, HasEvents() will be false even while not done. + // So we schedule a nothing event and wait for that to finish. + ScheduleEvent(EVENT_SYNC); + while (HasEvents() && coreState == CORE_RUNNING) { + eventsDrain_.wait_for(eventsDrainLock_, 1); + } + } + + void FinishEventLoop() { + if (threadEnabled_) { + ScheduleEvent(EVENT_FINISH); + } + } + +protected: + virtual void ProcessEvent(Event ev) = 0; + +private: + bool threadEnabled_; + std::deque events_; + recursive_mutex eventsLock_; + recursive_mutex eventsWaitLock_; + recursive_mutex eventsDrainLock_; + condition_variable eventsWait_; + condition_variable eventsDrain_; +}; \ No newline at end of file diff --git a/GPU/GPUCommon.h b/GPU/GPUCommon.h index b274f7e82..927a50e57 100644 --- a/GPU/GPUCommon.h +++ b/GPU/GPUCommon.h @@ -1,103 +1,8 @@ #pragma once -#include "native/base/mutex.h" +#include "Core/ThreadEventQueue.h" #include "GPU/GPUInterface.h" -#include "Core/CoreTiming.h" -#include -template -struct ThreadEventQueue : public B { - void SetThreadEnabled(bool threadEnabled) { - threadEnabled_ = threadEnabled; - } - - void ScheduleEvent(Event ev) { - { - lock_guard guard(eventsLock_); - events_.push_back(ev); - eventsWait_.notify_one(); - } - - if (!threadEnabled_) { - RunEventsUntil(0); - } - } - - bool HasEvents() { - lock_guard guard(eventsLock_); - return !events_.empty(); - } - - Event GetNextEvent() { - lock_guard guard(eventsLock_); - if (events_.empty()) { - eventsDrain_.notify_one(); - return EVENT_INVALID; - } - - Event ev = events_.front(); - events_.pop_front(); - return ev; - } - - void RunEventsUntil(u64 globalticks) { - do { - for (Event ev = GetNextEvent(); EventType(ev) != EVENT_INVALID; ev = GetNextEvent()) { - switch (EventType(ev)) { - case EVENT_FINISH: - // Stop waiting. - globalticks = 0; - break; - - case EVENT_SYNC: - break; - - default: - ProcessEvent(ev); - } - } - - // Quit the loop if the queue is drained and coreState has tripped, or threading is disabled. - if (coreState != CORE_RUNNING || !threadEnabled_) { - return; - } - - // coreState changes won't wake us, so recheck periodically. - eventsWait_.wait_for(eventsWaitLock_, 1); - } while (CoreTiming::GetTicks() < globalticks); - } - - void SyncThread() { - if (!threadEnabled_) { - return; - } - - // While processing the last event, HasEvents() will be false even while not done. - // So we schedule a nothing event and wait for that to finish. - ScheduleEvent(EVENT_SYNC); - while (HasEvents() && coreState == CORE_RUNNING) { - eventsDrain_.wait_for(eventsDrainLock_, 1); - } - } - - void FinishEventLoop() { - if (threadEnabled_) { - ScheduleEvent(EVENT_FINISH); - } - } - -protected: - virtual void ProcessEvent(Event ev) = 0; - -private: - bool threadEnabled_; - std::deque events_; - recursive_mutex eventsLock_; - recursive_mutex eventsWaitLock_; - recursive_mutex eventsDrainLock_; - condition_variable eventsWait_; - condition_variable eventsDrain_; -}; typedef ThreadEventQueue GPUThreadEventQueue; class GPUCommon : public GPUThreadEventQueue From b5ac31bbeaf61f5f6a27cb5a5717fed2a50e430a Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sat, 10 Aug 2013 09:27:06 -0700 Subject: [PATCH 2/7] Add locks to all the pspFileSystem methods. --- Core/FileSystems/MetaFileSystem.cpp | 19 +++++++++++++++++++ Core/FileSystems/MetaFileSystem.h | 5 ++++- 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/Core/FileSystems/MetaFileSystem.cpp b/Core/FileSystems/MetaFileSystem.cpp index 00ecb51ad..9beb4c6a6 100644 --- a/Core/FileSystems/MetaFileSystem.cpp +++ b/Core/FileSystems/MetaFileSystem.cpp @@ -162,6 +162,7 @@ static bool RealPath(const std::string ¤tDirectory, const std::string &inP IFileSystem *MetaFileSystem::GetHandleOwner(u32 handle) { + lock_guard guard(lock); for (size_t i = 0; i < fileSystems.size(); i++) { if (fileSystems[i].system->OwnsHandle(handle)) @@ -174,6 +175,7 @@ IFileSystem *MetaFileSystem::GetHandleOwner(u32 handle) extern u32 ioErrorCode; bool MetaFileSystem::MapFilePath(const std::string &_inpath, std::string &outpath, MountPoint **system) { + lock_guard guard(lock); std::string realpath; // Special handling: host0:command.txt (as seen in Super Monkey Ball Adventures, for example) @@ -225,6 +227,7 @@ bool MetaFileSystem::MapFilePath(const std::string &_inpath, std::string &outpat void MetaFileSystem::Mount(std::string prefix, IFileSystem *system) { + lock_guard guard(lock); MountPoint x; x.prefix=prefix; x.system=system; @@ -233,6 +236,7 @@ void MetaFileSystem::Mount(std::string prefix, IFileSystem *system) void MetaFileSystem::Shutdown() { + lock_guard guard(lock); current = 6; // Ownership is a bit convoluted. Let's just delete everything once. @@ -254,6 +258,7 @@ void MetaFileSystem::Shutdown() u32 MetaFileSystem::OpenFile(std::string filename, FileAccess access, const char *devicename) { + lock_guard guard(lock); std::string of; MountPoint *mount; if (MapFilePath(filename, of, &mount)) @@ -268,6 +273,7 @@ u32 MetaFileSystem::OpenFile(std::string filename, FileAccess access, const char PSPFileInfo MetaFileSystem::GetFileInfo(std::string filename) { + lock_guard guard(lock); std::string of; IFileSystem *system; if (MapFilePath(filename, of, &system)) @@ -283,6 +289,7 @@ PSPFileInfo MetaFileSystem::GetFileInfo(std::string filename) bool MetaFileSystem::GetHostPath(const std::string &inpath, std::string &outpath) { + lock_guard guard(lock); std::string of; IFileSystem *system; if (MapFilePath(inpath, of, &system)) { @@ -294,6 +301,7 @@ bool MetaFileSystem::GetHostPath(const std::string &inpath, std::string &outpath std::vector MetaFileSystem::GetDirListing(std::string path) { + lock_guard guard(lock); std::string of; IFileSystem *system; if (MapFilePath(path, of, &system)) @@ -309,11 +317,13 @@ std::vector MetaFileSystem::GetDirListing(std::string path) void MetaFileSystem::ThreadEnded(int threadID) { + lock_guard guard(lock); currentDir.erase(threadID); } int MetaFileSystem::ChDir(const std::string &dir) { + lock_guard guard(lock); // Retain the old path and fail if the arg is 1023 bytes or longer. if (dir.size() >= 1023) return SCE_KERNEL_ERROR_NAMETOOLONG; @@ -348,6 +358,7 @@ int MetaFileSystem::ChDir(const std::string &dir) bool MetaFileSystem::MkDir(const std::string &dirname) { + lock_guard guard(lock); std::string of; IFileSystem *system; if (MapFilePath(dirname, of, &system)) @@ -362,6 +373,7 @@ bool MetaFileSystem::MkDir(const std::string &dirname) bool MetaFileSystem::RmDir(const std::string &dirname) { + lock_guard guard(lock); std::string of; IFileSystem *system; if (MapFilePath(dirname, of, &system)) @@ -376,6 +388,7 @@ bool MetaFileSystem::RmDir(const std::string &dirname) int MetaFileSystem::RenameFile(const std::string &from, const std::string &to) { + lock_guard guard(lock); std::string of; std::string rf; IFileSystem *osystem; @@ -407,6 +420,7 @@ int MetaFileSystem::RenameFile(const std::string &from, const std::string &to) bool MetaFileSystem::RemoveFile(const std::string &filename) { + lock_guard guard(lock); std::string of; IFileSystem *system; if (MapFilePath(filename, of, &system)) @@ -421,6 +435,7 @@ bool MetaFileSystem::RemoveFile(const std::string &filename) void MetaFileSystem::CloseFile(u32 handle) { + lock_guard guard(lock); IFileSystem *sys = GetHandleOwner(handle); if (sys) sys->CloseFile(handle); @@ -428,6 +443,7 @@ void MetaFileSystem::CloseFile(u32 handle) size_t MetaFileSystem::ReadFile(u32 handle, u8 *pointer, s64 size) { + lock_guard guard(lock); IFileSystem *sys = GetHandleOwner(handle); if (sys) return sys->ReadFile(handle,pointer,size); @@ -437,6 +453,7 @@ size_t MetaFileSystem::ReadFile(u32 handle, u8 *pointer, s64 size) size_t MetaFileSystem::WriteFile(u32 handle, const u8 *pointer, s64 size) { + lock_guard guard(lock); IFileSystem *sys = GetHandleOwner(handle); if (sys) return sys->WriteFile(handle,pointer,size); @@ -446,6 +463,7 @@ size_t MetaFileSystem::WriteFile(u32 handle, const u8 *pointer, s64 size) size_t MetaFileSystem::SeekFile(u32 handle, s32 position, FileMove type) { + lock_guard guard(lock); IFileSystem *sys = GetHandleOwner(handle); if (sys) return sys->SeekFile(handle,position,type); @@ -455,6 +473,7 @@ size_t MetaFileSystem::SeekFile(u32 handle, s32 position, FileMove type) void MetaFileSystem::DoState(PointerWrap &p) { + lock_guard guard(lock); p.Do(current); // Save/load per-thread current directory map diff --git a/Core/FileSystems/MetaFileSystem.h b/Core/FileSystems/MetaFileSystem.h index 792885165..abf4b5a88 100644 --- a/Core/FileSystems/MetaFileSystem.h +++ b/Core/FileSystems/MetaFileSystem.h @@ -17,7 +17,8 @@ #pragma once -#include "FileSystem.h" +#include "native/base/mutex.h" +#include "Core/FileSystems/FileSystem.h" class MetaFileSystem : public IHandleAllocator, public IFileSystem { @@ -34,6 +35,7 @@ private: currentDir_t currentDir; std::string startingDirectory; + recursive_mutex lock; public: MetaFileSystem() @@ -94,6 +96,7 @@ public: // TODO: void IoCtl(...) void SetStartingDirectory(const std::string &dir) { + lock_guard guard(lock); startingDirectory = dir; } }; From 333cc33efbdd6312865bbea23cbea9a378fdcc71 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sat, 10 Aug 2013 09:54:14 -0700 Subject: [PATCH 3/7] Handle OpenFile() errors in a more threadsafe way. Probably needs better cleanup though. --- Core/FileSystems/MetaFileSystem.cpp | 12 ++++++++++-- Core/FileSystems/MetaFileSystem.h | 4 +++- Core/HLE/sceIo.cpp | 20 +++++++++----------- 3 files changed, 22 insertions(+), 14 deletions(-) diff --git a/Core/FileSystems/MetaFileSystem.cpp b/Core/FileSystems/MetaFileSystem.cpp index 9beb4c6a6..29c322b99 100644 --- a/Core/FileSystems/MetaFileSystem.cpp +++ b/Core/FileSystems/MetaFileSystem.cpp @@ -172,7 +172,6 @@ IFileSystem *MetaFileSystem::GetHandleOwner(u32 handle) return 0; } -extern u32 ioErrorCode; bool MetaFileSystem::MapFilePath(const std::string &_inpath, std::string &outpath, MountPoint **system) { lock_guard guard(lock); @@ -195,7 +194,7 @@ bool MetaFileSystem::MapFilePath(const std::string &_inpath, std::string &outpat //Attempt to emulate SCE_KERNEL_ERROR_NOCWD / 8002032C: may break things requiring fixes elsewhere if (inpath.find(':') == std::string::npos /* means path is relative */) { - ioErrorCode = SCE_KERNEL_ERROR_NOCWD; + lastOpenError = SCE_KERNEL_ERROR_NOCWD; WARN_LOG_REPORT(HLE, "Path is relative, but current directory not set for thread %i. returning 8002032C(SCE_KERNEL_ERROR_NOCWD) instead.", currentThread); } } @@ -256,9 +255,18 @@ void MetaFileSystem::Shutdown() startingDirectory = ""; } +u32 MetaFileSystem::OpenWithError(int &error, std::string filename, FileAccess access, const char *devicename) +{ + lock_guard guard(lock); + u32 h = OpenFile(filename, access, devicename); + error = lastOpenError; + return h; +} + u32 MetaFileSystem::OpenFile(std::string filename, FileAccess access, const char *devicename) { lock_guard guard(lock); + lastOpenError = 0; std::string of; MountPoint *mount; if (MapFilePath(filename, of, &mount)) diff --git a/Core/FileSystems/MetaFileSystem.h b/Core/FileSystems/MetaFileSystem.h index abf4b5a88..8de7dd4e8 100644 --- a/Core/FileSystems/MetaFileSystem.h +++ b/Core/FileSystems/MetaFileSystem.h @@ -35,6 +35,7 @@ private: currentDir_t currentDir; std::string startingDirectory; + int lastOpenError; recursive_mutex lock; public: @@ -74,7 +75,8 @@ public: bool GetHostPath(const std::string &inpath, std::string &outpath); std::vector GetDirListing(std::string path); - u32 OpenFile(std::string filename, FileAccess access, const char *devicename=NULL); + u32 OpenFile(std::string filename, FileAccess access, const char *devicename = NULL); + u32 OpenWithError(int &error, std::string filename, FileAccess access, const char *devicename = NULL); void CloseFile(u32 handle); size_t ReadFile(u32 handle, u8 *pointer, s64 size); size_t WriteFile(u32 handle, const u8 *pointer, s64 size); diff --git a/Core/HLE/sceIo.cpp b/Core/HLE/sceIo.cpp index 476692337..5f6e4c466 100644 --- a/Core/HLE/sceIo.cpp +++ b/Core/HLE/sceIo.cpp @@ -103,8 +103,6 @@ const int PSP_MIN_FD = 4; static int asyncNotifyEvent = -1; static SceUID fds[PSP_COUNT_FDS]; -u32 ioErrorCode = 0; - #define SCE_STM_FDIR 0x1000 #define SCE_STM_FREG 0x2000 #define SCE_STM_FLNK 0x4000 @@ -782,7 +780,7 @@ u32 sceIoLseek32Async(int id, int offset, int whence) { return 0; } -FileNode *__IoOpen(const char* filename, int flags, int mode) { +FileNode *__IoOpen(int &error, const char* filename, int flags, int mode) { //memory stick filename int access = FILEACCESS_NONE; if (flags & O_RDONLY) @@ -796,9 +794,7 @@ FileNode *__IoOpen(const char* filename, int flags, int mode) { PSPFileInfo info = pspFileSystem.GetFileInfo(filename); - ioErrorCode = 0; - - u32 h = pspFileSystem.OpenFile(filename, (FileAccess) access); + u32 h = pspFileSystem.OpenWithError(error, filename, (FileAccess) access); if (h == 0) { return NULL; } @@ -821,11 +817,12 @@ u32 sceIoOpen(const char* filename, int flags, int mode) { if (!__KernelIsDispatchEnabled()) return -1; - FileNode *f = __IoOpen(filename, flags, mode); + int error; + FileNode *f = __IoOpen(error, filename, flags, mode); if (f == NULL) { - //Timing is not accurate, aiming low for now. - if (ioErrorCode == SCE_KERNEL_ERROR_NOCWD) + // Timing is not accurate, aiming low for now. + if (error == SCE_KERNEL_ERROR_NOCWD) { ERROR_LOG(HLE, "SCE_KERNEL_ERROR_NOCWD=sceIoOpen(%s, %08x, %08x) - no current working directory", filename, flags, mode); return hleDelayResult(SCE_KERNEL_ERROR_NOCWD , "no cwd", 10000); @@ -1294,7 +1291,8 @@ u32 sceIoOpenAsync(const char *filename, int flags, int mode) if (!__KernelIsDispatchEnabled()) sceKernelResumeDispatchThread(1); - FileNode *f = __IoOpen(filename, flags, mode); + int error; + FileNode *f = __IoOpen(error, filename, flags, mode); int fd; // We have to return an fd here, which may have been destroyed when we reach Wait if it failed. @@ -1305,7 +1303,7 @@ u32 sceIoOpenAsync(const char *filename, int flags, int mode) f = new FileNode(); f->handle = kernelObjects.Create(f); f->fullpath = filename; - f->asyncResult = ERROR_ERRNO_FILE_NOT_FOUND; + f->asyncResult = error == 0 ? ERROR_ERRNO_FILE_NOT_FOUND : error; f->closePending = true; fd = __IoAllocFd(f); From 00ae8114467a13d6357d5934aa22a9187260d61d Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sat, 10 Aug 2013 13:50:21 -0700 Subject: [PATCH 4/7] Shutdown the filesystem after HLE. --- Core/System.cpp | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/Core/System.cpp b/Core/System.cpp index 6a005498d..4af24e2ce 100644 --- a/Core/System.cpp +++ b/Core/System.cpp @@ -116,6 +116,8 @@ void CPU_WaitStatus(bool (*pred)()) { cpuThreadLock.unlock(); } +void CPU_Shutdown(); + void CPU_Init() { currentCPU = &mipsr4k; numCPUs = 1; @@ -157,12 +159,7 @@ void CPU_Init() { // Why did we check for CORE_POWERDOWN here? if (!LoadFile(filename, &coreParameter.errorString)) { - pspFileSystem.Shutdown(); - CoreTiming::Shutdown(); - __KernelShutdown(); - HLEShutdown(); - host->ShutdownSound(); - Memory::Shutdown(); + CPU_Shutdown(); coreParameter.fileToStart = ""; CPU_SetState(CPU_THREAD_NOT_RUNNING); return; @@ -176,20 +173,18 @@ void CPU_Init() { } void CPU_Shutdown() { - pspFileSystem.Shutdown(); - - CoreTiming::Shutdown(); - if (g_Config.bAutoSaveSymbolMap) { host->SaveSymbolMap(); } + CoreTiming::Shutdown(); + __KernelShutdown(); + HLEShutdown(); if (coreParameter.enableSound) { host->ShutdownSound(); mixer = 0; // deleted in ShutdownSound } - __KernelShutdown(); - HLEShutdown(); + pspFileSystem.Shutdown(); Memory::Shutdown(); currentCPU = 0; } From 54ca1e212fec10e915098761d72d15e6f18bca50 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sat, 10 Aug 2013 14:02:18 -0700 Subject: [PATCH 5/7] Unmount filesystems during HLE shutdown. Fixes #3115. --- Core/FileSystems/MetaFileSystem.cpp | 14 ++++++++++++-- Core/FileSystems/MetaFileSystem.h | 7 ++++++- Core/HLE/sceIo.cpp | 30 ++++++++++++++++++++++------- 3 files changed, 41 insertions(+), 10 deletions(-) diff --git a/Core/FileSystems/MetaFileSystem.cpp b/Core/FileSystems/MetaFileSystem.cpp index 29c322b99..9b2076f4c 100644 --- a/Core/FileSystems/MetaFileSystem.cpp +++ b/Core/FileSystems/MetaFileSystem.cpp @@ -16,6 +16,7 @@ // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. #include +#include #include "Common/StringUtils.h" #include "Core/FileSystems/MetaFileSystem.h" #include "Core/HLE/sceKernelThread.h" @@ -228,11 +229,20 @@ void MetaFileSystem::Mount(std::string prefix, IFileSystem *system) { lock_guard guard(lock); MountPoint x; - x.prefix=prefix; - x.system=system; + x.prefix = prefix; + x.system = system; fileSystems.push_back(x); } +void MetaFileSystem::Unmount(std::string prefix, IFileSystem *system) +{ + lock_guard guard(lock); + MountPoint x; + x.prefix = prefix; + x.system = system; + fileSystems.erase(std::remove(fileSystems.begin(), fileSystems.end(), x), fileSystems.end()); +} + void MetaFileSystem::Shutdown() { lock_guard guard(lock); diff --git a/Core/FileSystems/MetaFileSystem.h b/Core/FileSystems/MetaFileSystem.h index 8de7dd4e8..b7d99ebc5 100644 --- a/Core/FileSystems/MetaFileSystem.h +++ b/Core/FileSystems/MetaFileSystem.h @@ -28,6 +28,11 @@ private: { std::string prefix; IFileSystem *system; + + bool operator == (const MountPoint &other) const + { + return prefix == other.prefix && system == other.system; + } }; std::vector fileSystems; @@ -45,7 +50,7 @@ public: } void Mount(std::string prefix, IFileSystem *system); - void Unmount(IFileSystem *system); + void Unmount(std::string prefix, IFileSystem *system); void ThreadEnded(int threadID); diff --git a/Core/HLE/sceIo.cpp b/Core/HLE/sceIo.cpp index 5f6e4c466..f34ff7d9c 100644 --- a/Core/HLE/sceIo.cpp +++ b/Core/HLE/sceIo.cpp @@ -292,6 +292,13 @@ void __IoAsyncNotify(u64 userdata, int cyclesLate) { } } +static DirectoryFileSystem *memstickSystem = NULL; +#ifdef ANDROID +static VFSFileSystem *flash0System = NULL; +#else +static DirectoryFileSystem *flash0System = NULL; +#endif + void __IoInit() { INFO_LOG(HLE, "Starting up I/O..."); @@ -303,16 +310,16 @@ void __IoInit() { std::string flash0path; GetSysDirectories(memstickpath, flash0path); - DirectoryFileSystem *memstick = new DirectoryFileSystem(&pspFileSystem, memstickpath); + memstickSystem = new DirectoryFileSystem(&pspFileSystem, memstickpath); #ifdef ANDROID - VFSFileSystem *flash0 = new VFSFileSystem(&pspFileSystem, "flash0"); + flash0System = new VFSFileSystem(&pspFileSystem, "flash0"); #else - DirectoryFileSystem *flash0 = new DirectoryFileSystem(&pspFileSystem, flash0path); + flash0System = new DirectoryFileSystem(&pspFileSystem, flash0path); #endif - pspFileSystem.Mount("ms0:", memstick); - pspFileSystem.Mount("fatms0:", memstick); - pspFileSystem.Mount("fatms:", memstick); - pspFileSystem.Mount("flash0:", flash0); + pspFileSystem.Mount("ms0:", memstickSystem); + pspFileSystem.Mount("fatms0:", memstickSystem); + pspFileSystem.Mount("fatms:", memstickSystem); + pspFileSystem.Mount("flash0:", flash0System); __KernelListenThreadEnd(&TellFsThreadEnded); @@ -326,6 +333,15 @@ void __IoDoState(PointerWrap &p) { } void __IoShutdown() { + pspFileSystem.Unmount("ms0:", memstickSystem); + pspFileSystem.Unmount("fatms0:", memstickSystem); + pspFileSystem.Unmount("fatms:", memstickSystem); + pspFileSystem.Unmount("flash0:", flash0System); + + delete memstickSystem; + memstickSystem = NULL; + delete flash0System; + flash0System = NULL; } u32 __IoGetFileHandleFromId(u32 id, u32 &outError) From f68ebfe230a6304d977ab8b5c32c865978ad7c8f Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sat, 10 Aug 2013 14:04:23 -0700 Subject: [PATCH 6/7] Fix savestates while not running. Fixes #2791. --- Core/SaveState.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/Core/SaveState.cpp b/Core/SaveState.cpp index d015e44ca..5e48f5441 100644 --- a/Core/SaveState.cpp +++ b/Core/SaveState.cpp @@ -88,6 +88,7 @@ namespace SaveState if (Core_IsInactive() && __KernelIsRunning()) { // Warning: this may run on a different thread. + needsProcess = true; Process(); } else From 3bba464451daebf6fe1aaa4d347e011436ca5c11 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sat, 10 Aug 2013 14:04:42 -0700 Subject: [PATCH 7/7] Add one more missing sceCcc func. --- Core/HLE/sceCcc.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Core/HLE/sceCcc.cpp b/Core/HLE/sceCcc.cpp index a47a95fec..ebd41a6b6 100644 --- a/Core/HLE/sceCcc.cpp +++ b/Core/HLE/sceCcc.cpp @@ -431,6 +431,12 @@ int sceCccIsValidJIS(u32 c) return c != 0; } +int sceCccIsValidUnicode(u32 c) +{ + WARN_LOG(HLE, "UNIMPL sceCccIsValidUnicode(%08x)", c); + return c != 0; +} + u32 sceCccSetErrorCharUTF8(u32 c) { DEBUG_LOG(HLE, "sceCccSetErrorCharUTF8(%08x)", c); @@ -507,6 +513,7 @@ const HLEFunction sceCcc[] = {0x76e33e9c, WrapI_U, "sceCccIsValidUCS2"}, {0xd2b18485, WrapI_U, "sceCccIsValidUCS4"}, {0xa2d5d209, WrapI_U, "sceCccIsValidJIS"}, + {0xbd11eef3, WrapI_U, "sceCccIsValidUnicode"}, {0x17e1d813, WrapU_U, "sceCccSetErrorCharUTF8"}, {0xb8476cf4, WrapU_U, "sceCccSetErrorCharUTF16"}, {0xc56949ad, WrapU_U, "sceCccSetErrorCharSJIS"},