semaphore.c

来自「KaOS is a real-time operating system tha」· C语言 代码 · 共 120 行

C
120
字号
os_semaphore* CreateSemaphore(UCHAR semVal)
{
    os_semaphore* temp_semaphore;

    temp_semaphore = (os_thread*)g_freesemaphores;

    if (temp_semaphore == NULL) return -1;
    
    // pop a free thread from the list
    g_freesemaphores = temp_semaphore->next;
    g_freesemaphores->prev = NULL;

    // push the free thread on the used threads list
    temp_semaphore->next = g_usedsemaphores;
    g_usedsemaphores->prev = temp_semaphore;
    g_usedsemaphores = temp_semaphore;
    
    temp_semaphore->remaining = semVal;
    
    return temp_semaphore;
}
/*
void FreeSemaphore(os_semaphore* semaphore)
{
	// this is harder than threadsem since its not always equal g_usedsemaphores
}
*/
os_threadsem* CreateThreadSem(os_thread *thread)
{
    os_threadsem* temp_threadsem;

    temp_threadsem = (os_thread*)g_freethreadsems;

    if (temp_threadsem == NULL) return -1;
    
    // pop a free thread from the list
    g_freethreadsems = temp_threadsem->next;

    // push the free thread on the used threads list
    temp_threadsem->next = g_usedthreadsems;
    g_usedthreadsems = temp_threadsem;
    
    temp_threadsem->thread = thread;
    
    return temp_threadsem;
}
void FreeThreadSem(os_threadsem* threadsem)
{
    // threadsem should always equal g_usedthreadsem since its a queue

    g_usedthreadsems = threadsem->next;

    threadsem->next = g_freethreadsems;
    g_freethreadsems = threadsem;
}

// return 1 if you had to wait at all
UCHAR WaitSemaphore(os_semaphore* semaphore)
{
    register UCHAR ret;
    os_threadsem *temp_threadsem;

    #asm("cli");

    ret = 1;

    if (semaphore->remaining > 0)
    {
        --(semaphore->remaining);
        ret = 0;
    }
    else
    {
        if (semaphore->queue != NULL)
        {
            // we have to wait
            temp_threadsem = semaphore->queue;

            while (temp_threadsem->next != NULL)
            {
                temp_threadsem = temp_threadsem->next;
            }
            temp_threadsem->next = CreateThreadSem(g_currthread);
        }
        else
        {
            semaphore->queue = CreateThreadSem(g_currthread);
        }
        g_currthread->state = THREADSTATE_BLOCKED;
        os_schedule();
    }

    #asm("sei");

    return ret;
}
void SignalSemaphore(os_semaphore* semaphore)
{
    os_threadsem* temp_threadsem;

    #asm("cli");

    if (semaphore->queue == NULL)
    {
        ++semaphore->remaining;
    }
    else
    {
        // pop first in off
        temp_threadsem = semaphore->queue;
        semaphore->queue = temp_threadsem->next;

        temp_threadsem->thread->state = THREADSTATE_RUNNING;

        FreeThreadSem(temp_threadsem);
        os_schedule();
    }

    #asm("sei");
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?