mirror of
https://github.com/libretro/ppsspp.git
synced 2024-11-30 20:01:00 +00:00
204 lines
6.4 KiB
C++
204 lines
6.4 KiB
C++
// Copyright (c) 2012- PPSSPP Project.
|
|
|
|
// This program is free software: you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, version 2.0 or later versions.
|
|
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License 2.0 for more details.
|
|
|
|
// A copy of the GPL 2.0 should have been included with the program.
|
|
// If not, see http://www.gnu.org/licenses/
|
|
|
|
// Official git repository and contact information can be found at
|
|
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
|
|
|
|
#pragma once
|
|
|
|
|
|
// There's a good description of the thread scheduling rules in:
|
|
// http://code.google.com/p/jpcsp/source/browse/trunk/src/jpcsp/HLE/modules150/ThreadManForUser.java
|
|
|
|
#include "sceKernelModule.h"
|
|
#include "HLE.h"
|
|
|
|
|
|
void sceKernelChangeThreadPriority();
|
|
void sceKernelCreateThread();
|
|
void sceKernelDelayThread();
|
|
void sceKernelDelayThreadCB();
|
|
void sceKernelDeleteThread();
|
|
void sceKernelExitDeleteThread();
|
|
void sceKernelExitThread();
|
|
void _sceKernelExitThread();
|
|
void sceKernelGetThreadId();
|
|
void sceKernelGetThreadCurrentPriority();
|
|
void sceKernelStartThread(SceUID threadToStartID, u32 argSize, u32 argBlockPtr);
|
|
u32 sceKernelSuspendDispatchThread();
|
|
u32 sceKernelResumeDispatchThread(u32 suspended);
|
|
void sceKernelWaitThreadEnd();
|
|
void sceKernelReferThreadStatus();
|
|
void sceKernelChangeCurrentThreadAttr();
|
|
void sceKernelRotateThreadReadyQueue();
|
|
void sceKernelCheckThreadStack();
|
|
void sceKernelSuspendThread();
|
|
void sceKernelResumeThread();
|
|
void sceKernelWakeupThread();
|
|
void sceKernelCancelWakeupThread();
|
|
void sceKernelTerminateDeleteThread();
|
|
void sceKernelWaitThreadEndCB();
|
|
void sceKernelGetThreadExitStatus();
|
|
void sceKernelGetThreadmanIdType();
|
|
|
|
|
|
enum WaitType //probably not the real values
|
|
{
|
|
WAITTYPE_NONE = 0,
|
|
WAITTYPE_SLEEP = 1,
|
|
WAITTYPE_DELAY = 2,
|
|
WAITTYPE_SEMA = 3,
|
|
WAITTYPE_EVENTFLAG = 4,
|
|
WAITTYPE_MBX = 5,
|
|
WAITTYPE_VPL = 6,
|
|
WAITTYPE_FPL = 7,
|
|
WAITTYPE_MSGPIPE = 8, // fake
|
|
WAITTYPE_THREADEND = 9,
|
|
WAITTYPE_AUDIOCHANNEL = 10, // this is fake, should be replaced with 8 eventflags ( ?? )
|
|
WAITTYPE_UMD = 11, // this is fake, should be replaced with 1 eventflag ( ?? )
|
|
WAITTYPE_VBLANK = 12, // fake
|
|
WAITTYPE_MUTEX = 13,
|
|
WAITTYPE_LWMUTEX = 14,
|
|
// Remember to update sceKernelThread.cpp's waitTypeStrings to match.
|
|
};
|
|
|
|
|
|
struct ThreadContext
|
|
{
|
|
void reset();
|
|
u32 r[32];
|
|
float f[32];
|
|
float v[128];
|
|
u32 vfpuCtrl[16];
|
|
|
|
u32 hi;
|
|
u32 lo;
|
|
u32 pc;
|
|
u32 fpcond;
|
|
|
|
u32 fcr0;
|
|
u32 fcr31;
|
|
};
|
|
|
|
// Internal API, used by implementations of kernel functions
|
|
|
|
void __KernelThreadingInit();
|
|
void __KernelThreadingShutdown();
|
|
|
|
void __KernelScheduleWakeup(int usFromNow, int threadnumber);
|
|
SceUID __KernelGetCurThread();
|
|
|
|
void __KernelSaveContext(ThreadContext *ctx);
|
|
void __KernelLoadContext(ThreadContext *ctx);
|
|
|
|
// TODO: Replace this with __KernelResumeThread over time as it's misguided.
|
|
bool __KernelTriggerWait(WaitType type, int id, bool dontSwitch = false);
|
|
u32 __KernelResumeThreadFromWait(SceUID threadID); // can return an error value
|
|
u32 __KernelResumeThreadFromWait(SceUID threadID, int retval);
|
|
|
|
u32 __KernelGetWaitValue(SceUID threadID, u32 &error);
|
|
u32 __KernelGetWaitTimeoutPtr(SceUID threadID, u32 &error);
|
|
SceUID __KernelGetWaitID(SceUID threadID, WaitType type, u32 &error);
|
|
void __KernelWaitCurThread(WaitType type, SceUID waitId, u32 waitValue, u32 timeoutPtr, bool processCallbacks);
|
|
void __KernelReSchedule(const char *reason = "no reason");
|
|
void __KernelReSchedule(bool doCallbacks, const char *reason);
|
|
|
|
// Registered callback types
|
|
enum RegisteredCallbackType {
|
|
THREAD_CALLBACK_UMD = 0,
|
|
THREAD_CALLBACK_IO = 1,
|
|
THREAD_CALLBACK_MEMORYSTICK = 2,
|
|
THREAD_CALLBACK_MEMORYSTICK_FAT = 3,
|
|
THREAD_CALLBACK_POWER = 4,
|
|
THREAD_CALLBACK_EXIT = 5,
|
|
THREAD_CALLBACK_USER_DEFINED = 6,
|
|
THREAD_CALLBACK_SIZE = 7,
|
|
THREAD_CALLBACK_NUM_TYPES = 8,
|
|
};
|
|
|
|
// These operate on the current thread
|
|
u32 __KernelRegisterCallback(RegisteredCallbackType type, SceUID cbId);
|
|
u32 __KernelUnregisterCallback(RegisteredCallbackType type, SceUID cbId);
|
|
|
|
// If cbId == -1, all the callbacks of the type on all the threads get notified.
|
|
// If not, only this particular callback gets notified.
|
|
u32 __KernelNotifyCallbackType(RegisteredCallbackType type, SceUID cbId, int notifyArg);
|
|
|
|
SceUID __KernelGetCurThread();
|
|
SceUID __KernelGetCurThreadModuleId();
|
|
void __KernelSetupRootThread(SceUID moduleId, int args, const char *argp, int prio, int stacksize, int attr); //represents the real PSP elf loader, run before execution
|
|
void __KernelStartIdleThreads();
|
|
void __KernelReturnFromThread(); // Called as HLE function
|
|
u32 __KernelGetThreadPrio(SceUID id);
|
|
|
|
void __KernelIdle();
|
|
|
|
u32 __KernelMipsCallReturnAddress();
|
|
u32 __KernelInterruptReturnAddress(); // TODO: remove
|
|
|
|
// Internal access - used by sceSetGeCallback
|
|
u32 __KernelCreateCallback(const char *name, u32 entrypoint, u32 signalArg);
|
|
|
|
void sceKernelCreateCallback();
|
|
void sceKernelDeleteCallback();
|
|
void sceKernelNotifyCallback();
|
|
void sceKernelCancelCallback();
|
|
void sceKernelGetCallbackCount();
|
|
void sceKernelCheckCallback();
|
|
void sceKernelGetCallbackCount();
|
|
void sceKernelReferCallbackStatus();
|
|
void __KernelReturnFromMipsCall(); // Called as HLE function
|
|
bool __KernelInCallback();
|
|
|
|
// Should be called by (nearly) all ...CB functions.
|
|
bool __KernelCheckCallbacks();
|
|
class Thread;
|
|
void __KernelSwitchContext(Thread *target, const char *reason);
|
|
bool __KernelExecutePendingMipsCalls();
|
|
void __KernelNotifyCallback(RegisteredCallbackType type, SceUID threadId, SceUID cbId, int notifyArg);
|
|
|
|
// A call into game code. These can be pending on a thread.
|
|
// Similar to Callback-s (NOT CallbackInfos) in JPCSP.
|
|
class Action;
|
|
struct MipsCall {
|
|
u32 entryPoint;
|
|
u32 cbId;
|
|
u32 args[6];
|
|
int numArgs;
|
|
Action *doAfter;
|
|
u32 savedIdRegister;
|
|
u32 savedRa;
|
|
u32 savedPc;
|
|
u32 savedV0;
|
|
u32 savedV1;
|
|
bool returnVoid;
|
|
const char *tag;
|
|
};
|
|
enum ThreadStatus
|
|
{
|
|
THREADSTATUS_RUNNING = 1,
|
|
THREADSTATUS_READY = 2,
|
|
THREADSTATUS_WAIT = 4,
|
|
THREADSTATUS_SUSPEND = 8,
|
|
THREADSTATUS_DORMANT = 16,
|
|
THREADSTATUS_DEAD = 32,
|
|
|
|
THREADSTATUS_WAITSUSPEND = THREADSTATUS_WAIT | THREADSTATUS_SUSPEND
|
|
};
|
|
|
|
void __KernelChangeThreadState(Thread *thread, ThreadStatus newStatus);
|
|
|
|
typedef void (*ThreadCallback)(SceUID threadID);
|
|
void __KernelListenThreadEnd(ThreadCallback callback);
|