int SDL_SemWaitTimeout(SDL_sem * sem, Uint32 timeout) { int32_t val; int retval; if (!sem) { SDL_SetError("Passed a NULL semaphore"); return -1; } int finished = 0; while( finished == 0) { // Do not wait if( timeout == 0) { val = sysSemTryWait( sem->id); // Wait Forever } else if (timeout == SDL_MUTEX_MAXWAIT) { val = sysSemWait(sem->id, 0); // Wait until timeout } else { timeout *= 1000; /* PS 3uses a timeout in microseconds */ val = sysSemWait(sem->id, timeout); } switch (val) { case EINTR: break; case 0: retval = 0; finished = 1; break; case ETIMEDOUT: retval = SDL_MUTEX_TIMEDOUT; finished = 1; break; default: SDL_SetError("sysSem[Try]Wait() failed"); retval = -1; finished = 1; break; } } return retval; }
/* * Pend on a semaphore- and allow the pend to be cancelled. * * PS3 OS provides no functionality to asynchronously interrupt a blocked call. We simulte * this by polling on the main semaphore and the cancellation semaphore and sleeping in a loop. */ pte_osResult pte_osSemaphoreCancellablePend(pte_osSemaphoreHandle semHandle, unsigned int *pTimeout) { psl1ghtThreadData *pThreadData; sys_ppu_thread_t threadId; sysThreadGetId (&threadId); pThreadData = getThreadData(threadId); clock_t start_time; s32 result = 0; u64 timeout; unsigned char timeoutEnabled; start_time = clock(); // clock() is in microseconds, timeout as passed in was in milliseconds if (pTimeout == NULL) { timeout = 0; timeoutEnabled = 0; } else { timeout = *pTimeout * 1000; timeoutEnabled = 1; } while (1) { int status; /* Poll semaphore */ status = sysSemTryWait(semHandle); if (status == 0) { /* User semaphore posted to */ result = PTE_OS_OK; break; } else if ((timeoutEnabled) && ((clock() - start_time) > timeout)) { /* Timeout expired */ result = PTE_OS_TIMEOUT; break; } else { if (pThreadData != NULL) { s32 count; s32 osResult; osResult = sysSemGetValue (pThreadData->cancelSem, &count); if (osResult == 0) { if (count > 0) { result = PTE_OS_INTERRUPTED; break; } else { /* Nothing found and not timed out yet; let's yield so we're not * in busy loop. */ sysThreadYield (); } } else { result = PTE_OS_GENERAL_FAILURE; break; } } } } return result; }