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;
}