16#define MAX_PS2_UID 2048
17#define DEFAULT_STACK_SIZE_BYTES 4096
19#define MAX_THREADS 256
22#define PS2_DEBUG(x) printf(x)
27#define POLLING_DELAY_IN_us 100
32unsigned int __threadDataKey;
34extern void *__globalTls;
43 pte_osThreadEntryPoint entryPoint;
63 pTls = __getTlsStructFromThread(threadHandle);
64 pThreadData = (
ps2ThreadData *) pteTlsGetValue(pTls, __threadDataKey);
69static inline int32_t SemWaitTimeout(s32 semHandle, uint32_t timeout)
75 return PollSema(semHandle);
80 if (timeout > 0 && timeout != UINT32_MAX) {
81 timeoutUsec = timeout;
82 timeoutPtr = &timeoutUsec;
86 return WaitSema(semHandle);
92int __ps2StubThreadEntry(
void *argv)
97 pThreadData = __getThreadData(GetThreadId());
98 result = (*(pThreadData->entryPoint))(pThreadData->argv);
108pte_osResult pte_osInit(
void)
115 result = pteTlsGlobalInit(PS2_MAX_TLS);
117 if (result == PTE_OS_OK) {
119 result = __pteTlsAlloc(&__threadDataKey);
121 if (result == PTE_OS_OK) {
125 __globalTls = pteTlsThreadInit();
135 if (pThreadData == NULL) {
136 result = PTE_OS_NO_RESOURCES;
139 __pteTlsSetValue(__globalTls, __threadDataKey, pThreadData);
142 sema.max_count = 255;
144 pThreadData->cancelSem = CreateSema(&sema);
154pte_osResult pte_osTerminate(
void) {
155 pteTlsGlobalDestroy();
165static inline int invert_priority(
int priority)
167 return (pte_osThreadGetMinPriority() - priority) + pte_osThreadGetMaxPriority();
170pte_osResult pte_osThreadCreate(pte_osThreadEntryPoint entryPoint,
174 pte_osThreadHandle* ppte_osThreadHandle)
176 ee_thread_t eethread;
180 static int threadNum;
185 if (++threadNum > MAX_PS2_UID) {
190 if (stackSize < DEFAULT_STACK_SIZE_BYTES) {
191 stackSize = DEFAULT_STACK_SIZE_BYTES;
195 pTls = pteTlsThreadInit();
197 PS2_DEBUG(
"pteTlsThreadInit: PTE_OS_NO_RESOURCES\n");
198 return PTE_OS_NO_RESOURCES;
207 if (pThreadData == NULL) {
208 pteTlsThreadDestroy(pTls);
209 PS2_DEBUG(
"malloc(ps2ThreadData): PTE_OS_NO_RESOURCES\n");
210 return PTE_OS_NO_RESOURCES;
214 __pteTlsSetValue(pTls, __threadDataKey, pThreadData);
216 pThreadData->entryPoint = entryPoint;
217 pThreadData->argv = argv;
220 sema.max_count = 255;
222 pThreadData->cancelSem = CreateSema(&sema);
223 if (pThreadData->cancelSem < 0) {
225 pteTlsThreadDestroy(pTls);
226 PS2_DEBUG(
"CreateSema(cancelSem): PTE_OS_NO_RESOURCES\n");
227 return PTE_OS_NO_RESOURCES;
234 stack = malloc(stackSize);
236 DeleteSema(pThreadData->cancelSem);
238 pteTlsThreadDestroy(pTls);
239 PS2_DEBUG(
"malloc(stack): PTE_OS_NO_RESOURCES\n");
240 return PTE_OS_NO_RESOURCES;
245 eethread.func = &__ps2StubThreadEntry;
246 eethread.stack = stack;
247 eethread.stack_size = stackSize;
248 eethread.gp_reg = &
_gp;
249 eethread.initial_priority = invert_priority(initialPriority);
250 threadId = CreateThread(&eethread);
257 DeleteSema(pThreadData->cancelSem);
259 pteTlsThreadDestroy(pTls);
260 PS2_DEBUG(
"CreateThread: PTE_OS_GENERAL_FAILURE\n");
261 return PTE_OS_GENERAL_FAILURE;
269 threadInfo = &__threadInfo[threadId];
270 threadInfo->threadNumber = threadNum;
271 threadInfo->tlsPtr = pTls;
273 *ppte_osThreadHandle = threadId;
277pte_osResult pte_osThreadStart(pte_osThreadHandle osThreadHandle)
279 StartThread(osThreadHandle, 0);
284pte_osResult pte_osThreadDelete(pte_osThreadHandle handle)
288 ee_thread_status_t info;
292 res = ReferThreadStatus(handle, &info);
294 pTls = __getTlsStructFromThread(handle);
295 pThreadData = __getThreadData(handle);
296 DeleteSema(pThreadData->cancelSem);
298 pteTlsThreadDestroy(pTls);
299 TerminateThread(handle);
300 DeleteThread(handle);
302 if (res > 0 && info.stack) {
306 threadInfo = &__threadInfo[handle];
307 threadInfo->threadNumber = 0;
308 threadInfo->tlsPtr = NULL;
313pte_osResult pte_osThreadExitAndDelete(pte_osThreadHandle handle)
315 pte_osThreadDelete(handle);
321void pte_osThreadExit()
330pte_osResult pte_osThreadWaitForEnd(pte_osThreadHandle threadHandle)
335 pThreadData = __getThreadData(GetThreadId());
338 ee_thread_status_t info;
341 ReferThreadStatus(threadHandle, &info);
343 if (info.status == THS_DORMANT) {
350 if (pThreadData != NULL) {
353 osResult = ReferSemaStatus(pThreadData->cancelSem, &semInfo);
354 if (osResult == pThreadData->cancelSem) {
355 if (semInfo.count > 0) {
356 result = PTE_OS_INTERRUPTED;
362 DelayThread(POLLING_DELAY_IN_us);
365 result = PTE_OS_GENERAL_FAILURE;
375pte_osThreadHandle pte_osThreadGetHandle(
void)
377 return GetThreadId();
380int pte_osThreadGetPriority(pte_osThreadHandle threadHandle)
382 ee_thread_status_t thinfo;
384 ReferThreadStatus(threadHandle, &thinfo);
386 return invert_priority(thinfo.current_priority);
389pte_osResult pte_osThreadSetPriority(pte_osThreadHandle threadHandle,
int newPriority)
391 ChangeThreadPriority(threadHandle, invert_priority(newPriority));
395pte_osResult pte_osThreadCancel(pte_osThreadHandle threadHandle)
401 pThreadData = __getThreadData(threadHandle);
402 osResult = SignalSema(pThreadData->cancelSem);
404 if (osResult == pThreadData->cancelSem) {
407 result = PTE_OS_GENERAL_FAILURE;
413pte_osResult pte_osThreadCheckCancel(pte_osThreadHandle threadHandle)
420 pThreadData = __getThreadData(threadHandle);
421 if (pThreadData != NULL) {
422 osResult = ReferSemaStatus(pThreadData->cancelSem, &semInfo);
424 if (osResult == pThreadData->cancelSem) {
425 if (semInfo.count > 0) {
426 result = PTE_OS_INTERRUPTED;
432 result = PTE_OS_GENERAL_FAILURE;
436 result = PTE_OS_GENERAL_FAILURE;
442void pte_osThreadSleep(
unsigned int msecs)
444 DelayThread(msecs * 1000);
447int pte_osThreadGetMinPriority()
449 return pte_osThreadGetDefaultPriority() - 32;
452int pte_osThreadGetMaxPriority()
454 return pte_osThreadGetDefaultPriority() + 32;
457int pte_osThreadGetDefaultPriority()
462int pthread_num_processors_np(
void)
472pte_osResult pte_osMutexCreate(pte_osMutexHandle *pHandle)
474 static int mutexCtr = 0;
476 pte_osMutexHandle handle;
478 if (mutexCtr++ > MAX_PS2_UID) {
485 handle = CreateSema(&sema);
488 return PTE_OS_NO_RESOURCES;
495pte_osResult pte_osMutexDelete(pte_osMutexHandle handle)
502pte_osResult pte_osMutexLock(pte_osMutexHandle handle)
504 SemWaitTimeout(handle, UINT32_MAX);
509pte_osResult pte_osMutexTimedLock(pte_osMutexHandle handle,
unsigned int timeoutMsecs)
512 int32_t timeout = timeoutMsecs * 1000;
513 int status = SemWaitTimeout(handle, timeout);
516 }
else if (status == -1) {
517 result = PTE_OS_TIMEOUT;
519 result = PTE_OS_GENERAL_FAILURE;
525pte_osResult pte_osMutexUnlock(pte_osMutexHandle handle)
536pte_osResult pte_osSemaphoreCreate(
int initialValue, pte_osSemaphoreHandle *pHandle)
538 pte_osSemaphoreHandle handle;
540 static int semCtr = 0;
542 if (semCtr++ > MAX_PS2_UID) {
546 sema.init_count = initialValue;
547 sema.max_count = 32767;
549 handle = CreateSema(&sema);
552 return PTE_OS_NO_RESOURCES;
559pte_osResult pte_osSemaphoreDelete(pte_osSemaphoreHandle handle)
565pte_osResult pte_osSemaphorePost(pte_osSemaphoreHandle handle,
int count)
568 for (i = 0; i <
count; i++)
574pte_osResult pte_osSemaphorePend(pte_osSemaphoreHandle handle,
unsigned int *pTimeoutMsecs)
578 pte_osResult osResult;
580 if (pTimeoutMsecs == NULL) {
581 timeout = UINT32_MAX;
583 timeout = *pTimeoutMsecs * 1000;
586 result = SemWaitTimeout(handle, timeout);
588 osResult = PTE_OS_OK;
589 }
else if (result == -1) {
590 osResult = PTE_OS_TIMEOUT;
592 osResult = PTE_OS_GENERAL_FAILURE;
605pte_osResult pte_osSemaphoreCancellablePend(pte_osSemaphoreHandle semHandle,
unsigned int *pTimeout)
609 pThreadData = __getThreadData(GetThreadId());
612 pte_osResult result = PTE_OS_OK;
615 start_time = clock();
618 if (pTimeout == NULL) {
621 timeout = *pTimeout * 1000;
628 status = SemWaitTimeout(semHandle, 0);
633 }
else if ((pTimeout != NULL) && ((clock() - start_time) > timeout)) {
635 result = PTE_OS_TIMEOUT;
640 if (pThreadData != NULL) {
643 osResult = ReferSemaStatus(pThreadData->cancelSem, &semInfo);
644 if (osResult == pThreadData->cancelSem) {
645 if (semInfo.count > 0) {
646 result = PTE_OS_INTERRUPTED;
652 DelayThread(POLLING_DELAY_IN_us);
655 result = PTE_OS_GENERAL_FAILURE;
671int pte_osAtomicExchange(
int *ptarg,
int val)
679 if(intc) { EIntr(); }
683int pte_osAtomicCompareExchange(
int *pdest,
int exchange,
int comp)
693 if(intc) { EIntr(); }
697int pte_osAtomicExchangeAdd(
int volatile* pAddend,
int value)
705 if(intc) { EIntr(); }
709int pte_osAtomicDecrement(
int *pdest)
717 if(intc) { EIntr(); }
721int pte_osAtomicIncrement(
int *pdest)
729 if(intc) { EIntr(); }
s32 WaitSemaEx(s32 semaid, int signal, u64 *timeout)
u32 count
start sector of fragmented bd/file