~ppsspp/ppsspp/ppsspp-1.2.2

« back to all changes in this revision

Viewing changes to Core/HLE/sceKernelThread.h

  • Committer: Sérgio Benjamim
  • Date: 2016-04-25 02:30:18 UTC
  • Revision ID: sergio_br2@yahoo.com.br-20160425023018-wk3rd7nu30fejjzz
1.2.2 source.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// Copyright (c) 2012- PPSSPP Project.
 
2
 
 
3
// This program is free software: you can redistribute it and/or modify
 
4
// it under the terms of the GNU General Public License as published by
 
5
// the Free Software Foundation, version 2.0 or later versions.
 
6
 
 
7
// This program is distributed in the hope that it will be useful,
 
8
// but WITHOUT ANY WARRANTY; without even the implied warranty of
 
9
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
10
// GNU General Public License 2.0 for more details.
 
11
 
 
12
// A copy of the GPL 2.0 should have been included with the program.
 
13
// If not, see http://www.gnu.org/licenses/
 
14
 
 
15
// Official git repository and contact information can be found at
 
16
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
 
17
 
 
18
#pragma once
 
19
 
 
20
#include <string>
 
21
#include <vector>
 
22
 
 
23
#include "Common/CommonTypes.h"
 
24
#include "Core/HLE/sceKernel.h"
 
25
 
 
26
// There's a good description of the thread scheduling rules in:
 
27
// http://code.google.com/p/jpcsp/source/browse/trunk/src/jpcsp/HLE/modules150/ThreadManForUser.java
 
28
 
 
29
class Thread;
 
30
 
 
31
int sceKernelChangeThreadPriority(SceUID threadID, int priority);
 
32
SceUID __KernelCreateThreadInternal(const char *threadName, SceUID moduleID, u32 entry, u32 prio, int stacksize, u32 attr);
 
33
int __KernelCreateThread(const char *threadName, SceUID moduleID, u32 entry, u32 prio, int stacksize, u32 attr, u32 optionAddr);
 
34
int sceKernelCreateThread(const char *threadName, u32 entry, u32 prio, int stacksize, u32 attr, u32 optionAddr);
 
35
int sceKernelDelayThread(u32 usec);
 
36
int sceKernelDelayThreadCB(u32 usec);
 
37
int sceKernelDelaySysClockThread(u32 sysclockAddr);
 
38
int sceKernelDelaySysClockThreadCB(u32 sysclockAddr);
 
39
void __KernelStopThread(SceUID threadID, int exitStatus, const char *reason);
 
40
u32 __KernelDeleteThread(SceUID threadID, int exitStatus, const char *reason);
 
41
int sceKernelDeleteThread(int threadHandle);
 
42
void sceKernelExitDeleteThread(int exitStatus);
 
43
void sceKernelExitThread(int exitStatus);
 
44
void _sceKernelExitThread(int exitStatus);
 
45
SceUID sceKernelGetThreadId();
 
46
int sceKernelGetThreadCurrentPriority();
 
47
int __KernelStartThread(SceUID threadToStartID, int argSize, u32 argBlockPtr, bool forceArgs = false);
 
48
int __KernelStartThreadValidate(SceUID threadToStartID, int argSize, u32 argBlockPtr, bool forceArgs = false);
 
49
int sceKernelStartThread(SceUID threadToStartID, int argSize, u32 argBlockPtr);
 
50
u32 sceKernelSuspendDispatchThread();
 
51
u32 sceKernelResumeDispatchThread(u32 suspended);
 
52
int sceKernelWaitThreadEnd(SceUID threadID, u32 timeoutPtr);
 
53
u32 sceKernelReferThreadStatus(u32 uid, u32 statusPtr);
 
54
u32 sceKernelReferThreadRunStatus(u32 uid, u32 statusPtr);
 
55
int sceKernelReleaseWaitThread(SceUID threadID);
 
56
int sceKernelChangeCurrentThreadAttr(u32 clearAttr, u32 setAttr);
 
57
int sceKernelRotateThreadReadyQueue(int priority);
 
58
int sceKernelCheckThreadStack();
 
59
int sceKernelSuspendThread(SceUID threadID);
 
60
int sceKernelResumeThread(SceUID threadID);
 
61
int sceKernelWakeupThread(SceUID threadID);
 
62
int sceKernelCancelWakeupThread(SceUID threadID);
 
