mirror of
https://github.com/libretro/ppsspp.git
synced 2024-12-13 11:38:34 +00:00
Start with sceIoOpenAsync() cleaning up async io.
Now it actually fires the callback as necessary. Some games care.
This commit is contained in:
parent
29504da03b
commit
60e6fa514a
@ -25,6 +25,7 @@
|
|||||||
#include "HLE.h"
|
#include "HLE.h"
|
||||||
#include "../MIPS/MIPS.h"
|
#include "../MIPS/MIPS.h"
|
||||||
#include "../HW/MemoryStick.h"
|
#include "../HW/MemoryStick.h"
|
||||||
|
#include "Core/CoreTiming.h"
|
||||||
|
|
||||||
#include "../FileSystems/FileSystem.h"
|
#include "../FileSystems/FileSystem.h"
|
||||||
#include "../FileSystems/MetaFileSystem.h"
|
#include "../FileSystems/MetaFileSystem.h"
|
||||||
@ -90,6 +91,7 @@ typedef u64 SceIores;
|
|||||||
typedef u32 (*DeferredAction)(SceUID id, int param);
|
typedef u32 (*DeferredAction)(SceUID id, int param);
|
||||||
DeferredAction defAction = 0;
|
DeferredAction defAction = 0;
|
||||||
u32 defParam = 0;
|
u32 defParam = 0;
|
||||||
|
int asyncNotifyEvent = -1;
|
||||||
|
|
||||||
#define SCE_STM_FDIR 0x1000
|
#define SCE_STM_FDIR 0x1000
|
||||||
#define SCE_STM_FREG 0x2000
|
#define SCE_STM_FREG 0x2000
|
||||||
@ -187,15 +189,35 @@ public:
|
|||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
|
void __IoCompleteAsyncIO(SceUID id);
|
||||||
|
|
||||||
static void TellFsThreadEnded (SceUID threadID) {
|
static void TellFsThreadEnded (SceUID threadID) {
|
||||||
pspFileSystem.ThreadEnded(threadID);
|
pspFileSystem.ThreadEnded(threadID);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Async IO seems to work roughly like this:
|
||||||
|
// 1. Game calls SceIo*Async() to start the process.
|
||||||
|
// 2. This runs a thread with a customizable priority.
|
||||||
|
// 3. The operation runs, which takes an inconsistent amount of time from UMD.
|
||||||
|
// 4. Once done (regardless of other syscalls), the fd-registered callback is notified.
|
||||||
|
// 5. The game can find out via *CB() or sceKernelCheckCallback().
|
||||||
|
// 6. At this point, the fd is STILL not usable.
|
||||||
|
// 7. One must call sceIoWaitAsync / sceIoWaitAsyncCB / sceIoPollAsync / possibly sceIoGetAsyncStat.
|
||||||
|
// 8. Finally, the fd is usable (or closed via sceIoCloseAsync.) Presumably the io thread has joined now.
|
||||||
|
|
||||||
|
// TODO: We don't do any of that yet.
|
||||||
|
// For now, let's at least delay the callback mnotification.
|
||||||
|
void __IoAsyncNotify(u64 userdata, int cyclesLate) {
|
||||||
|
__IoCompleteAsyncIO((SceUID) userdata);
|
||||||
|
}
|
||||||
|
|
||||||
void __IoInit() {
|
void __IoInit() {
|
||||||
INFO_LOG(HLE, "Starting up I/O...");
|
INFO_LOG(HLE, "Starting up I/O...");
|
||||||
|
|
||||||
MemoryStick_SetFatState(PSP_FAT_MEMORYSTICK_STATE_ASSIGNED);
|
MemoryStick_SetFatState(PSP_FAT_MEMORYSTICK_STATE_ASSIGNED);
|
||||||
|
|
||||||
|
asyncNotifyEvent = CoreTiming::RegisterEvent("IoAsyncNotify", __IoAsyncNotify);
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
|
|
||||||
char path_buffer[_MAX_PATH], drive[_MAX_DRIVE] ,dir[_MAX_DIR], file[_MAX_FNAME], ext[_MAX_EXT];
|
char path_buffer[_MAX_PATH], drive[_MAX_DRIVE] ,dir[_MAX_DIR], file[_MAX_FNAME], ext[_MAX_EXT];
|
||||||
@ -242,6 +264,9 @@ void __IoDoState(PointerWrap &p) {
|
|||||||
if (defAction != NULL) {
|
if (defAction != NULL) {
|
||||||
WARN_LOG(HLE, "FIXME: Savestate failure: deferred IO not saved yet.");
|
WARN_LOG(HLE, "FIXME: Savestate failure: deferred IO not saved yet.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
p.Do(asyncNotifyEvent);
|
||||||
|
CoreTiming::RestoreRegisterEvent(asyncNotifyEvent, "IoAsyncNotify", __IoAsyncNotify);
|
||||||
}
|
}
|
||||||
|
|
||||||
void __IoShutdown() {
|
void __IoShutdown() {
|
||||||
@ -987,8 +1012,9 @@ u32 sceIoOpenAsync(const char *filename, int flags, int mode)
|
|||||||
DEBUG_LOG(HLE, "sceIoOpenAsync() sorta implemented");
|
DEBUG_LOG(HLE, "sceIoOpenAsync() sorta implemented");
|
||||||
u32 fd = sceIoOpen(filename, flags, mode);
|
u32 fd = sceIoOpen(filename, flags, mode);
|
||||||
|
|
||||||
// TODO: This can't actually have a callback yet, but if it's set before waiting, it should be called.
|
// TODO: Timing is very inconsistent. From ms0, 10ms - 20ms depending on filesize/dir depth? From umd, can take > 1s.
|
||||||
__IoCompleteAsyncIO(fd);
|
// For now let's aim low.
|
||||||
|
CoreTiming::ScheduleEvent(usToCycles(100), asyncNotifyEvent, fd);
|
||||||
|
|
||||||
// We have to return an fd here, which may have been destroyed when we reach Wait if it failed.
|
// We have to return an fd here, which may have been destroyed when we reach Wait if it failed.
|
||||||
if (fd == ERROR_ERRNO_FILE_NOT_FOUND)
|
if (fd == ERROR_ERRNO_FILE_NOT_FOUND)
|
||||||
|
Loading…
Reference in New Issue
Block a user