釋放互斥量_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);
}