mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-02-21 06:33:22 +00:00
Io: Update async priority more correctly.
When an operation finishes, whether it uses the priority from the first operation or the current thread's priority depends on sdk version, it seems. This also makes it resolve the default priority on open, so that changing the default afterward doesn't affect already open descriptors.
This commit is contained in:
parent
0a5ec48382
commit
593e48b865
@ -16,9 +16,11 @@
|
||||
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
|
||||
|
||||
#include "Common/ChunkFile.h"
|
||||
#include "Core/CoreTiming.h"
|
||||
#include "Core/MemMapHelpers.h"
|
||||
#include "Core/HLE/HLE.h"
|
||||
#include "Core/HLE/HLEHelperThread.h"
|
||||
#include "Core/HLE/KernelWaitHelpers.h"
|
||||
#include "Core/HLE/sceKernelThread.h"
|
||||
#include "Core/HLE/sceKernelMemory.h"
|
||||
#include "Core/MIPS/MIPSCodeUtils.h"
|
||||
@ -91,6 +93,13 @@ void HLEHelperThread::ChangePriority(u32 prio) {
|
||||
KernelChangeThreadPriority(id_, prio);
|
||||
}
|
||||
|
||||
void HLEHelperThread::Resume(WaitType waitType, SceUID uid, int result) {
|
||||
bool res = HLEKernel::ResumeFromWait(id_, waitType, uid, result);
|
||||
if (!res) {
|
||||
ERROR_LOG(HLE, "Failed to wake helper thread from wait");
|
||||
}
|
||||
}
|
||||
|
||||
void HLEHelperThread::Forget() {
|
||||
id_ = 0;
|
||||
entry_ = 0;
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include "Core/HLE/sceKernel.h"
|
||||
|
||||
class PointerWrap;
|
||||
enum WaitType : int;
|
||||
|
||||
class HLEHelperThread {
|
||||
public:
|
||||
@ -33,10 +34,15 @@ public:
|
||||
void Terminate();
|
||||
bool Stopped();
|
||||
void ChangePriority(u32 prio);
|
||||
void Resume(WaitType waitType, SceUID uid, int result);
|
||||
|
||||
// For savestates.
|
||||
void Forget();
|
||||
|
||||
u32 Entry() {
|
||||
return entry_;
|
||||
}
|
||||
|
||||
private:
|
||||
void AllocEntry(u32 size);
|
||||
void Create(const char *threadName, u32 prio, int stacksize);
|
||||
|
@ -295,8 +295,11 @@ public:
|
||||
|
||||
u64 __IoCompleteAsyncIO(FileNode *f);
|
||||
|
||||
static void IoAsyncCleanupThread(int fd, bool force = false) {
|
||||
if (asyncThreads[fd] && (asyncThreads[fd]->Stopped() || force)) {
|
||||
static void IoAsyncCleanupThread(int fd) {
|
||||
if (asyncThreads[fd]) {
|
||||
if (!asyncThreads[fd]->Stopped()) {
|
||||
asyncThreads[fd]->Terminate();
|
||||
}
|
||||
delete asyncThreads[fd];
|
||||
asyncThreads[fd] = nullptr;
|
||||
}
|
||||
@ -438,8 +441,6 @@ static void __IoAsyncNotify(u64 userdata, int cyclesLate) {
|
||||
if (f->closePending) {
|
||||
__IoFreeFd(fd, error);
|
||||
}
|
||||
|
||||
IoAsyncCleanupThread(fd);
|
||||
}
|
||||
}
|
||||
|
||||
@ -488,8 +489,6 @@ static void __IoSyncNotify(u64 userdata, int cyclesLate) {
|
||||
|
||||
HLEKernel::ResumeFromWait(threadID, WAITTYPE_IO, fd, result);
|
||||
f->waitingSyncThreads.erase(std::remove(f->waitingSyncThreads.begin(), f->waitingSyncThreads.end(), threadID), f->waitingSyncThreads.end());
|
||||
|
||||
IoAsyncCleanupThread(fd);
|
||||
}
|
||||
|
||||
static void __IoAsyncBeginCallback(SceUID threadID, SceUID prevCallbackId) {
|
||||
@ -778,12 +777,20 @@ u32 __IoGetFileHandleFromId(u32 id, u32 &outError)
|
||||
}
|
||||
|
||||
static void IoStartAsyncThread(int id, FileNode *f) {
|
||||
IoAsyncCleanupThread(id, true);
|
||||
int priority = asyncParams[id].priority == -1 ? asyncDefaultPriority : asyncParams[id].priority;
|
||||
if (priority == -1)
|
||||
priority = KernelCurThreadPriority();
|
||||
asyncThreads[id] = new HLEHelperThread("SceIoAsync", "IoFileMgrForUser", "__IoAsyncFinish", priority, 0x200);
|
||||
asyncThreads[id]->Start(id, 0);
|
||||
if (asyncThreads[id] && !asyncThreads[id]->Stopped()) {
|
||||
// Wake the thread up.
|
||||
if (asyncParams[id].priority == -1 && sceKernelGetCompiledSdkVersion() >= 0x04020000) {
|
||||
asyncThreads[id]->ChangePriority(KernelCurThreadPriority());
|
||||
}
|
||||
asyncThreads[id]->Resume(WAITTYPE_ASYNCIO, id, 0);
|
||||
} else {
|
||||
IoAsyncCleanupThread(id);
|
||||
int priority = asyncParams[id].priority;
|
||||
if (priority == -1)
|
||||
priority = KernelCurThreadPriority();
|
||||
asyncThreads[id] = new HLEHelperThread("SceIoAsync", "IoFileMgrForUser", "__IoAsyncFinish", priority, 0x200);
|
||||
asyncThreads[id]->Start(id, 0);
|
||||
}
|
||||
f->pendingAsyncResult = true;
|
||||
}
|
||||
|
||||
@ -1491,7 +1498,7 @@ static u32 sceIoOpen(const char *filename, int flags, int mode) {
|
||||
return id;
|
||||
} else {
|
||||
DEBUG_LOG(SCEIO, "%i=sceIoOpen(%s, %08x, %08x)", id, filename, flags, mode);
|
||||
asyncParams[id].priority = -1;
|
||||
asyncParams[id].priority = asyncDefaultPriority;
|
||||
// Timing is not accurate, aiming low for now.
|
||||
return hleDelayResult(id, "file opened", 100);
|
||||
}
|
||||
@ -1984,6 +1991,9 @@ static int sceIoChangeAsyncPriority(int id, int priority) {
|
||||
}
|
||||
|
||||
if (asyncThreads[id] && !asyncThreads[id]->Stopped()) {
|
||||
if (priority == -1) {
|
||||
priority = KernelCurThreadPriority();
|
||||
}
|
||||
asyncThreads[id]->ChangePriority(priority);
|
||||
}
|
||||
|
||||
@ -2101,7 +2111,6 @@ static u32 sceIoGetAsyncStat(int id, u32 poll, u32 address) {
|
||||
DEBUG_LOG(SCEIO, "%lli = sceIoGetAsyncStat(%i, %i, %08x)", f->asyncResult, id, poll, address);
|
||||
Memory::Write_U64((u64) f->asyncResult, address);
|
||||
f->hasAsyncResult = false;
|
||||
IoAsyncCleanupThread(id);
|
||||
|
||||
if (f->closePending) {
|
||||
__IoFreeFd(id, error);
|
||||
@ -2139,7 +2148,6 @@ static int sceIoWaitAsync(int id, u32 address) {
|
||||
}
|
||||
Memory::Write_U64((u64) f->asyncResult, address);
|
||||
f->hasAsyncResult = false;
|
||||
IoAsyncCleanupThread(id);
|
||||
|
||||
if (f->closePending) {
|
||||
__IoFreeFd(id, error);
|
||||
@ -2173,7 +2181,6 @@ static int sceIoWaitAsyncCB(int id, u32 address) {
|
||||
} else if (f->hasAsyncResult) {
|
||||
Memory::Write_U64((u64) f->asyncResult, address);
|
||||
f->hasAsyncResult = false;
|
||||
IoAsyncCleanupThread(id);
|
||||
|
||||
if (f->closePending) {
|
||||
__IoFreeFd(id, error);
|
||||
@ -2197,7 +2204,6 @@ static u32 sceIoPollAsync(int id, u32 address) {
|
||||
} else if (f->hasAsyncResult) {
|
||||
Memory::Write_U64((u64) f->asyncResult, address);
|
||||
f->hasAsyncResult = false;
|
||||
IoAsyncCleanupThread(id);
|
||||
|
||||
if (f->closePending) {
|
||||
__IoFreeFd(id, error);
|
||||
@ -2671,6 +2677,8 @@ static int IoAsyncFinish(int id) {
|
||||
if (f) {
|
||||
// Reset this so the Io funcs don't reject the request.
|
||||
f->pendingAsyncResult = false;
|
||||
// Reset the PC back so we will run again on resume.
|
||||
currentMIPS->pc = asyncThreads[id]->Entry();
|
||||
|
||||
auto ¶ms = asyncParams[id];
|
||||
|
||||
@ -2732,6 +2740,7 @@ static int IoAsyncFinish(int id) {
|
||||
|
||||
__IoSchedAsync(f, id, us);
|
||||
__KernelWaitCurThread(WAITTYPE_ASYNCIO, id, 0, 0, false, "async io");
|
||||
hleSkipDeadbeef();
|
||||
|
||||
params.op = IoAsyncOp::NONE;
|
||||
return 0;
|
||||
|
@ -80,7 +80,7 @@ struct SceKernelSysClock {
|
||||
|
||||
// TODO: Map these to PSP wait types. Most of these are wrong.
|
||||
// remember to update the waitTypeNames array in sceKernelThread.cpp when changing these
|
||||
enum WaitType
|
||||
enum WaitType : int
|
||||
{
|
||||
WAITTYPE_NONE = 0,
|
||||
WAITTYPE_SLEEP = 1,
|
||||
|
Loading…
x
Reference in New Issue
Block a user