釋放信號量_tx_semaphore_put
1,如果tx_semaphore_suspension_list掛起隊列爲空,那麼直接把tx_semaphore_count計數器加一
2,如果tx_semaphore_suspension_list掛起隊列不爲空,那麼tx_semaphore_suspension_list最前面線程獲取釋放的信號量,
並恢復線程。這裏採用的FIFO,並沒有按照優先級高低選擇恢復線程。
_tx_semaphore_put函數在釋放信號量是並沒有檢查當前釋放信號量的線程是不是線程的擁有者,信號量並沒有所有權屬性。
這種特性可以用來進行事件通知,比如一個線程不斷等待信號量,成功後處理任務;另一個線程,進行信號量釋放。
這種特性,任何線程都可以釋放信號量。
UINT _tx_semaphore_put(TX_SEMAPHORE *semaphore_ptr)
{
TX_INTERRUPT_SAVE_AREA
REG_1 TX_THREAD *thread_ptr; /* Working thread pointer */
/* Disable interrupts to put an instance back to the semaphore. */
TX_DISABLE
/* Determine if there are any threads suspended on the semaphore. */
thread_ptr = semaphore_ptr -> tx_semaphore_suspension_list;
#def tx_semaphore_suspension_list不爲空,隊列頭部線程獲得信號量,恢復線程
if (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. */
semaphore_ptr -> tx_semaphore_suspension_list = TX_NULL;
}
else
{
/* At least one more thread is on the same expiration list. */
/* Update the list head pointer. */
semaphore_ptr -> tx_semaphore_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. */
semaphore_ptr -> tx_semaphore_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
/* Deactivate the timeout timer if necessary. */
#def 關閉定時器
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;
semaphore_ptr->sema_last_owner = thread_ptr;
/* Resume thread. */
#def 恢復線程
if (_tx_thread_resume(thread_ptr))
/* Preemption is required, transfer control back to
system. */
_tx_thread_system_return();
/* Return success. */
return (TX_SUCCESS);
}
else
{
#def 沒有線程掛起等待信號量,信號量計數器加1
/* Increment the semaphore count. */
semaphore_ptr -> tx_semaphore_count++;
semaphore_ptr->sema_last_owner = 0;
}
/* Restore interrupts. */
TX_RESTORE
/* Return successful completion status. */
return (TX_SUCCESS);
}