Io: Store sceIoChangeAsyncPriority value.

Also some prep for async threaded IO.
This commit is contained in:
Unknown W. Brackets 2019-07-28 15:43:19 -07:00
parent dd804660c9
commit f1037248f1
2 changed files with 61 additions and 9 deletions

View file

@ -33,6 +33,7 @@
#include "Core/Host.h" #include "Core/Host.h"
#include "Core/SaveState.h" #include "Core/SaveState.h"
#include "Core/HLE/HLE.h" #include "Core/HLE/HLE.h"
#include "Core/HLE/HLEHelperThread.h"
#include "Core/HLE/FunctionWrappers.h" #include "Core/HLE/FunctionWrappers.h"
#include "Core/HLE/sceDisplay.h" #include "Core/HLE/sceDisplay.h"
#include "Core/HLE/sceKernel.h" #include "Core/HLE/sceKernel.h"
@ -159,6 +160,46 @@ struct SceIoDirEnt {
u32_le d_private; u32_le d_private;
}; };
enum class IoAsyncOp {
NONE,
OPEN,
CLOSE,
READ,
WRITE,
SEEK,
IOCTL,
};
struct IoAsyncParams {
IoAsyncOp op = IoAsyncOp::NONE;
int priority = -1;
union {
struct {
u32 filenameAddr;
int flags;
int mode;
} open;
struct {
u32 addr;
u32 size;
} std;
struct {
s64 pos;
int whence;
} seek;
struct {
u32 cmd;
u32 inAddr;
u32 inSize;
u32 outAddr;
u32 outSize;
} ioctl;
};
};
static IoAsyncParams asyncParams[PSP_COUNT_FDS];
static HLEHelperThread *asyncThreads[PSP_COUNT_FDS]{};
class FileNode : public KernelObject { class FileNode : public KernelObject {
public: public:
FileNode() : callbackID(0), callbackArg(0), asyncResult(0), hasAsyncResult(false), pendingAsyncResult(false), sectorBlockMode(false), closePending(false), npdrm(0), pgdInfo(NULL) {} FileNode() : callbackID(0), callbackArg(0), asyncResult(0), hasAsyncResult(false), pendingAsyncResult(false), sectorBlockMode(false), closePending(false), npdrm(0), pgdInfo(NULL) {}
@ -335,7 +376,6 @@ static void __IoFreeFd(int fd, u32 &error) {
// TODO: Closed files are a bit special: until the fd is reused (?), the async result is still available. // TODO: Closed files are a bit special: until the fd is reused (?), the async result is still available.
// Clearly a buffer is used, it doesn't seem like they are actually kernel objects. // Clearly a buffer is used, it doesn't seem like they are actually kernel objects.
// TODO: We don't do any of that yet.
// For now, let's at least delay the callback notification. // For now, let's at least delay the callback notification.
static void __IoAsyncNotify(u64 userdata, int cyclesLate) { static void __IoAsyncNotify(u64 userdata, int cyclesLate) {
int fd = (int) userdata; int fd = (int) userdata;
@ -1407,6 +1447,7 @@ static u32 sceIoOpen(const char *filename, int flags, int mode) {
return id; return id;
} else { } else {
DEBUG_LOG(SCEIO, "%i=sceIoOpen(%s, %08x, %08x)", id, filename, flags, mode); DEBUG_LOG(SCEIO, "%i=sceIoOpen(%s, %08x, %08x)", id, filename, flags, mode);
asyncParams[id].priority = -1;
// Timing is not accurate, aiming low for now. // Timing is not accurate, aiming low for now.
return hleDelayResult(id, "file opened", 100); return hleDelayResult(id, "file opened", 100);
} }
@ -1881,15 +1922,20 @@ static u32 sceIoChdir(const char *dirname) {
return pspFileSystem.ChDir(dirname); return pspFileSystem.ChDir(dirname);
} }
static int sceIoChangeAsyncPriority(int id, int priority) static int sceIoChangeAsyncPriority(int id, int priority) {
{
// priority = -1 is valid // priority = -1 is valid
if (priority < 0 && priority != -1) { if (priority != -1 && (priority < 0x08 || priority > 0x77)) {
ERROR_LOG(SCEIO, "sceIoChangeAsyncPriority : Illegal Priority %i", priority); return hleLogError(SCEIO, SCE_KERNEL_ERROR_ILLEGAL_PRIORITY, "illegal priority %d", priority);
return SCE_KERNEL_ERROR_ILLEGAL_PRIORITY;
} }
WARN_LOG(SCEIO, "UNIMPL sceIoChangeAsyncPriority(%d, %d)", id, priority);
return 0; u32 error;
FileNode *f = __IoGetFd(id, error);
if (!f) {
return hleLogError(SCEIO, error, "bad file descriptor");
}
asyncParams[id].priority = priority;
return hleLogSuccessI(SCEIO, 0);
} }
static int sceIoCloseAsync(int id) static int sceIoCloseAsync(int id)
@ -2569,6 +2615,11 @@ static u32 sceKernelRegisterStdoutPipe(u32 msgPipeUID) {
return 0; return 0;
} }
static int IoAsyncFinish(int id) {
// TODO
return 0;
}
KernelObject *__KernelFileNodeObject() { KernelObject *__KernelFileNodeObject() {
return new FileNode; return new FileNode;
} }
@ -2615,6 +2666,7 @@ const HLEFunction IoFileMgrForUser[] = {
{0x35DBD746, &WrapI_IU<sceIoWaitAsyncCB>, "sceIoWaitAsyncCB", 'i', "iP" }, {0x35DBD746, &WrapI_IU<sceIoWaitAsyncCB>, "sceIoWaitAsyncCB", 'i', "iP" },
{0xE23EEC33, &WrapI_IU<sceIoWaitAsync>, "sceIoWaitAsync", 'i', "iP" }, {0xE23EEC33, &WrapI_IU<sceIoWaitAsync>, "sceIoWaitAsync", 'i', "iP" },
{0X5C2BE2CC, &WrapU_UIU<sceIoGetFdList>, "sceIoGetFdList", 'i', "xip" }, {0X5C2BE2CC, &WrapU_UIU<sceIoGetFdList>, "sceIoGetFdList", 'i', "xip" },
{0x13370001, &WrapI_I<IoAsyncFinish>, "__IoAsyncFinish", 'i', "i" },
}; };
void Register_IoFileMgrForUser() { void Register_IoFileMgrForUser() {

View file

@ -2131,7 +2131,7 @@ void __KernelReturnFromThread()
Thread *thread = __GetCurrentThread(); Thread *thread = __GetCurrentThread();
_dbg_assert_msg_(SCEKERNEL, thread != NULL, "Returned from a NULL thread."); _dbg_assert_msg_(SCEKERNEL, thread != NULL, "Returned from a NULL thread.");
INFO_LOG(SCEKERNEL,"__KernelReturnFromThread: %d", exitStatus); DEBUG_LOG(SCEKERNEL, "__KernelReturnFromThread: %d", exitStatus);
__KernelStopThread(currentThread, exitStatus, "thread returned"); __KernelStopThread(currentThread, exitStatus, "thread returned");
hleReSchedule("thread returned"); hleReSchedule("thread returned");