Threadx 釋放互斥量_tx_mutex_put

釋放互斥量_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);
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章