mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-10-16 16:00:30 +02:00
Merge branch 'master' of https://github.com/artart78/ppsspp into artart78-master
This commit is contained in:
commit
6bed1afb72
40 files changed
+979
-849
No files matched your search
@@ -28,6 +28,7 @@
|
||||
#include "sceKernelThread.h"
|
||||
#include "sceKernelModule.h"
|
||||
#include "sceKernelInterrupt.h"
|
||||
#include "sceKernelCallback.h"
|
||||
|
||||
#include <queue>
|
||||
|
||||
@@ -109,13 +110,6 @@ struct NativeThread
|
||||
int numReleases;
|
||||
};
|
||||
|
||||
struct CallbackNotification
|
||||
{
|
||||
SceUID cbid;
|
||||
int count;
|
||||
int arg;
|
||||
};
|
||||
|
||||
class Thread : public KernelObject
|
||||
{
|
||||
public:
|
||||
@@ -318,14 +312,28 @@ void __KernelNotifyCallback(SceUID threadID, SceUID cbid, u32 notifyArg)
|
||||
return;
|
||||
}
|
||||
}
|
||||
CallbackNotification cb;
|
||||
cb.cbid = cbid;
|
||||
cb.arg = notifyArg;
|
||||
cb.count = 1;
|
||||
//CallbackNotification cb;
|
||||
//cb.cbid = cbid;
|
||||
//cb.arg = notifyArg;
|
||||
//cb.count = 1;
|
||||
}
|
||||
// TODO: error checking
|
||||
}
|
||||
|
||||
CallbackNotification *__KernelGetCallbackNotification(SceUID cbid)
|
||||
{
|
||||
u32 error;
|
||||
Thread *t = kernelObjects.Get<Thread>(__KernelGetCurThread(), error);
|
||||
for (size_t i = 0; i < t->callbacks.size(); t++)
|
||||
{
|
||||
if (t->callbacks[i].cbid == cbid)
|
||||
{
|
||||
return &t->callbacks[i];
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void sceKernelReferThreadStatus()
|
||||
{
|
||||
SceUID threadID = PARAM(0);
|
||||
@@ -449,7 +457,7 @@ void __KernelLoadContext(ThreadContext *ctx)
|
||||
// If any changes were made, it will context switch
|
||||
bool __KernelTriggerWait(WaitType type, int id, bool dontSwitch)
|
||||
{
|
||||
bool doneAnything = false;
|
||||
//bool doneAnything = false;
|
||||
|
||||
for (std::vector<Thread *>::iterator iter = threadqueue.begin(); iter != threadqueue.end(); iter++)
|
||||
{
|
||||
@@ -464,7 +472,7 @@ bool __KernelTriggerWait(WaitType type, int id, bool dontSwitch)
|
||||
{
|
||||
t->nt.status = THREADSTATUS_READY;
|
||||
}
|
||||
doneAnything = true;
|
||||
//doneAnything = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -536,7 +544,7 @@ void __KernelScheduleWakeup(SceUID threadID, int usFromNow)
|
||||
|
||||
void __KernelRemoveFromThreadQueue(Thread *t)
|
||||
{
|
||||
for (int i = 0; i < threadqueue.size(); i++)
|
||||
for (u32 i = 0; i < threadqueue.size(); i++)
|
||||
{
|
||||
if (threadqueue[i] == t)
|
||||
{
|
||||
@@ -549,9 +557,11 @@ void __KernelRemoveFromThreadQueue(Thread *t)
|
||||
|
||||
void __KernelReSchedule(const char *reason)
|
||||
{
|
||||
if (__IsInInterrupt())
|
||||
// cancel rescheduling when in interrupt or callback, otherwise everything will be fucked up
|
||||
if (__IsInInterrupt() || __KernelInCallback())
|
||||
{
|
||||
reason = "WTF";
|
||||
return;
|
||||
}
|
||||
// round-robin scheduler
|
||||
// seems to work ?
|
||||
@@ -587,26 +597,20 @@ retry:
|
||||
|
||||
if (bestthread != -1)
|
||||
{
|
||||
//u32 pc = MIPS_GetNextPC();
|
||||
//MIPS_ClearDelaySlot();
|
||||
if (currentThread) // It might just have been deleted.
|
||||
{
|
||||
__KernelSaveContext(¤tThread->context);
|
||||
// currentThread->context.pc = pc;
|
||||
DEBUG_LOG(HLE,"Context saved (%s): %i - %s - pc: %08x", reason, currentThread->GetUID(), currentThread->GetName(), currentMIPS->pc);
|
||||
}
|
||||
//currentThread->nt.status = THREADSTATUS_READY;
|
||||
currentThread = threadqueue[bestthread];
|
||||
if (currentThread) // It might just have been deleted.
|
||||
{
|
||||
__KernelSaveContext(¤tThread->context);
|
||||
DEBUG_LOG(HLE,"Context saved (%s): %i - %s - pc: %08x", reason, currentThread->GetUID(), currentThread->GetName(), currentMIPS->pc);
|
||||
}
|
||||
currentThread = threadqueue[bestthread];
|
||||
__KernelLoadContext(¤tThread->context);
|
||||
DEBUG_LOG(HLE,"Context loaded (%s): %i - %s - pc: %08x", reason, currentThread->GetUID(), currentThread->GetName(), currentMIPS->pc);
|
||||
//currentThread->nt.status = THREADSTATUS_RUNNING;
|
||||
// currentMIPS->pc -= 4; //compensate for +=4 ADJUSTPC
|
||||
DEBUG_LOG(HLE,"Context loaded (%s): %i - %s - pc: %08x", reason, currentThread->GetUID(), currentThread->GetName(), currentMIPS->pc);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
_dbg_assert_msg_(HLE,0,"No threads available to schedule! There should be at least one idle thread available.");
|
||||
// This shouldn't happen anymore now that we have idle threads.
|
||||
_dbg_assert_msg_(HLE,0,"No threads available to schedule! There should be at least one idle thread available.");
|
||||
// This shouldn't happen anymore now that we have idle threads.
|
||||
|
||||
// No threads want to run : increase timers, skip time in general
|
||||
// MessageBox(0,"Error: no thread to transition to",0,0);
|
||||
@@ -745,7 +749,7 @@ void sceKernelCreateThread()
|
||||
}
|
||||
|
||||
|
||||
void sceKernelStartThread()
|
||||
u32 sceKernelStartThread()
|
||||
{
|
||||
int threadToStartID = PARAM(0);
|
||||
u32 argSize = PARAM(1);
|
||||
@@ -755,41 +759,45 @@ void sceKernelStartThread()
|
||||
{
|
||||
u32 error;
|
||||
Thread *startThread = kernelObjects.Get<Thread>(threadToStartID, error);
|
||||
if (startThread == 0)
|
||||
{
|
||||
ERROR_LOG(HLE,"%08x=sceKernelStartThread(thread=%i, argSize=%i, argPtr= %08x): thread does not exist!",
|
||||
error,threadToStartID,argSize,argBlockPtr)
|
||||
return error;
|
||||
}
|
||||
|
||||
if (startThread->nt.status != THREADSTATUS_DORMANT)
|
||||
{
|
||||
//Not dormant, WTF?
|
||||
RETURN(ERROR_KERNEL_THREAD_IS_NOT_DORMANT);
|
||||
return;
|
||||
//Not dormant, WTF?
|
||||
return ERROR_KERNEL_THREAD_IS_NOT_DORMANT;
|
||||
}
|
||||
|
||||
INFO_LOG(HLE,"sceKernelStartThread(thread=%i, argSize=%i, argPtr= %08x )",
|
||||
threadToStartID,argSize,argBlockPtr);
|
||||
|
||||
RETURN(0); //return success (this does not exit this function)
|
||||
|
||||
startThread->nt.status = THREADSTATUS_READY;
|
||||
u32 sp = startThread->context.r[MIPS_REG_SP];
|
||||
if (argBlockPtr)
|
||||
{
|
||||
startThread->context.r[MIPS_REG_A0] = argSize;
|
||||
startThread->context.r[MIPS_REG_A1] = sp;
|
||||
}
|
||||
else
|
||||
{
|
||||
startThread->context.r[MIPS_REG_A0] = 0;
|
||||
startThread->context.r[MIPS_REG_A1] = 0;
|
||||
}
|
||||
startThread->context.r[MIPS_REG_GP] = startThread->nt.gpreg;
|
||||
if (argBlockPtr)
|
||||
{
|
||||
startThread->context.r[MIPS_REG_A0] = argSize;
|
||||
startThread->context.r[MIPS_REG_A1] = sp;
|
||||
}
|
||||
else
|
||||
{
|
||||
startThread->context.r[MIPS_REG_A0] = 0;
|
||||
startThread->context.r[MIPS_REG_A1] = 0;
|
||||
}
|
||||
startThread->context.r[MIPS_REG_GP] = startThread->nt.gpreg;
|
||||
|
||||
//now copy argument to stack
|
||||
for (int i = 0; i < (int)argSize; i++)
|
||||
Memory::Write_U8(Memory::Read_U8(argBlockPtr + i), sp + i);
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
ERROR_LOG(HLE,"thread %i trying to start itself", threadToStartID);
|
||||
RETURN(-1);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user