Threadx 互斥量mutex


互斥量用來保證對共享資源或臨界區的訪問唯一性,保證在指定範圍內,只能有一個線程訪問該共享資源。
Threadx中同一個線程可以多次申請同一互斥量,並且釋放互斥量必須釋放相同次數。

互斥量控制塊

Threadx中互斥量控制塊(MCB)是用來保持運行時互斥量狀態的數據結構。

/* Define the mutex structure utilized by the application.  */

typedef struct TX_MUTEX_STRUCT
{

    /* Define the mutex ID used for error checking.  */
    ULONG       tx_mutex_id;

    /* Define the mutex's name.  */
    CHAR_PTR    tx_mutex_name;

    /* Define the mutex ownership count.  */
    ULONG       tx_mutex_ownership_count;

    /* Define the mutex ownership pointer.  This pointer points to the
       the thread that owns the mutex.  */
    TX_THREAD   *tx_mutex_owner;

    /* Define the priority inheritance flag.  If this flag is set, priority
       inheritance will be in effect.  */
    UINT        tx_mutex_inherit;

    /* Define the save area for the owning thread's original priority and
       threshold.  */
    UINT        tx_mutex_original_priority;
    UINT        tx_mutex_original_threshold;

    /* Define the mutex suspension list head along with a count of
       how many threads are suspended.  */
    struct TX_THREAD_STRUCT  *tx_mutex_suspension_list;
    ULONG                    tx_mutex_suspended_count;

    /* Define the created list next and previous pointers.  */
    struct TX_MUTEX_STRUCT
        *tx_mutex_created_next,
        *tx_mutex_created_previous;

} TX_MUTEX;
意義
tx_mutex_id 互斥量控制塊ID
tx_mutex_name 互斥量名字指針
tx_mutex_ownership_count 互斥量所有權計數器,表示某線程獲取互斥量次數,範圍0到2^32-1
tx_mutex_owner 擁有互斥量的線程指針
tx_mutex_inherit 優先級繼承標誌
tx_mutex_original_priority 擁有互斥量的線程的原始優先級
tx_mutex_original_threshold 擁有互斥量的線程的原始搶佔門限
tx_mutex_suspension_list 互斥量掛起list指針
tx_mutex_suspended_count 互斥量掛起list上線程個數
tx_mutex_created_next 指向下一個互斥量指針
tx_mutex_created_previous 指向前一個互斥量指針

互斥量隊列

系統中所有互斥量掛載同一個鏈表中,_tx_mutex_created_ptr執行鏈表頭部。tx_mutex_created_next 指向下一個互斥量,tx_mutex_created_previous 指向前一個互斥量。

TX_MUTEX    *_tx_mutex_created_ptr;

在這裏插入圖片描述

互斥量API

