sdk-core v2026.11.05
PS2 SDK - core tier (build-critical EE/IOP modules)
Loading...
Searching...
No Matches
thread.c
Go to the documentation of this file.
1/*
2# _____ ___ ____ ___ ____
3# ____| | ____| | | |____|
4# | ___| |____ ___| ____| | \ PS2DEV Open Source Project.
5#-----------------------------------------------------------------------
6# Licenced under Academic Free License version 2.0
7# Review ps2sdk README & LICENSE files for further details.
8*/
9
14
15#include "kernel.h"
16
17struct request
18{
19 u8 mode;
20 u8 data;
21};
22
23enum TOP_REQ {
24 TOP_REQ_WAKEUP,
25 TOP_REQ_ROTATE,
26 TOP_REQ_SUSPEND
27};
28
29struct topArg
30{
31 int requestOut;
32 int requestIn;
33 struct request request[512];
34};
35
36extern int topId;
37extern int topSema;
38extern struct topArg topArg;
39
40
41extern void *_gp;
42
43u8 stack[0x400] __attribute__((aligned(16)));
44
45int topId = 0;
46int topSema = 0;
47struct topArg topArg = {0};
48
49static void topThread(void *arg)
50{
51 (void)arg;
52
53 while (1) {
54 int index;
55
56 WaitSema(topSema);
57 index = topArg.requestOut & 0x1FF;
58 topArg.requestOut = index + 1;
59
60 switch (topArg.request[index].mode) {
61 case TOP_REQ_WAKEUP:
62 WakeupThread(topArg.request[index].data);
63 break;
64 case TOP_REQ_ROTATE:
65 RotateThreadReadyQueue(topArg.request[index].data);
66 break;
67 case TOP_REQ_SUSPEND:
68 SuspendThread(topArg.request[index].data);
69 break;
70 /* default:
71 Kprintf("## internal error in libkernel!\n"); */
72 }
73 }
74}
75
76__attribute__((weak))
77int InitThread(void)
78{
79 ee_sema_t sema;
80 ee_thread_t thread;
81
82 sema.max_count = 255;
83 sema.init_count = 0;
84 sema.option = (u32) "KernelTopThread";
85 if ((topSema = CreateSema(&sema)) < 0)
86 return -1;
87
88 thread.func = &topThread;
89 thread.stack = stack;
90 thread.stack_size = sizeof(stack);
91 thread.gp_reg = &_gp;
92 thread.option = (u32) "KernelTopThread";
93 thread.initial_priority = 0;
94 if ((topId = CreateThread(&thread)) < 0) {
95 DeleteSema(topSema);
96 return -1;
97 }
98
99 topArg.requestOut = 0;
100 topArg.requestIn = 0;
101 StartThread(topId, &topArg);
102
103 ChangeThreadPriority(GetThreadId(), 1);
104
105 return topId;
106}
107
108// The original iWakeupThread cannot wake up threads in THS_RUN state.
109__attribute__((weak))
110s32 iWakeupThread(s32 thread_id)
111{
112 if (_iGetThreadId() == thread_id) {
113 if (thread_id < 256 && topId != 0) {
114 int index;
115
116 index = topArg.requestIn & 0x1FF;
117 topArg.requestIn = index + 1;
118 topArg.request[index].mode = TOP_REQ_WAKEUP;
119 topArg.request[index].data = thread_id;
120
121 iSignalSema(topSema);
122 return 0;
123 } else
124 return -1;
125 } else {
126 return _iWakeupThread(thread_id);
127 }
128}
129
130// The original iRotateThreadReadyQueue will not change the current thread ID.
131__attribute__((weak))
132s32 iRotateThreadReadyQueue(s32 priority)
133{
134 if (priority < 128 && topId != 0) {
135 int index;
136
137 index = topArg.requestIn & 0x1FF;
138 topArg.requestIn = index + 1;
139 topArg.request[index].mode = TOP_REQ_ROTATE;
140 topArg.request[index].data = priority;
141
142 iSignalSema(topSema);
143 return 0;
144 } else
145 return -1;
146}
147
148// The original iSuspendThread allows a thread to suspend itself, but won't change the current thread ID.
149__attribute__((weak))
150s32 iSuspendThread(s32 thread_id)
151{
152 if (_iGetThreadId() == thread_id) {
153 if (thread_id < 256 && topId != 0) {
154 int index;
155
156 index = topArg.requestIn & 0x1FF;
157 topArg.requestIn = index + 1;
158 topArg.request[index].mode = TOP_REQ_SUSPEND;
159 topArg.request[index].data = thread_id;
160
161 iSignalSema(topSema);
162 return 0;
163 } else
164 return -1;
165 } else {
166 return _iSuspendThread(thread_id);
167 }
168}
void * _gp