63
int sceKernelSleepThread();
 
64
int sceKernelSleepThreadCB();
 
65
int sceKernelTerminateDeleteThread(int threadno);
 
66
int sceKernelTerminateThread(SceUID threadID);
 
67
int sceKernelWaitThreadEndCB(SceUID threadID, u32 timeoutPtr);
 
68
int sceKernelGetThreadExitStatus(SceUID threadID);
 
69
u32 sceKernelGetThreadmanIdType(u32);
 
70
u32 sceKernelGetThreadmanIdList(u32 type, u32 readBufPtr, u32 readBufSize, u32 idCountPtr);
 
71
u32 sceKernelExtendThreadStack(u32 size, u32 entryAddr, u32 entryParameter);
 
72
 
 
73
struct SceKernelSysClock {
 
74
        u32_le lo;
 
75
        u32_le hi;
 
76
};
 
77
 
 
78
 
 
79
// TODO: Map these to PSP wait types.  Most of these are wrong.
 
80
// remember to update the waitTypeNames array in sceKernelThread.cpp when changing these
 
81
enum WaitType
 
82
{
 
83
        WAITTYPE_NONE         = 0,
 
84
        WAITTYPE_SLEEP        = 1,
 
85
        WAITTYPE_DELAY        = 2,
 
86
        WAITTYPE_SEMA         = 3,
 
87
        WAITTYPE_EVENTFLAG    = 4,
 
88
        WAITTYPE_MBX          = 5,
 
89
        WAITTYPE_VPL          = 6,
 
90
        WAITTYPE_FPL          = 7,
 
91
        WAITTYPE_MSGPIPE      = 8,  // fake
 
92
        WAITTYPE_THREADEND    = 9,
 
93
        WAITTYPE_AUDIOCHANNEL = 10, // this is fake, should be replaced with 8 eventflags   ( ?? )
 
94
        WAITTYPE_UMD          = 11, // this is fake, should be replaced with 1 eventflag    ( ?? )
 
95
        WAITTYPE_VBLANK       = 12, // fake
 
96
        WAITTYPE_MUTEX        = 13,
 
97
        WAITTYPE_LWMUTEX      = 14,
 
98
        WAITTYPE_CTRL         = 15,
 
99
        WAITTYPE_IO           = 16,
 
100
        WAITTYPE_GEDRAWSYNC   = 17,
 
101
        WAITTYPE_GELISTSYNC   = 18,
 
102
        WAITTYPE_MODULE       = 19,
 
103
        WAITTYPE_HLEDELAY     = 20,
 
104
        WAITTYPE_TLSPL        = 21,
 
105
        WAITTYPE_VMEM         = 22,
 
106
        WAITTYPE_ASYNCIO      = 23,
 
107
 
 
108
        NUM_WAITTYPES
 
109
};
 
110
 
 
111
const char *getWaitTypeName(WaitType type);
 
112
 
 
113
// Suspend wait and timeout while a thread enters a callback.
 
114
typedef void (* WaitBeginCallbackFunc)(SceUID threadID, SceUID prevCallbackId);
 
115
// Resume wait and timeout as a thread exits a callback.
 
116
typedef void (* WaitEndCallbackFunc)(SceUID threadID, SceUID prevCallbackId);
 
117
 
 
118
void __KernelRegisterWaitTypeFuncs(WaitType type, WaitBeginCallbackFunc beginFunc, WaitEndCallbackFunc endFunc);
 
119
 
 
120
struct ThreadContext
 
121
{
 
122
        void reset();
 
123
 
 
124
        // r must be followed by f.
 
125
        u32 r[32];
 
126
        union {
 
127
                float f[32];
 
128
                u32 fi[32];
 
129
                int fs[32];
 
130
        };
 
131
        union {
 
132
                float v[128];
 
133
                u32 vi[128];
 
134
        };
 
135
        u32 vfpuCtrl[16];
 
136
 
 
137
        union {
 
138
                struct {
 
139
                        u32 pc;
 
140
 
 
141
                        u32 lo;
 
142
                        u32 hi;
 
143
 
 
144
                        u32 fcr31;
 
145
                        u32 fpcond;
 
146
                };
 
147
                u32 other[6];
 
148
        };
 
149
};
 
150
 
 
151
// Internal API, used by implementations of kernel functions
 
