Threadx 释放互斥量_tx_mutex_put

news/2024/5/19 3:26:35 标签: rtos, mutex

mutex_put_0">释放互斥量_tx_mutex_put

1,只有拥有互斥量的线程才能够释放互斥量
2,计数器减1后,值不是0,说明本线程多次申请了互斥量,那么本线程继续占有互斥量,函数返回
3,挂起队列中有线程等待互斥量资源,那么需要恢复挂起线程
4,挂起队列中线程优先级一定比拥有互斥量线程优先级高,因为低优先级获取了互斥量后,只有高优先级线程能够打断低优先级线程,并尝试获取互斥量,并挂在挂起队列中。 如果是高优先级线程先获取了互斥量,低优先级线程不可能打断高优先级线程。
5,如果设置了优先级继承,把最高优先级线程放在挂起队列最前面,保证最高优先级先恢复执行。如果没有设置优先级继承,那么恢复的线程就是tx_mutex_suspension_list队列最前面的,不一定是最高优先级队列,是按照FIFO原则进出
6,如果设置了优先级继承,需要恢复互斥量拥有着线程的优先级为原始优先级

UINT    _tx_mutex_put(TX_MUTEX *mutex_ptr)
{

    TX_INTERRUPT_SAVE_AREA

    REG_1   TX_THREAD   *thread_ptr = NULL;            /* Working thread pointer          */
    REG_2   TX_THREAD   *old_owner = NULL;             /* Remember previous mutex owner   */
    REG_3   UINT        old_priority;           /* Original thread priority        */
    REG_3   UINT        old_threshold;          /* Original thread threshold       */

    /* Disable interrupts to put an instance back to the mutex.  */
    TX_DISABLE

    /* Determine if this thread owns the mutex.  */
    #def 只有拥有互斥量的线程才能够释放互斥量
    if ((mutex_ptr -> tx_mutex_ownership_count) &&
        (mutex_ptr -> tx_mutex_owner == _tx_thread_current_ptr))
    {

        /* Yes, this thread does own the mutex.  */

        /* Decrement the mutex ownership count.  */
        #def 计数器减1
        mutex_ptr -> tx_mutex_ownership_count--;

        /* Determine if the mutex is still owned by the current thread.  */
        #def 计数器减1后,值不是0,说明本线程多次申请了互斥量,那么本线程继续占有互斥量,函数返回
        if (mutex_ptr -> tx_mutex_ownership_count)
        {

            /* Restore interrupts.  */
            TX_RESTORE

            /* Mutex is still owned, just return successful status.  */
            return (TX_SUCCESS);
        }
        else
        {
			#def 计数器减1后为0,说明本线程不再拥有互斥量。看看是否有其他线程正在等待互斥量,也就是tx_mutex_suspension_list队列是否有挂载线程
			
            /* Yes, the mutex is available we now need to check for a waiting thread.  */

            /* Determine if priority inheritance is in effect.  */
            #def 设置了优先级继承,把最高优先级线程放在挂起队列最前面,保证最高优先级先恢复执行
            #def 如果没有设置优先级继承,那么恢复的线程就是tx_mutex_suspension_list队列最前面的,不一定是最高优先级队列,是按照FIFO原则进出。
            if ((mutex_ptr -> tx_mutex_inherit) && (mutex_ptr -> tx_mutex_suspension_list))
            {

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

                /* Restore interrupts.  */
                TX_RESTORE

                /* Call the mutex prioritize processing to ensure the
                   highest priority thread is resumed.  */
                   #def 把最高优先级线程放在挂起队列最前面
                _tx_mutex_prioritize(mutex_ptr);

                /* At this point, the highest priority thread is at the
                   front of the suspension list.  */

                /* Disable interrupts.  */
                TX_DISABLE

                /* Back off the preemption disable.  */
                _tx_thread_preempt_disable--;
            }
			
			#def 挂起队列为空,说明没有等待互斥量的线程,不需要恢复挂起线程
            if (mutex_ptr -> tx_mutex_suspension_list == TX_NULL)
            {

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

                /* Restore interrupts.  */
                TX_RESTORE

                /* Mutex is not owned, but it is possible that a thread that
                   caused a priority inheritance to occur is no longer waiting
                   on the mutex.  */
                   #def 如果在申请互斥量是设置了优先级继承,也就是把低优先级进程优先级改为高优先级进程的优先级,现在需要设置为原始优先级
                if ((mutex_ptr -> tx_mutex_inherit) && (_tx_thread_current_ptr) &&
                    (_tx_thread_current_ptr -> tx_priority != mutex_ptr -> tx_mutex_original_priority))
                {

                    /* Restore the current priority and threshold of thread.  */
                    _tx_mutex_priority_change(mutex_ptr -> tx_mutex_owner, mutex_ptr -> tx_mutex_original_priority,
                                              mutex_ptr -> tx_mutex_original_threshold);
                }


                /* Disable interrupts again.  */
                TX_DISABLE

                /* Back off the preemption disable.  */
                _tx_thread_preempt_disable--;

                /* Restore interrupts.  */
                TX_RESTORE

                /* Check for a preemption condition that might be present.  */
                #def 开中断后,可能更高优先级线程变为了可执行线程,需要进行切换
                if ((_tx_thread_current_ptr != _tx_thread_execute_ptr) &&
                    (_tx_thread_system_state == 0))
                {

                    /* Return control to the system.  */
                    #def 进行切换
                    _tx_thread_system_return();
                }

                /* Return success.  */
                return (TX_SUCCESS);
            }
            else
            {
				#def 挂起队列中有线程等待互斥量资源,那么需要恢复挂起线程
				#def 挂起队列中线程优先级一定比拥有互斥量线程优先级高,因为低优先级获取了互斥量后,只有高优先级线程能够打断低优先级线程,并尝试获取互斥量,并挂在挂起队列中。  如果是高优先级线程先获取了互斥量,低优先级线程不可能打断高优先级线程
				#def  如果设置了优先级继承,把最高优先级线程放在挂起队列最前面,保证最高优先级先恢复执行。如果没有设置优先级继承,那么恢复的线程就是tx_mutex_suspension_list队列最前面的,不一定是最高优先级队列,是按照FIFO原则进出
				#def 如果设置了优先级继承,需要恢复互斥量拥有着线程的优先级为原始优先级
                /* Pickup the thread a the front of the suspension list.  */
                thread_ptr =  mutex_ptr ->tx_mutex_suspension_list;

                /* Save the previous ownership information, if inheritance is
                   in effect.  */
                if (mutex_ptr ->tx_mutex_inherit)
                {
                	#def 临时记录,后面要恢复互斥量拥有着线程的优先级为原始优先级
                    old_owner =     mutex_ptr ->tx_mutex_owner;            
                    old_priority =  mutex_ptr->tx_mutex_original_priority;
                    old_threshold = mutex_ptr->tx_mutex_original_threshold;
					
					#def thread_ptr 一定是最高优先级线程,因为前面已经调整过队列。 保存原始优先级
                    mutex_ptr ->tx_mutex_original_priority =   thread_ptr ->tx_priority;
                    mutex_ptr ->tx_mutex_original_threshold =  thread_ptr ->tx_preempt_threshold;         
                }

                /* Mark the Mutex as owned and fill in the corresponding information.  */
                #def 设置新的计数器为1,拥有者为新的线程
                mutex_ptr ->tx_mutex_ownership_count =  1;
                mutex_ptr ->tx_mutex_owner = thread_ptr;

                /* Remove the suspended thread from the list.  */

                /* See if this is the only suspended thread on the list.  */
                if (thread_ptr == thread_ptr ->tx_suspended_next)
                {

                    /* Yes, the only suspended thread.  */

                    /* Update the head pointer.  */
                    mutex_ptr ->tx_mutex_suspension_list =  TX_NULL;
                }
                else
                {

                    /* At least one more thread is on the same expiration list.  */

                    /* Update the list head pointer.  */
                    mutex_ptr -> tx_mutex_suspension_list =  thread_ptr -> tx_suspended_next;

                    /* Update the links of the adjacent threads.  */
                    (thread_ptr -> tx_suspended_next) -> tx_suspended_previous =
                        thread_ptr -> tx_suspended_previous;
                    (thread_ptr -> tx_suspended_previous) -> tx_suspended_next =
                        thread_ptr -> tx_suspended_next;
                }

                /* Decrement the suspension count.  */
                mutex_ptr -> tx_mutex_suspended_count--;

                /* Prepare for resumption of the first thread.  */

                /* Clear cleanup routine to avoid timeout.  */
                thread_ptr -> tx_suspend_cleanup =  TX_NULL;

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

                /* Restore interrupts.  */
                TX_RESTORE
				
				#def 关闭之前设置的定时器
                /* Deactivate the timeout timer if necessary.  */					
                if (thread_ptr -> tx_thread_timer.tx_list_head)
                {

                    /* Deactivate the thread's timeout timer.  */
                    _tx_timer_deactivate(&(thread_ptr -> tx_thread_timer));
                }
                else
                {

                    /* Clear the remaining time to ensure timer doesn't get activated.  */
                    thread_ptr -> tx_thread_timer.tx_remaining_ticks =  0;
                }

                /* Put return status into the thread control block.  */
                thread_ptr -> tx_suspend_status =  TX_SUCCESS;

                /* Restore previous priority needs to be restored after priority
                   inheritance.  */
    			#def 恢复old线程的优先级
                if ((mutex_ptr ->tx_mutex_inherit) && (old_owner) &&
                    (old_owner ->tx_priority != old_priority))
                {

                    /* Restore the current priority and threshold of thread.  */
                    _tx_mutex_priority_change(old_owner, old_priority, old_threshold);
                }

                /* Resume thread.  */
                #def 恢复新的互斥量拥有者线程
                if (_tx_thread_resume(thread_ptr))

                    /* Return control to the system.  */
                    _tx_thread_system_return();

                /* Return a successful status.  */
                return (TX_SUCCESS);
            }
        }
    }

    /* Restore interrupts.  */
    TX_RESTORE

    /* Caller does not own the mutex.  */
    return (TX_NOT_OWNED);
}

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

相关文章

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有挂起线程,说明发送线程由于消息队列已满而挂起,挂起时把发送的消息 存放到了发送线程的…

Threadx 定时器timer

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

Threadx 激活定时器和去激活定时器tx_timer_activate

文章目录tx_timer_activatetx_timer_deactivate_tx_timer_deactivate分析激活定时器和去激活定时器函数。tx_timer_activate _tx_timer_activate_api(TX_TIMER *timer_ptr) 用来激活已经创建的定时器。 UINT _tx_timer_activate_api(TX_TIMER *timer_ptr) {/* Check for a…