PS2SDK
PS2 Homebrew Libraries
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 
15 #include "kernel.h"
16 
17 struct request
18 {
19  u8 mode;
20  u8 data;
21 };
22 
23 enum TOP_REQ {
24  TOP_REQ_WAKEUP,
25  TOP_REQ_ROTATE,
26  TOP_REQ_SUSPEND
27 };
28 
29 struct topArg
30 {
31  int requestOut;
32  int requestIn;
33  struct request request[512];
34 };
35 
36 extern int topId;
37 extern int topSema;
38 extern struct topArg topArg;
39 
40 #ifdef F__thread_internals
41 
42 extern void *_gp;
43 
44 u8 stack[0x400] __attribute__((aligned(16)));
45 
46 int topId = 0;
47 int topSema = 0;
48 struct topArg topArg = {0};
49 
50 static void topThread(void *arg)
51 {
52  (void)arg;
53 
54  while (1) {
55  int index;
56 
57  WaitSema(topSema);
58  index = topArg.requestOut & 0x1FF;
59  topArg.requestOut = index + 1;
60 
61  switch (topArg.request[index].mode) {
62  case TOP_REQ_WAKEUP:
63  WakeupThread(topArg.request[index].data);
64  break;
65  case TOP_REQ_ROTATE:
66  RotateThreadReadyQueue(topArg.request[index].data);
67  break;
68  case TOP_REQ_SUSPEND:
69  SuspendThread(topArg.request[index].data);
70  break;
71  /* default:
72  Kprintf("## internal error in libkernel!\n"); */
73  }
74  }
75 }
76 
77 __attribute__((weak))
78 int InitThread(void)
79 {
80  ee_sema_t sema;
82 
83  sema.max_count = 255;
84  sema.init_count = 0;
85  sema.option = (u32) "KernelTopThread";
86  if ((topSema = CreateSema(&sema)) < 0)
87  return -1;
88 
89  thread.func = &topThread;
90  thread.stack = stack;
91  thread.stack_size = sizeof(stack);
92  thread.gp_reg = &_gp;
93  thread.option = (u32) "KernelTopThread";
94  thread.initial_priority = 0;
95  if ((topId = CreateThread(&thread)) < 0) {
96  DeleteSema(topSema);
97  return -1;
98  }
99 
100  topArg.requestOut = 0;
101  topArg.requestIn = 0;
102  StartThread(topId, &topArg);
103 
104  ChangeThreadPriority(GetThreadId(), 1);
105 
106  return topId;
107 }
108 #endif
109 
110 #ifdef F_iWakeupThread
111 // The original iWakeupThread cannot wake up threads in THS_RUN state.
112 __attribute__((weak))
113 s32 iWakeupThread(s32 thread_id)
114 {
115  if (_iGetThreadId() == thread_id) {
116  if (thread_id < 256 && topId != 0) {
117  int index;
118 
119  index = topArg.requestIn & 0x1FF;
120  topArg.requestIn = index + 1;
121  topArg.request[index].mode = TOP_REQ_WAKEUP;
122  topArg.request[index].data = thread_id;
123 
124  iSignalSema(topSema);
125  return 0;
126  } else
127  return -1;
128  } else {
129  return _iWakeupThread(thread_id);
130  }
131 }
132 #endif
133 
134 #ifdef F_iRotateThreadReadyQueue
135 // The original iRotateThreadReadyQueue will not change the current thread ID.
136 __attribute__((weak))
137 s32 iRotateThreadReadyQueue(s32 priority)
138 {
139  if (priority < 128 && topId != 0) {
140  int index;
141 
142  index = topArg.requestIn & 0x1FF;
143  topArg.requestIn = index + 1;
144  topArg.request[index].mode = TOP_REQ_ROTATE;
145  topArg.request[index].data = priority;
146 
147  iSignalSema(topSema);
148  return 0;
149  } else
150  return -1;
151 }
152 #endif
153 
154 #ifdef F_iSuspendThread
155 // The original iSuspendThread allows a thread to suspend itself, but won't change the current thread ID.
156 __attribute__((weak))
157 s32 iSuspendThread(s32 thread_id)
158 {
159  if (_iGetThreadId() == thread_id) {
160  if (thread_id < 256 && topId != 0) {
161  int index;
162 
163  index = topArg.requestIn & 0x1FF;
164  topArg.requestIn = index + 1;
165  topArg.request[index].mode = TOP_REQ_SUSPEND;
166  topArg.request[index].data = thread_id;
167 
168  iSignalSema(topSema);
169  return 0;
170  } else
171  return -1;
172  } else {
173  return _iSuspendThread(thread_id);
174  }
175 }
176 #endif
kernel.h
request
Definition: thread.c:17
thread
Definition: thcommon.h:143
t_ee_sema
Definition: kernel.h:193
_gp
void * _gp
__attribute__
typedef __attribute__
Definition: tlbfunc.c:60
__attribute__
Definition: gif_registers.h:38
topArg
Definition: thread.c:29
t_ee_thread
Definition: kernel.h:203