152
 
 
153
void __KernelThreadingInit();
 
154
void __KernelThreadingDoState(PointerWrap &p);
 
155
void __KernelThreadingDoStateLate(PointerWrap &p);
 
156
void __KernelThreadingShutdown();
 
157
KernelObject *__KernelThreadObject();
 
158
KernelObject *__KernelCallbackObject();
 
159
 
 
160
void __KernelScheduleWakeup(int threadnumber, s64 usFromNow);
 
161
SceUID __KernelGetCurThread();
 
162
u32 __KernelGetCurThreadStack();
 
163
u32 __KernelGetCurThreadStackStart();
 
164
const char *__KernelGetThreadName(SceUID threadID);
 
165
 
 
166
void __KernelSaveContext(ThreadContext *ctx, bool vfpuEnabled);
 
167
void __KernelLoadContext(ThreadContext *ctx, bool vfpuEnabled);
 
168
 
 
169
u32 __KernelResumeThreadFromWait(SceUID threadID, u32 retval); // can return an error value
 
170
u32 __KernelResumeThreadFromWait(SceUID threadID, u64 retval);
 
171
 
 
172
inline u32 __KernelResumeThreadFromWait(SceUID threadID, int retval)
 
173
{
 
174
        return __KernelResumeThreadFromWait(threadID, (u32)retval);
 
175
}
 
176
 
 
177
inline u32 __KernelResumeThreadFromWait(SceUID threadID, s64 retval)
 
178
{
 
179
        return __KernelResumeThreadFromWait(threadID, (u64)retval);
 
180
}
 
181
 
 
182
u32 __KernelGetWaitValue(SceUID threadID, u32 &error);
 
183
u32 __KernelGetWaitTimeoutPtr(SceUID threadID, u32 &error);
 
184
SceUID __KernelGetWaitID(SceUID threadID, WaitType type, u32 &error);
 
185
SceUID __KernelGetCurrentCallbackID(SceUID threadID, u32 &error);
 
186
void __KernelWaitCurThread(WaitType type, SceUID waitId, u32 waitValue, u32 timeoutPtr, bool processCallbacks, const char *reason);
 
187
void __KernelWaitCallbacksCurThread(WaitType type, SceUID waitID, u32 waitValue, u32 timeoutPtr);
 
188
void __KernelReSchedule(const char *reason = "no reason");
 
189
void __KernelReSchedule(bool doCallbacks, const char *reason);
 
190
 
 
191
SceUID __KernelGetCurThread();
 
192
SceUID __KernelGetCurThreadModuleId();
 
193
SceUID __KernelSetupRootThread(SceUID moduleId, int args, const char *argp, int prio, int stacksize, int attr); //represents the real PSP elf loader, run before execution
 
194
void __KernelStartIdleThreads(SceUID moduleId);
 
195
void __KernelReturnFromThread();  // Called as HLE function
 
196
u32 __KernelGetThreadPrio(SceUID id);
 
197
bool __KernelThreadSortPriority(SceUID thread1, SceUID thread2);
 
198
bool __KernelIsDispatchEnabled();
 
199
void __KernelReturnFromExtendStack();
 
200
 
 
201
void __KernelIdle();
 
202
 
 
203
u32 __KernelMipsCallReturnAddress();
 
204
u32 __KernelInterruptReturnAddress();  // TODO: remove
 
205
 
 
206
SceUID sceKernelCreateCallback(const char *name, u32 entrypoint, u32 signalArg);
 
207
int sceKernelDeleteCallback(SceUID cbId);
 
208
int sceKernelNotifyCallback(SceUID cbId, int notifyArg);
 
209
int sceKernelCancelCallback(SceUID cbId);
 
210
int sceKernelGetCallbackCount(SceUID cbId);
 
211
void sceKernelCheckCallback();
 
212
int sceKernelReferCallbackStatus(SceUID cbId, u32 statusAddr);
 
213
 
 
214
class Action;
 
215
 
 
216
// Not an official Callback object, just calls a mips function on the current thread.
 
217
void __KernelDirectMipsCall(u32 entryPoint, Action *afterAction, u32 args[], int numargs, bool reschedAfter);
 
218
 
 
219
void __KernelReturnFromMipsCall();  // Called as HLE function
 
220
bool __KernelInCallback();
 
221
 
 
222
// Should be called by (nearly) all ...CB functions.
 
