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