14#include <delaythread.h>
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
34#ifdef F___threadDataKey
35unsigned int __threadDataKey;
37extern unsigned int __threadDataKey;
40extern void *__globalTls;
49 pte_osThreadEntryPoint entryPoint;
64#ifdef F___getThreadData
70 pTls = __getTlsStructFromThread(threadHandle);
71 pThreadData = (
ps2ThreadData *) pteTlsGetValue(pTls, __threadDataKey);
79static inline int32_t SemWaitTimeout(s32 semHandle, uint32_t timeout)
85 return PollSema(semHandle);
90 if (timeout > 0 && timeout != UINT32_MAX) {
91 timeoutUsec = timeout;
92 timeoutPtr = &timeoutUsec;
93 return WaitSemaEx(semHandle, 1, timeoutPtr);
96 return WaitSema(semHandle);
102#ifdef F___ps2StubThreadEntry
103int __ps2StubThreadEntry(
void *argv)
108 pThreadData = __getThreadData(GetThreadId());
109 result = (*(pThreadData->entryPoint))(pThreadData->argv);
114extern int __ps2StubThreadEntry(
void *argv);
123pte_osResult pte_osInit(
void)
130 result = pteTlsGlobalInit(PS2_MAX_TLS);
132 if (result == PTE_OS_OK) {
134 result = __pteTlsAlloc(&__threadDataKey);
136 if (result == PTE_OS_OK) {
140 __globalTls = pteTlsThreadInit();
150 if (pThreadData == NULL) {
151 result = PTE_OS_NO_RESOURCES;
154 __pteTlsSetValue(__globalTls, __threadDataKey, pThreadData);
157 sema.max_count = 255;
159 pThreadData->cancelSem = CreateSema(&sema);
170#ifdef F_pte_osTerminate
171pte_osResult pte_osTerminate(
void) {
172 pteTlsGlobalDestroy();
183static inline int invert_priority(
int priority)
185 return (pte_osThreadGetMinPriority() - priority) + pte_osThreadGetMaxPriority();
188#ifdef F_pte_osThreadCreate
189pte_osResult pte_osThreadCreate(pte_osThreadEntryPoint entryPoint,
193 pte_osThreadHandle* ppte_osThreadHandle)
199 static int threadNum = 1;
205 if (threadNum++ > MAX_PS2_UID) {
210 if (stackSize < DEFAULT_STACK_SIZE_BYTES) {
211 stackSize = DEFAULT_STACK_SIZE_BYTES;
215 pTls = pteTlsThreadInit();
217 PS2_DEBUG(
"pteTlsThreadInit: PTE_OS_NO_RESOURCES\n");
218 result = PTE_OS_NO_RESOURCES;
228 if (pThreadData == NULL) {
229 pteTlsThreadDestroy(pTls);
231 PS2_DEBUG(
"malloc(ps2ThreadData): PTE_OS_NO_RESOURCES\n");
232 result = PTE_OS_NO_RESOURCES;
237 __pteTlsSetValue(pTls, __threadDataKey, pThreadData);
239 pThreadData->entryPoint = entryPoint;
240 pThreadData->argv = argv;
243 sema.max_count = 255;
245 pThreadData->cancelSem = CreateSema(&sema);
248 stack = malloc(stackSize);
252 eethread.func = &__ps2StubThreadEntry;
253 eethread.stack = stack;
254 eethread.stack_size = stackSize;
255 eethread.gp_reg = &_gp;
256 eethread.initial_priority = invert_priority(initialPriority);
257 threadId = CreateThread(&eethread);
264 threadInfo = &__threadInfo[threadId];
265 threadInfo->threadNumber = threadNum;
266 threadInfo->tlsPtr = pTls;
270 pteTlsThreadDestroy(pTls);
272 PS2_DEBUG(
"CreateThread: PTE_OS_NO_RESOURCES\n");
273 result = PTE_OS_NO_RESOURCES;
274 }
else if (threadId < 0) {
276 pteTlsThreadDestroy(pTls);
278 PS2_DEBUG(
"CreateThread: PTE_OS_GENERAL_FAILURE\n");
279 result = PTE_OS_GENERAL_FAILURE;
281 *ppte_osThreadHandle = threadId;
290#ifdef F_pte_osThreadStart
291pte_osResult pte_osThreadStart(pte_osThreadHandle osThreadHandle)
293 StartThread(osThreadHandle, 0);
299#ifdef F_pte_osThreadDelete
300pte_osResult pte_osThreadDelete(pte_osThreadHandle handle)
308 res = ReferThreadStatus(handle, &
info);
310 pTls = __getTlsStructFromThread(handle);
311 pThreadData = __getThreadData(handle);
312 DeleteSema(pThreadData->cancelSem);
314 pteTlsThreadDestroy(pTls);
315 TerminateThread(handle);
316 DeleteThread(handle);
318 if (res > 0 &&
info.stack) {
322 threadInfo = &__threadInfo[handle];
323 threadInfo->threadNumber = 0;
324 threadInfo->tlsPtr = NULL;
330#ifdef F_pte_osThreadExitAndDelete
331pte_osResult pte_osThreadExitAndDelete(pte_osThreadHandle handle)
333 pte_osThreadDelete(handle);
340#ifdef F_pte_osThreadExit
341void pte_osThreadExit()
351#ifdef F_pte_osThreadWaitForEnd
352pte_osResult pte_osThreadWaitForEnd(pte_osThreadHandle threadHandle)
357 pThreadData = __getThreadData(GetThreadId());
363 ReferThreadStatus(threadHandle, &
info);
365 if (
info.status == THS_DORMANT) {
372 if (pThreadData != NULL) {
375 osResult = ReferSemaStatus(pThreadData->cancelSem, &semInfo);
376 if (osResult == pThreadData->cancelSem) {
377 if (semInfo.count > 0) {
378 result = PTE_OS_INTERRUPTED;
384 DelayThread(POLLING_DELAY_IN_us);
387 result = PTE_OS_GENERAL_FAILURE;
398#ifdef F_pte_osThreadGetHandle
399pte_osThreadHandle pte_osThreadGetHandle(
void)
401 return GetThreadId();
405#ifdef F_pte_osThreadGetPriority
406int pte_osThreadGetPriority(pte_osThreadHandle threadHandle)
410 ReferThreadStatus(threadHandle, &thinfo);
412 return invert_priority(thinfo.current_priority);
416#ifdef F_pte_osThreadSetPriority
417pte_osResult pte_osThreadSetPriority(pte_osThreadHandle threadHandle,
int newPriority)
419 ChangeThreadPriority(threadHandle, invert_priority(newPriority));
424#ifdef F_pte_osThreadCancel
425pte_osResult pte_osThreadCancel(pte_osThreadHandle threadHandle)
431 pThreadData = __getThreadData(threadHandle);
432 osResult = SignalSema(pThreadData->cancelSem);
434 if (osResult == pThreadData->cancelSem) {
437 result = PTE_OS_GENERAL_FAILURE;
444#ifdef F_pte_osThreadCheckCancel
445pte_osResult pte_osThreadCheckCancel(pte_osThreadHandle threadHandle)
452 pThreadData = __getThreadData(threadHandle);
453 if (pThreadData != NULL) {
454 osResult = ReferSemaStatus(pThreadData->cancelSem, &semInfo);
456 if (osResult == pThreadData->cancelSem) {
457 if (semInfo.count > 0) {
458 result = PTE_OS_INTERRUPTED;
464 result = PTE_OS_GENERAL_FAILURE;
468 result = PTE_OS_GENERAL_FAILURE;
475#ifdef F_pte_osThreadSleep
476void pte_osThreadSleep(
unsigned int msecs)
478 DelayThread(msecs * 1000);
482#ifdef F_pte_osThreadGetMinPriority
483int pte_osThreadGetMinPriority()
485 return pte_osThreadGetDefaultPriority() - 32;
489#ifdef F_pte_osThreadGetMaxPriority
490int pte_osThreadGetMaxPriority()
492 return pte_osThreadGetDefaultPriority() + 32;
496#ifdef F_pte_osThreadGetDefaultPriority
497int pte_osThreadGetDefaultPriority()
503#ifdef F_pthread_num_processors_np
504int pthread_num_processors_np(
void)
515#ifdef F_pte_osMutexCreate
516pte_osResult pte_osMutexCreate(pte_osMutexHandle *pHandle)
518 static int mutexCtr = 0;
520 pte_osMutexHandle handle;
522 if (mutexCtr++ > MAX_PS2_UID) {
529 handle = CreateSema(&sema);
536#ifdef F_pte_osMutexDelete
537pte_osResult pte_osMutexDelete(pte_osMutexHandle handle)
545#ifdef F_pte_osMutexLock
546pte_osResult pte_osMutexLock(pte_osMutexHandle handle)
548 SemWaitTimeout(handle, UINT32_MAX);
554#ifdef F_pte_osMutexTimedLock
555pte_osResult pte_osMutexTimedLock(pte_osMutexHandle handle,
unsigned int timeoutMsecs)
558 int32_t timeout = timeoutMsecs * 1000;
559 int status = SemWaitTimeout(handle, timeout);
562 }
else if (status == -1) {
563 result = PTE_OS_TIMEOUT;
565 result = PTE_OS_GENERAL_FAILURE;
572#ifdef F_pte_osMutexUnlock
573pte_osResult pte_osMutexUnlock(pte_osMutexHandle handle)
585#ifdef F_pte_osSemaphoreCreate
586pte_osResult pte_osSemaphoreCreate(
int initialValue, pte_osSemaphoreHandle *pHandle)
588 pte_osSemaphoreHandle handle;
590 static int semCtr = 0;
592 if (semCtr++ > MAX_PS2_UID) {
596 sema.init_count = initialValue;
597 sema.max_count = 32767;
599 handle = CreateSema(&sema);
606#ifdef F_pte_osSemaphoreDelete
607pte_osResult pte_osSemaphoreDelete(pte_osSemaphoreHandle handle)
614#ifdef F_pte_osSemaphorePost
615pte_osResult pte_osSemaphorePost(pte_osSemaphoreHandle handle,
int count)
618 for (i = 0; i <
count; i++)
625#ifdef F_pte_osSemaphorePend
626pte_osResult pte_osSemaphorePend(pte_osSemaphoreHandle handle,
unsigned int *pTimeoutMsecs)
630 pte_osResult osResult;
632 if (pTimeoutMsecs == NULL) {
633 timeout = UINT32_MAX;
635 timeout = *pTimeoutMsecs * 1000;
638 result = SemWaitTimeout(handle, timeout);
640 osResult = PTE_OS_OK;
641 }
else if (result == -1) {
642 osResult = PTE_OS_TIMEOUT;
644 osResult = PTE_OS_GENERAL_FAILURE;
658#ifdef F_pte_osSemaphoreCancellablePend
659pte_osResult pte_osSemaphoreCancellablePend(pte_osSemaphoreHandle semHandle,
unsigned int *pTimeout)
663 pThreadData = __getThreadData(GetThreadId());
666 pte_osResult result = PTE_OS_OK;
669 start_time = clock();
672 if (pTimeout == NULL) {
675 timeout = *pTimeout * 1000;
682 status = SemWaitTimeout(semHandle, 0);
687 }
else if ((pTimeout != NULL) && ((clock() - start_time) > timeout)) {
689 result = PTE_OS_TIMEOUT;
694 if (pThreadData != NULL) {
697 osResult = ReferSemaStatus(pThreadData->cancelSem, &semInfo);
698 if (osResult == pThreadData->cancelSem) {
699 if (semInfo.count > 0) {
700 result = PTE_OS_INTERRUPTED;
706 DelayThread(POLLING_DELAY_IN_us);
709 result = PTE_OS_GENERAL_FAILURE;
726#ifdef F_pte_osAtomicExchange
727int pte_osAtomicExchange(
int *ptarg,
int val)
735 if(intc) { EIntr(); }
740#ifdef F_pte_osAtomicCompareExchange
741int pte_osAtomicCompareExchange(
int *pdest,
int exchange,
int comp)
751 if(intc) { EIntr(); }
756#ifdef F_pte_osAtomicExchangeAdd
757int pte_osAtomicExchangeAdd(
int volatile* pAddend,
int value)
765 if(intc) { EIntr(); }
770#ifdef F_pte_osAtomicDecrement
771int pte_osAtomicDecrement(
int *pdest)
779 if(intc) { EIntr(); }
784#ifdef F_pte_osAtomicIncrement
785int pte_osAtomicIncrement(
int *pdest)
793 if(intc) { EIntr(); }
u32 count
start sector of fragmented bd/file