223
bool __KernelCheckCallbacks();
 
224
bool __KernelForceCallbacks();
 
225
bool __KernelCurHasReadyCallbacks();
 
226
void __KernelSwitchContext(Thread *target, const char *reason);
 
227
bool __KernelExecutePendingMipsCalls(Thread *currentThread, bool reschedAfter);
 
228
void __KernelNotifyCallback(SceUID cbId, int notifyArg);
 
229
 
 
230
// Switch to an idle / non-user thread, if not already on one.
 
231
// Returns whether a switch occurred.
 
232
bool __KernelSwitchOffThread(const char *reason);
 
233
bool __KernelSwitchToThread(SceUID threadID, const char *reason);
 
234
 
 
235
// Set a thread's return address to a specific FakeSyscall nid.
 
236
// Discards old RA.  Only useful for special threads that do special things on exit.
 
237
u32 __KernelSetThreadRA(SceUID threadID, u32 nid);
 
238
 
 
239
// A call into game code. These can be pending on a thread.
 
240
// Similar to Callback-s (NOT CallbackInfos) in JPCSP.
 
241
typedef Action *(*ActionCreator)();
 
242
Action *__KernelCreateAction(int actionType);
 
243
int __KernelRegisterActionType(ActionCreator creator);
 
244
void __KernelRestoreActionType(int actionType, ActionCreator creator);
 
245
 
 
246
struct MipsCall {
 
247
        MipsCall()
 
248
        {
 
249
                doAfter = NULL;
 
250
        }
 
251
 
 
252
        u32 entryPoint;
 
253
        u32 cbId;
 
254
        u32 args[6];
 
255
        int numArgs;
 
256
        Action *doAfter;
 
257
        u32 savedRa;
 
258
        u32 savedPc;
 
259
        u32 savedV0;
 
260
        u32 savedV1;
 
261
        std::string tag;
 
262
        u32 savedId;
 
263
        bool reschedAfter;
 
264
 
 
265
        void DoState(PointerWrap &p);
 
266
        void setReturnValue(u32 value);
 
267
        void setReturnValue(u64 value);
 
268
        inline void setReturnValue(int value)
 
269
        {
 
270
                setReturnValue((u32)value);
 
271
        }
 
272
        inline void setReturnValue(s64 value)
 
273
        {
 
274
                setReturnValue((u64)value);
 
275
        }
 
276
};
 
277
 
 
278
class Action
 
279
{
 
280
public:
 
281
        virtual ~Action() {}
 
282
        virtual void run(MipsCall &call) = 0;
 
283
        virtual void DoState(PointerWrap &p) = 0;
 
284
        int actionTypeID;
 
285
};
 
286
 
 
287
enum ThreadStatus
 
288
{
 
289
        THREADSTATUS_RUNNING = 1,
 
290
        THREADSTATUS_READY   = 2,
 
291
        THREADSTATUS_WAIT    = 4,
 
292
        THREADSTATUS_SUSPEND = 8,
 
293
        THREADSTATUS_DORMANT = 16,
 
294
        THREADSTATUS_DEAD    = 32,
 
295
 
 
296
        THREADSTATUS_WAITSUSPEND = THREADSTATUS_WAIT | THREADSTATUS_SUSPEND
 
297
};
 
298
 
 
299
void __KernelChangeThreadState(Thread *thread, ThreadStatus newStatus);
 
300
 
 
301
typedef void (*ThreadCallback)(SceUID threadID);
 
302
void __KernelListenThreadEnd(ThreadCallback callback);
 
303
 
 
304
struct DebugThreadInfo
 
305
{
 
306
        SceUID id;
 
307
        char name[KERNELOBJECT_MAX_NAME_LENGTH+1];
 
308
        u32 status;
 
309
        u32 curPC;
 
310
        u32 entrypoint;
 
311
        u32 initialStack;
 
312
        int stackSize;
 
313
        int priority;
 
314
        WaitType waitType;
 
315
        bool isCurrent;
 
316
};
 
317
 
 
318
std::vector<DebugThreadInfo> GetThreadsInfo();
 
319
void __KernelChangeThreadState(SceUID threadId, ThreadStatus newStatus);
 
320
 
 
321
int LoadExecForUser_362A956B();
 
322
int sceKernelRegisterExitCallback(SceUID cbId);