Threadx 申请互斥量 _tx_mutex_get

news/2024/5/19 6:43:07 标签: mutex, 操作系统

文章目录

mutex_get_2">申请互斥量 _tx_mutex_get

_tx_mutex_get用于申请互斥量:
1,如果是系统中第一个申请互斥量线程,tx_mutex_ownership_count 设置为1,申请成功。
2,如果是拥有互斥量的线程再次申请,那么只需tx_mutex_ownership_count 计数器加一,申请成功。
3,如果申请互斥量的当前线程不是拥有互斥量的线程,需要把当前线程挂入tx_mutex_suspension_list队列:
(1)如果设置了优先级继承,并且当前线程优先级高于拥有互斥量线程的优先级,那么设置拥有互斥量线程的优先级
为当前线程优先级;
4,挂起队列中线程优先级一定大于拥有者线程优先级,因为只有高优先级才能够打断拥有者线程,尝试申请互斥量

UINT    _tx_mutex_get(TX_MUTEX *mutex_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 mutex.  */
    TX_DISABLE

    /* Determine if there is an instance of the mutex.  */
   
    if (!mutex_ptr -> tx_mutex_ownership_count)
    {
     #def 第一次线程申请互斥量
        /* Set the ownership count to 1.  */
        mutex_ptr -> tx_mutex_ownership_count =  1;

        /* Remember that the calling thread owns the mutex.  */
        mutex_ptr -> tx_mutex_owner =  _tx_thread_current_ptr;

        /* Determine if priority inheritance is required.  */
        if ((mutex_ptr -> tx_mutex_inherit) && (_tx_thread_current_ptr))
        { 
        #def 设置了优先级继承,保存原始的优先级和抢占门限
            /* Remember the current priority and threshold of thread.  */
            mutex_ptr -> tx_mutex_original_priority =  _tx_thread_current_ptr -> tx_priority;
            mutex_ptr -> tx_mutex_original_threshold = _tx_thread_current_ptr -> tx_preempt_threshold;
        }

        /* Set status to success.  */
        status =  TX_SUCCESS;
    }
    else if (mutex_ptr -> tx_mutex_owner == _tx_thread_current_ptr)
    {
		#def 本线程已经拥有了这个互斥量,已经申请过。再次申请,只需tx_mutex_ownership_count计数器加一
        /* The owning thread is requesting the mutex again, just
           increment the ownership count.  */
        mutex_ptr -> tx_mutex_ownership_count++;

        /* Set status to success.  */
        status =  TX_SUCCESS;
    }
    else
    {
		#def 互斥量已经被其他线程申请成功; 本线程进行申请
		#def 1,wait_option =0 本线程不等待互斥量释放,直接返回
		#def 2,wait_option 不为0,本线程挂入tx_mutex_suspension_list队列,自我挂起
		
        /* 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_mutex_cleanup,如果后续这个线程不再等待信号量,会回调tx_suspend_cleanup ,清除互斥量相关的data struct
       
            thread_ptr -> tx_suspend_cleanup =  _tx_mutex_cleanup;

            /* Setup cleanup information, i.e. this mutex control
               block.  */
            thread_ptr -> tx_suspend_control_block = (VOID_PTR) mutex_ptr;
			
			#def 插入到互斥量挂起队列tx_mutex_suspension_list,这里挂入了尾部,也就是FIFO。这里并没有按照线程优先级,把最高优先级插入到最前面
            /* Setup suspension list.  */
            if (mutex_ptr -> tx_mutex_suspension_list)
            {

                /* This list is not NULL, add current thread to the end. */
                thread_ptr -> tx_suspended_next =
                    mutex_ptr -> tx_mutex_suspension_list;
                thread_ptr -> tx_suspended_previous =
                    (mutex_ptr -> tx_mutex_suspension_list) -> tx_suspended_previous;
                ((mutex_ptr -> tx_mutex_suspension_list) -> tx_suspended_previous) -> tx_suspended_next =
                    thread_ptr;
                (mutex_ptr -> tx_mutex_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.  */
                mutex_ptr -> tx_mutex_suspension_list =  thread_ptr;
                thread_ptr -> tx_suspended_next =        thread_ptr;
                thread_ptr -> tx_suspended_previous =    thread_ptr;
            }

            /* Increment the suspended thread count.  */
            mutex_ptr -> tx_mutex_suspended_count++;
            
            /* Set the state to suspended.  */
            #def 设置为挂起状态
            thread_ptr -> tx_state =    TX_MUTEX_SUSP;

            /* Set the suspending flag.  */
            #def 设置为true,表示正在挂起过程;_tx_thread_suspend或resume中用到这个标志
            thread_ptr -> tx_suspending =  TX_TRUE;

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

            /* Save the timeout value.  */
            #def wait_option为线程等待互斥量时间,需要开启定时器;定时器超时就调用前面设置的tx_suspend_cleanup 
            thread_ptr -> tx_thread_timer.tx_remaining_ticks =  wait_option;

            /* Restore interrupts.  */
            TX_RESTORE

            /* Determine if we need to raise the priority of the thread
               owning the mutex.  */
              #def 如果设置了优先级继承标志,
            if ((mutex_ptr -> tx_mutex_inherit) && (mutex_ptr -> tx_mutex_owner)
                && (_tx_thread_current_ptr))
            {

                /* Priority inheritance is requested, check to see if the
                   thread that owns the mutex is lower priority.  */
                   #def 如果当前申请互斥量线程优先级高于 互斥量拥有者的线程,那么把互斥量拥有者的线程设置为当前线程优先级,抢占门限也设置为当前线程优先级。 这样保证了拥有互斥量线程优先级最高,防止了中等优先级线程抢占, 这样高优先级等待互斥量时间 由  拥有互斥量线程 占用互斥量的时间。把不确定变为了确定。                 
                if ((mutex_ptr -> tx_mutex_owner) -> tx_priority >
                    _tx_thread_current_ptr -> tx_priority)
                {

                    /* Yes, raise the suspended, owning thread's priority to that
                       of the current thread.  */
                    _tx_mutex_priority_change(mutex_ptr -> tx_mutex_owner, _tx_thread_current_ptr -> tx_priority, _tx_thread_current_ptr -> tx_priority);
                }
            }

            /* See if we need to start a timer.  */
            #def wait_option 不是永久等待时,启动等待定时器
            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_thread_suspend(thread_ptr);

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

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

    /* Restore interrupts.  */
    TX_RESTORE

    /* Return completion status.  */
    return (status);
}

mutex_prioritize_176">_tx_mutex_prioritize

_tx_mutex_prioritize把最高优先级线程挂到tx_mutex_suspension_list最前面

UINT    _tx_mutex_prioritize(TX_MUTEX *mutex_ptr)
{

    TX_INTERRUPT_SAVE_AREA

    REG_1   TX_THREAD   *thread_ptr;            /* Working thread pointer  */
    REG_2   TX_THREAD   *priority_thread_ptr;   /* Highest priority thread */


    /* Disable interrupts.  */
    TX_DISABLE

    /* Determine if there how many threads are suspended on this mutex.  */
    
    if (mutex_ptr -> tx_mutex_suspended_count == 2)
    {
#def list中只有两个线程,只需要把tx_mutex_suspension_list指向优先级最高线程
        /* Determine if the next suspended thread has a higher priority.  */
        if (((mutex_ptr -> tx_mutex_suspension_list) -> tx_suspended_next) -> tx_priority <
            ((mutex_ptr -> tx_mutex_suspension_list) -> tx_priority))
        {

            /* Yes, move the list head to the next thread.  */
            mutex_ptr -> tx_mutex_suspension_list =
                (mutex_ptr -> tx_mutex_suspension_list) -> tx_suspended_next;
        }
    }
    else if (mutex_ptr -> tx_mutex_suspended_count > 2)
    {

        /* Default the highest priority thread to the thread at the front of the list.  */
        priority_thread_ptr =  mutex_ptr -> tx_mutex_suspension_list;

        /* Setup search pointer.  */
        thread_ptr =  priority_thread_ptr -> tx_suspended_next;
		
		#def 从tx_mutex_suspension_list队列中找出优先级最高的线程
        /* Search through the list to find the highest priority thread.  */
        do
        {

            /* Is the current thread higher priority?  */
            if (thread_ptr -> tx_priority < priority_thread_ptr -> tx_priority)
            {

                /* Yes, remember that this thread is the highest priority.  */
                priority_thread_ptr =  thread_ptr;
            }

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

        }
        while (thread_ptr != mutex_ptr -> tx_mutex_suspension_list);

        /* Now determine if the highest priority thread is at the front
           of the list.  */
         #def 如果优先级最高线程不是在队列最前面,那么先从队列中remove 最高优先级线程,再插入到队列最前面
        if (priority_thread_ptr != mutex_ptr -> tx_mutex_suspension_list)
        {

            /* No, we need to move the highest priority suspended thread to the
               front of the list.  */

            /* First, remove the highest priority thread by updating the
               adjacent suspended threads.  */
            (priority_thread_ptr -> tx_suspended_next) -> tx_suspended_previous =
                priority_thread_ptr -> tx_suspended_previous;
            (priority_thread_ptr -> tx_suspended_previous) -> tx_suspended_next =
                priority_thread_ptr -> tx_suspended_next;

            /* Now, link the highest priority thread at the front of the list.  */
            priority_thread_ptr -> tx_suspended_next =
                mutex_ptr -> tx_mutex_suspension_list;
            priority_thread_ptr -> tx_suspended_previous =
                (mutex_ptr -> tx_mutex_suspension_list) -> tx_suspended_previous;
            ((mutex_ptr -> tx_mutex_suspension_list) -> tx_suspended_previous) -> tx_suspended_next =
                priority_thread_ptr;
            (mutex_ptr -> tx_mutex_suspension_list) -> tx_suspended_previous =   priority_thread_ptr;

            /* Move the list head pointer to the highest priority suspended thread.  */
            mutex_ptr -> tx_mutex_suspension_list =  priority_thread_ptr;
        }
    }

    /* Restore interrupts.  */
    TX_RESTORE

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

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

相关文章

Threadx 释放互斥量_tx_mutex_put

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

Threadx 信号量semaphore

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

Threadx 申请信号量_tx_semaphore_get

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

Threadx 释放信号量_tx_semaphore_put

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

Threadx 消息队列 queue

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

Threadx 消息队列-发送消息_tx_queue_send

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

Threadx 消息队列-接收消息_tx_queue_receive

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

Threadx 定时器timer

文章目录定时器管理结构定时器链表定时器激活链表定时器工作原理定时器API定时器创建_tx_timer_create删除定时器_tx_timer_delete修改_tx_timer_changeThreadx 操作系统定时器提供单次定时和周期性定时功能。定时器由周期性定时中断驱动&#xff0c;每一个定时中断称为一个时钟…