Threadx 互斥量mutex

news/2024/5/19 2:38:55 标签: mutex

文章目录

    • 互斥量控制块
    • 互斥量队列
    • 互斥量API
    • 互斥量创建_tx_mutex_create
    • 删除互斥量 _tx_semaphore_delete

互斥量用来保证对共享资源或临界区的访问唯一性,保证在指定范围内,只能有一个线程访问该共享资源。
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线程在互斥量数据结构

mutex_create_83">互斥量创建_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);
}

http://www.niftyadmin.cn/n/1428576.html

相关文章

Threadx 申请互斥量 _tx_mutex_get

文章目录申请互斥量 _tx_mutex_get_tx_mutex_prioritize申请互斥量 _tx_mutex_get _tx_mutex_get用于申请互斥量: 1,如果是系统中第一个申请互斥量线程,tx_mutex_ownership_count 设置为1,申请成功。 2,如果是拥有互斥…

Threadx 释放互斥量_tx_mutex_put

释放互斥量_tx_mutex_put 1,只有拥有互斥量的线程才能够释放互斥量 2,计数器减1后,值不是0,说明本线程多次申请了互斥量,那么本线程继续占有互斥量,函数返回 3,挂起队列中有线程等待互斥量资源…

Threadx 信号量semaphore

文章目录信号量控制块信号量队列信号量API优先级翻转信号量创建_tx_semaphore_create删除信号量_tx_semaphore_delete信号量(semaphore)用来保护共享资源,临界区访问,同步;可以用于生产者-消费者模式中提供事件通知。如…

Threadx 申请信号量_tx_semaphore_get

申请信号量_tx_semaphore_get 1,如果信号量计数器tx_semaphore_count不为0,就减一,返回申请成功。 2,如果信号量计数器tx_semaphore_count为0,说明资源都被占用,挂起当前线程到tx_semaphore_suspension_li…

Threadx 释放信号量_tx_semaphore_put

释放信号量_tx_semaphore_put 1,如果tx_semaphore_suspension_list挂起队列为空,那么直接把tx_semaphore_count计数器加一 2,如果tx_semaphore_suspension_list挂起队列不为空,那么tx_semaphore_suspension_list最前面线程获取释…

Threadx 消息队列 queue

文章目录消息传递规则消息大小消息队列控制块消息队列list消息队列API创建消息队列_tx_queue_create删除队列_tx_queue_delete清空消息队列_tx_queue_flushThreadx提供了消息队列进行线程间通信。消息队列中消息通常按照先进先出规则传递,同时提供了把消息直接存储到…

Threadx 消息队列-发送消息_tx_queue_send

消息队列-发送消息_tx_queue_send 1,发送消息会插入到队列尾部。 2,如果消息队列有挂起的接收线程,发送消息时,可以直接把消息放到接收线程的缓冲中,这可以降低消息传递延时。 TX_THREAD线程控制块中tx_additional_su…

Threadx 消息队列-接收消息_tx_queue_receive

消息队列-接收消息_tx_queue_receive 1,如果消息队列有消息,从队列头部取出消息 (1)并且tx_queue_suspension_list有挂起线程,说明发送线程由于消息队列已满而挂起,挂起时把发送的消息 存放到了发送线程的…