Merge pull request #12432 from unknownbrackets/io-async

Fix change async priority when thread already running
This commit is contained in:
Henrik Rydgård 2019-10-20 19:56:46 +02:00 committed by GitHub
commit 1856dabb24
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 44 additions and 13 deletions

View File

@ -87,6 +87,10 @@ bool HLEHelperThread::Stopped() {
return KernelIsThreadDormant(id_);
}
void HLEHelperThread::ChangePriority(u32 prio) {
KernelChangeThreadPriority(id_, prio);
}
void HLEHelperThread::Forget() {
id_ = 0;
entry_ = 0;

View File

@ -32,6 +32,7 @@ public:
void Start(u32 a0, u32 a1);
void Terminate();
bool Stopped();
void ChangePriority(u32 prio);
// For savestates.
void Forget();

View File

@ -737,6 +737,15 @@ void __IoShutdown() {
ioManager.Shutdown();
}
for (int i = 0; i < PSP_COUNT_FDS; ++i) {
asyncParams[i].op = IoAsyncOp::NONE;
asyncParams[i].priority = -1;
if (asyncThreads[i])
asyncThreads[i]->Forget();
delete asyncThreads[i];
asyncThreads[i] = nullptr;
}
pspFileSystem.Unmount("ms0:", memstickSystem);
pspFileSystem.Unmount("fatms0:", memstickSystem);
pspFileSystem.Unmount("fatms:", memstickSystem);
@ -1964,6 +1973,10 @@ static int sceIoChangeAsyncPriority(int id, int priority) {
return hleLogError(SCEIO, error, "bad file descriptor");
}
if (asyncThreads[id] && !asyncThreads[id]->Stopped()) {
asyncThreads[id]->ChangePriority(priority);
}
asyncParams[id].priority = priority;
return hleLogSuccessI(SCEIO, 0);
}

View File

@ -1641,9 +1641,9 @@ void __KernelStopThread(SceUID threadID, int exitStatus, const char *reason)
// Stopped threads are never waiting.
t->nt.waitType = WAITTYPE_NONE;
t->nt.waitID = 0;
}
else
} else {
ERROR_LOG_REPORT(SCEKERNEL, "__KernelStopThread: thread %d does not exist", threadID);
}
}
u32 __KernelDeleteThread(SceUID threadID, int exitStatus, const char *reason)
@ -2418,6 +2418,28 @@ int sceKernelChangeCurrentThreadAttr(u32 clearAttr, u32 setAttr) {
return hleLogSuccessI(SCEKERNEL, 0);
}
// Assumes validated parameters.
bool KernelChangeThreadPriority(SceUID threadID, int priority) {
u32 error;
Thread *thread = kernelObjects.Get<Thread>(threadID, error);
if (thread) {
int old = thread->nt.currentPriority;
threadReadyQueue.remove(old, threadID);
thread->nt.currentPriority = priority;
threadReadyQueue.prepare(thread->nt.currentPriority);
if (thread->isRunning()) {
thread->nt.status = (thread->nt.status & ~THREADSTATUS_RUNNING) | THREADSTATUS_READY;
}
if (thread->isReady()) {
threadReadyQueue.push_back(thread->nt.currentPriority, threadID);
}
return true;
} else {
return false;
}
}
int sceKernelChangeThreadPriority(SceUID threadID, int priority) {
if (threadID == 0) {
threadID = __KernelGetCurThread();
@ -2444,17 +2466,7 @@ int sceKernelChangeThreadPriority(SceUID threadID, int priority) {
return hleLogError(SCEKERNEL, SCE_KERNEL_ERROR_ILLEGAL_PRIORITY, "bogus priority");
}
int old = thread->nt.currentPriority;
threadReadyQueue.remove(old, threadID);
thread->nt.currentPriority = priority;
threadReadyQueue.prepare(thread->nt.currentPriority);
if (thread->isRunning()) {
thread->nt.status = (thread->nt.status & ~THREADSTATUS_RUNNING) | THREADSTATUS_READY;
}
if (thread->isReady()) {
threadReadyQueue.push_back(thread->nt.currentPriority, threadID);
}
KernelChangeThreadPriority(threadID, priority);
hleEatCycles(450);
hleReSchedule("change thread priority");

View File

@ -162,6 +162,7 @@ KernelObject *__KernelCallbackObject();
void __KernelScheduleWakeup(int threadnumber, s64 usFromNow);
SceUID __KernelGetCurThread();
int KernelCurThreadPriority();
bool KernelChangeThreadPriority(SceUID threadID, int priority);
u32 __KernelGetCurThreadStack();
u32 __KernelGetCurThreadStackStart();
const char *__KernelGetThreadName(SceUID threadID);