函數 描述
UINT _tx_mutex_create(TX_MUTEX *mutex_ptr, CHAR *name_ptr, UINT inherit) 創建互斥量
UINT _tx_mutex_delete(TX_MUTEX *mutex_ptr) 刪除互斥量
UINT _tx_mutex_get(TX_MUTEX *mutex_ptr, ULONG wait_option) 申請互斥量
UINT _tx_mutex_info_get(TX_MUTEX *mutex_ptr, CHAR **name, ULONG *count, TX_THREAD **owner,TX_THREAD **first_suspended, ULONG *suspended_count,TX_MUTEX **next_mutex 獲取互斥量信息
UINT _tx_mutex_prioritize(TX_MUTEX *mutex_ptr) 調整最高優先級線程到互斥量掛起隊列的最前面
UINT _tx_mutex_put(TX_MUTEX *mutex_ptr) 釋放擁有的互斥量
VOID _tx_mutex_priority_change(TX_THREAD *thread_ptr, UINT new_priority, UINT new_threshold) 改變線程優先級和搶佔門限
VOID _tx_mutex_cleanup(TX_THREAD *thread_ptr) clean線程在互斥量數據結構

互斥量創建_tx_mutex_create

_tx_mutex_create創建互斥量,函數很簡單。 同一資源的互斥量只創建一次,互斥量創建時並沒有擁有者。
線程使用時需要申請。

UINT    _tx_mutex_create(TX_MUTEX *mutex_ptr, CHAR *name_ptr, UINT inherit)
{

    TX_INTERRUPT_SAVE_AREA

    TX_MUTEX   *tail_ptr;                   /* Working mutex pointer  */


    /* Setup the basic mutex fields.  */
    mutex_ptr -> tx_mutex_name =             name_ptr;
    mutex_ptr -> tx_mutex_ownership_count =  0;
    #def 優先級繼承標誌
    mutex_ptr -> tx_mutex_inherit =          inherit;
    mutex_ptr -> tx_mutex_suspension_list =  TX_NULL;
    mutex_ptr -> tx_mutex_suspended_count =  0;

    /* Disable interrupts to place the mutex on the created list.  */
    TX_DISABLE

    /* Setup the mutex ID to make it valid.  */
    mutex_ptr -> tx_mutex_id =  TX_MUTEX_ID;

    /* Place the mutex on the list of created mutexes.  First,
       check for an empty list.  */
    #def 把互斥量插入_tx_mutex_created_ptr 隊列
    if (_tx_mutex_created_ptr)
    {

        /* Pickup tail pointer.  */
        tail_ptr =  _tx_mutex_created_ptr -> tx_mutex_created_previous;

        /* Place the new mutex in the list.  */
        _tx_mutex_created_ptr -> tx_mutex_created_previous =  mutex_ptr;
        tail_ptr -> tx_mutex_created_next =                   mutex_ptr;

        /* Setup this mutex's next and previous created links.  */
        mutex_ptr -> tx_mutex_created_previous =  tail_ptr;
        mutex_ptr -> tx_mutex_created_next =      _tx_mutex_created_ptr;
    }
    else
    {

        /* The created mutex list is empty.  Add mutex to empty list.  */
        _tx_mutex_created_ptr =                   mutex_ptr;
        mutex_ptr -> tx_mutex_created_next =      mutex_ptr;
        mutex_ptr -> tx_mutex_created_previous =  mutex_ptr;
    }

    /* Increment the number of mutexes created counter.  */
    _tx_mutex_created_count++;

    /* Restore interrupts.  */
    TX_RESTORE

    /* Return TX_SUCCESS.  */
    return (TX_SUCCESS);
}

刪除互斥量 _tx_semaphore_delete

刪除互斥量:
1,把互斥量從_tx_mutex_created_ptr 隊列刪除。
2,把tx_mutex_suspension_list隊列中線程移除,清除互斥量數據結構,並恢復線程

UINT    _tx_mutex_delete(TX_MUTEX *mutex_ptr)
{

    TX_INTERRUPT_SAVE_AREA

    TX_THREAD       *thread_ptr;                /* Working thread pointer  */


    /* Disable interrupts to remove the mutex from the created list.  */
    TX_DISABLE

    /* Decrement the number of mutexes created.  */
    _tx_mutex_created_count--;

    /* Clear the mutex ID to make it invalid.  */
    mutex_ptr -> tx_mutex_id =  0;

    /* See if the mutex is the only one on the list.  */
    #def 從_tx_mutex_created_ptr 刪除mutex
    if (mutex_ptr == mutex_ptr -> tx_mutex_created_next)
    {

        /* Only created mutex, just set the created list to NULL.  */
        _tx_mutex_created_ptr =  TX_NULL;
    }
    else
    {

        /* Link-up the neighbors.  */
        (mutex_ptr -> tx_mutex_created_next) -> tx_mutex_created_previous =
            mutex_ptr -> tx_mutex_created_previous;
        (mutex_ptr -> tx_mutex_created_previous) -> tx_mutex_created_next =
            mutex_ptr -> tx_mutex_created_next;

        /* See if we have to update the created list head pointer.  */
        if (_tx_mutex_created_ptr == mutex_ptr)

            /* Yes, move the head pointer to the next link. */
            _tx_mutex_created_ptr =  mutex_ptr -> tx_mutex_created_next;
    }

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

    /* Restore interrupts.  */
    TX_RESTORE

    /* Walk through the mutex list to resume any and all threads suspended
       on this mutex.  */
    thread_ptr =  mutex_ptr -> tx_mutex_suspension_list;
    #def 從tx_mutex_suspension_list移除線程,清除數據,並恢復線程
    while (mutex_ptr -> tx_mutex_suspended_count)
    {
        /* Lockout interrupts.  */
        TX_DISABLE

        /* Clear the cleanup pointer, this prevents the timeout from doing
           anything.  */
        thread_ptr -> tx_suspend_cleanup =  TX_NULL;

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

        /* Restore interrupts.  */
        TX_RESTORE

        /* Yes, deactivate the thread's timer just in case.  */
        _tx_timer_deactivate(&(thread_ptr -> tx_thread_timer));

        /* Set the return status in the thread to TX_DELETED.  */
        thread_ptr -> tx_suspend_status =  TX_DELETED;

        /* Move the thread pointer ahead.  */
        thread_ptr =  thread_ptr -> tx_suspended_next;

        /* Resume the thread.  */
        _tx_thread_resume(thread_ptr -> tx_suspended_previous);

        /* Decrease the suspended count.  */
        mutex_ptr -> tx_mutex_suspended_count--;
    }

    /* Disable interrupts.  */
    TX_DISABLE

    /* Release previous preempt disable.  */
    _tx_thread_preempt_disable--;

    /* Restore interrupts.  */
    TX_RESTORE

    /* Check for preemption.  */
    if (_tx_thread_current_ptr != _tx_thread_execute_ptr)

        /* Transfer control to system.  */
        _tx_thread_system_return();

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