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);
}
发布了41 篇原创文章 · 获赞 2 · 访问量 3253

猜你喜欢

转载自blog.csdn.net/qq_45683435/article/details/104188498