/**
 * [P : P Operation]
 * @param sem [semaphore pointer]
 */
void P(semaphore *sem)
{
    struct TCB **blkq;
    disable();

    sem->value--; 
    /* There is no available resources */
    if(sem->value < 0)
    {
        blkq = &(sem->wq);
        /* Insert current thread to Block Queue */
        ThreadBlock(blkq);
    }
    enable();
}
U32 CNvThread::m_Func()
{
    NV_ASSERT(ThreadInit());

    if (m_bSyncStart)
    {
        m_EventStart.Set();
    }

    if (m_bOneShot)
    {
        m_Mutex.Acquire();
        ThreadFunc();
        m_Mutex.Release();
    }
    else
    {
        while (!ThreadIsQuit())
        {
            m_Mutex.Acquire();
            bool bDoMore = ThreadFunc();
            m_Mutex.Release();

            if (bDoMore || ThreadIsQuit())
            {
                continue;
            }

            ThreadBlock((U32)INvThreading::NV_TIMEOUT_INFINITE);
        }
    }

    NV_ASSERT(ThreadFini());

    return 0;
}