Threadx 申請信號量_tx_semaphore_get

申請信號量_tx_semaphore_get

1,如果信號量計數器tx_semaphore_count不爲0,就減一,返回申請成功。
2,如果信號量計數器tx_semaphore_count爲0,說明資源都被佔用,掛起當前線程到tx_semaphore_suspension_list隊列,掛入隊列的尾部,FIFO, 後續恢復時按住FIFO,而不是按照線程優先級

UINT    _tx_semaphore_get(TX_SEMAPHORE *semaphore_ptr, ULONG wait_option)
{

    TX_INTERRUPT_SAVE_AREA

    REG_1   UINT        status;                 /* Return status           */
    REG_2   TX_THREAD   *thread_ptr;            /* Working thread pointer  */


    /* Disable interrupts to get an instance from the semaphore.  */
    #def 禁止中斷,防止打斷對全局變量操作。如果更高優先級線程不需要信號量呢,是否有必要禁止中斷
    TX_DISABLE

    /* Determine if there is an instance of the semaphore.  */
    #def 還有信號量資源
    if (semaphore_ptr -> tx_semaphore_count)
    {

        /* Decrement the semaphore count.  */
        #def 計數器減1,少一個可用信號量資源
        semaphore_ptr -> tx_semaphore_count--;
		
		#def 記錄最後一個申請到資源的線程
        semaphore_ptr->sema_last_owner = _tx_thread_current_ptr;
        /* Set status to success.  */
        status =  TX_SUCCESS;
    }
    else
    {
		#def 沒有信號量資源,並且wait_option不爲0,掛起線程
        /* Determine if the request specifies suspension.  */
        if (wait_option)
        {
           
            /* Prepare for suspension of this thread.  */

            /* Pickup thread pointer.  */
            thread_ptr =  _tx_thread_current_ptr;

            /* Setup cleanup routine pointer.  */
            #def 由於獲取不到信號量而掛起,所以設置清除函數爲信號量相關的函數_tx_semaphore_cleanup,當定時器超時或線程中止時,回調這個函數,釋放清除和信號量相關數據,比如從tx_semaphore_suspension_list隊列移除線程
            thread_ptr -> tx_suspend_cleanup =  _tx_semaphore_cleanup;

            /* Setup cleanup information, i.e. this semaphore control
               block.  */
            thread_ptr -> tx_suspend_control_block = (VOID_PTR) semaphore_ptr;

            /* Setup suspension list.  */
            #def 插入隊列的尾部,fifo,所以後續恢復時也是按照fifo,並不是按照優先級高低 恢復線程
            if (semaphore_ptr -> tx_semaphore_suspension_list)
            {

                /* This list is not NULL, add current thread to the end. */
                thread_ptr -> tx_suspended_next =
                    semaphore_ptr -> tx_semaphore_suspension_list;
                thread_ptr -> tx_suspended_previous =
                    (semaphore_ptr -> tx_semaphore_suspension_list) -> tx_suspended_previous;
                ((semaphore_ptr -> tx_semaphore_suspension_list) -> tx_suspended_previous) -> tx_suspended_next =
                    thread_ptr;
                (semaphore_ptr -> tx_semaphore_suspension_list) -> tx_suspended_previous =   thread_ptr;
            }
            else
            {

                /* No other threads are suspended.  Setup the head pointer and
                   just setup this threads pointers to itself.  */
                semaphore_ptr -> tx_semaphore_suspension_list =  thread_ptr;
                thread_ptr -> tx_suspended_next =                thread_ptr;
                thread_ptr -> tx_suspended_previous =            thread_ptr;
            }

            /* Increment the suspended thread count.  */
            semaphore_ptr -> tx_semaphore_suspended_count++;

            /* Set the state to suspended.  */
            #def 線程狀態改爲掛起
            thread_ptr -> tx_state =    TX_SEMAPHORE_SUSP;

            /* Set the suspending flag.  */
            #def 開始進行掛起過程標誌
            thread_ptr -> tx_suspending =  TX_TRUE;

            /* Temporarily disable preemption.  */
            _tx_thread_preempt_disable++;

            /* Save the timeout value.  */
            thread_ptr -> tx_thread_timer.tx_remaining_ticks =  wait_option;

            /* Restore interrupts.  */
            #def 恢復中斷,後續可能被搶佔了,線程可能被恢復
            TX_RESTORE

            /* See if we need to start a timer.  */
            #def 不是TX_WAIT_FOREVER永久掛起是,開啓定時器
            if (wait_option != TX_WAIT_FOREVER)
            {

                /* A timeout is required.  */
                _tx_timer_activate(&(thread_ptr -> tx_thread_timer));
            }

            /* Call actual thread suspension routine.  */
            #def 掛起,執行到這個函數時,這個 線程可能又被標記爲恢復了,會檢查tx_suspending 標誌
            _tx_thread_suspend(thread_ptr);

            /* Return the completion status.  */
            return (thread_ptr -> tx_suspend_status);
        }
        else

            /* Immediate return, return error completion.  */
            status =  TX_NO_INSTANCE;
    }

    /* Restore interrupts.  */
    TX_RESTORE

    /* Return completion status.  */
    return (status);
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章