mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-09-05 20:25:25 +02:00
ThreadEvent: Add management functions.
Currently never being triggered, though.
This commit is contained in:
@@ -596,6 +596,8 @@ KernelObject *KernelObjectPool::CreateByIDType(int type) {
|
||||
return __KernelFileNodeObject();
|
||||
case PPSSPP_KERNEL_TMID_DirList:
|
||||
return __KernelDirListingObject();
|
||||
case SCE_KERNEL_TMID_ThreadEventHandler:
|
||||
return __KernelThreadEventHandlerObject();
|
||||
|
||||
default:
|
||||
ERROR_LOG(COMMON, "Unable to load state: could not find object type %d.", type);
|
||||
@@ -786,10 +788,6 @@ const HLEFunction ThreadManForUser[] =
|
||||
{0X278C0DF5, &WrapI_IU<sceKernelWaitThreadEnd>, "sceKernelWaitThreadEnd", 'i', "ix" },
|
||||
{0XD59EAD2F, &WrapI_I<sceKernelWakeupThread>, "sceKernelWakeupThread", 'i', "i" }, //AI Go, audio?
|
||||
|
||||
{0X0C106E53, nullptr, "sceKernelRegisterThreadEventHandler", '?', "" },
|
||||
{0X72F3C145, nullptr, "sceKernelReleaseThreadEventHandler", '?', "" },
|
||||
{0X369EEB6B, nullptr, "sceKernelReferThreadEventHandlerStatus", '?', "" },
|
||||
|
||||
{0x349d6d6c, &sceKernelCheckCallback, "sceKernelCheckCallback", 'i', "" },
|
||||
{0XE81CAF8F, &WrapI_CUU<sceKernelCreateCallback>, "sceKernelCreateCallback", 'i', "sxx" },
|
||||
{0XEDBA5844, &WrapI_I<sceKernelDeleteCallback>, "sceKernelDeleteCallback", 'i', "i" },
|
||||
@@ -864,6 +862,9 @@ const HLEFunction ThreadManForUser[] =
|
||||
{0x0E927AED, &_sceKernelReturnFromTimerHandler, "_sceKernelReturnFromTimerHandler", 'v', "" },
|
||||
{0X532A522E, &WrapV_I<_sceKernelExitThread>, "_sceKernelExitThread", 'v', "i" },
|
||||
|
||||
{0x0C106E53, &WrapI_CIUUU<sceKernelRegisterThreadEventHandler>, "sceKernelRegisterThreadEventHandler", 'i', "sixxx", },
|
||||
{0x72F3C145, &WrapI_I<sceKernelReleaseThreadEventHandler>, "sceKernelReleaseThreadEventHandler", 'i', "i" },
|
||||
{0x369EEB6B, &WrapI_IU<sceKernelReferThreadEventHandlerStatus>, "sceKernelReferThreadEventHandlerStatus", 'i', "ip" },
|
||||
|
||||
// Shouldn't hook this up. No games should import this function manually and call it.
|
||||
// {0x6E9EA350, _sceKernelReturnFromCallback,"_sceKernelReturnFromCallback"},
|
||||
|
||||
@@ -3470,3 +3470,92 @@ int LoadExecForUser_362A956B()
|
||||
Memory::Write_U32(-1, parameterArea + 8);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const SceUID SCE_TE_THREADID_ALL_USER = 0xFFFFFFF0;
|
||||
enum {
|
||||
THREADEVENT_CREATE = 1,
|
||||
THREADEVENT_START = 2,
|
||||
THREADEVENT_EXIT = 4,
|
||||
THREADEVENT_DELETE = 8,
|
||||
THREADEVENT_KNOWN = THREADEVENT_CREATE | THREADEVENT_START | THREADEVENT_EXIT | THREADEVENT_DELETE,
|
||||
};
|
||||
|
||||
struct NativeThreadEventHandler {
|
||||
u32 size;
|
||||
char name[KERNELOBJECT_MAX_NAME_LENGTH + 1];
|
||||
SceUID threadID;
|
||||
u32 mask;
|
||||
u32 handlerPtr;
|
||||
u32 commonArg;
|
||||
};
|
||||
|
||||
struct ThreadEventHandler : public KernelObject {
|
||||
const char *GetName() { return nteh.name; }
|
||||
const char *GetTypeName() { return "ThreadEventHandler"; }
|
||||
static u32 GetMissingErrorCode() { return SCE_KERNEL_ERROR_UNKNOWN_TEID; }
|
||||
static int GetStaticIDType() { return SCE_KERNEL_TMID_ThreadEventHandler; }
|
||||
int GetIDType() const { return SCE_KERNEL_TMID_ThreadEventHandler; }
|
||||
|
||||
virtual void DoState(PointerWrap &p) {
|
||||
auto s = p.Section("ThreadEventHandler", 1);
|
||||
if (!s)
|
||||
return;
|
||||
|
||||
p.Do(nteh);
|
||||
}
|
||||
|
||||
NativeThreadEventHandler nteh;
|
||||
};
|
||||
|
||||
KernelObject *__KernelThreadEventHandlerObject() {
|
||||
// Default object to load from state.
|
||||
return new ThreadEventHandler;
|
||||
}
|
||||
|
||||
SceUID sceKernelRegisterThreadEventHandler(const char *name, SceUID threadID, u32 mask, u32 handlerPtr, u32 commonArg) {
|
||||
if (!name) {
|
||||
return hleReportError(SCEKERNEL, SCE_KERNEL_ERROR_ERROR, "invalid name");
|
||||
}
|
||||
if (threadID == 0) {
|
||||
return hleReportError(SCEKERNEL, SCE_KERNEL_ERROR_ILLEGAL_ATTR, "invalid thread id");
|
||||
}
|
||||
u32 error;
|
||||
if (kernelObjects.Get<Thread>(threadID, error) == NULL && threadID != SCE_TE_THREADID_ALL_USER) {
|
||||
return hleReportError(SCEKERNEL, error, "bad thread id");
|
||||
}
|
||||
if ((mask & ~THREADEVENT_KNOWN) != 0) {
|
||||
return hleReportError(SCEKERNEL, SCE_KERNEL_ERROR_ILLEGAL_MASK, "invalid event mask");
|
||||
}
|
||||
|
||||
auto teh = new ThreadEventHandler;
|
||||
teh->nteh.size = sizeof(teh->nteh);
|
||||
strncpy(teh->nteh.name, name, KERNELOBJECT_MAX_NAME_LENGTH);
|
||||
teh->nteh.name[KERNELOBJECT_MAX_NAME_LENGTH] = '\0';
|
||||
teh->nteh.threadID = threadID;
|
||||
teh->nteh.mask = mask;
|
||||
teh->nteh.handlerPtr = handlerPtr;
|
||||
teh->nteh.commonArg = commonArg;
|
||||
|
||||
SceUID uid = kernelObjects.Create(teh);
|
||||
|
||||
return hleLogSuccessI(SCEKERNEL, uid);
|
||||
}
|
||||
|
||||
int sceKernelReleaseThreadEventHandler(SceUID uid) {
|
||||
return hleLogSuccessI(SCEKERNEL, kernelObjects.Destroy<ThreadEventHandler>(uid));
|
||||
}
|
||||
|
||||
int sceKernelReferThreadEventHandlerStatus(SceUID uid, u32 infoPtr) {
|
||||
u32 error;
|
||||
auto teh = kernelObjects.Get<ThreadEventHandler>(uid, error);
|
||||
if (!teh) {
|
||||
return hleReportError(SCEKERNEL, error, "bad handler id");
|
||||
}
|
||||
|
||||
if (Memory::IsValidAddress(infoPtr) && Memory::Read_U32(infoPtr) != 0) {
|
||||
Memory::WriteStruct(infoPtr, &teh->nteh);
|
||||
return hleLogSuccessI(SCEKERNEL, 0);
|
||||
} else {
|
||||
return hleLogDebug(SCEKERNEL, 0, "struct size was 0");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -320,3 +320,8 @@ void __KernelChangeThreadState(SceUID threadId, ThreadStatus newStatus);
|
||||
|
||||
int LoadExecForUser_362A956B();
|
||||
int sceKernelRegisterExitCallback(SceUID cbId);
|
||||
|
||||
KernelObject *__KernelThreadEventHandlerObject();
|
||||
SceUID sceKernelRegisterThreadEventHandler(const char *name, SceUID threadID, u32 mask, u32 handlerPtr, u32 commonArg);
|
||||
int sceKernelReleaseThreadEventHandler(SceUID uid);
|
||||
int sceKernelReferThreadEventHandlerStatus(SceUID uid, u32 infoPtr);
|
||||
|
||||
Reference in New Issue
Block a user