tx_block_release
应用程序调用tx_block_release释放分配的内存。
如果tx_block_pool_suspension_list 链表有线程挂起,把释放的块给挂起线程,并恢复线程。
如果没有挂起线程等待内存释放,那么释放的内存块,直接插入空闲内存块头部,这样操作简单,不需要遍历链表,开销少。修改内存块控制字段,指向下一个块首地址
UINT _tx_block_release(VOID *block_ptr)
{
TX_INTERRUPT_SAVE_AREA
REG_1 TX_BLOCK_POOL *pool_ptr; /* Pool pointer */
REG_2 TX_THREAD *thread_ptr; /* Working thread pointer */
REG_3 CHAR_PTR work_ptr; /* Working block pointer */
/* Disable interrupts to put this block back in the pool. */
#def 禁止中断
TX_DISABLE
/* Pickup the pool pointer which is just previous to the starting
address of the block that the caller sees. */
#def 释放内存首地址后退sizeof(CHAR_PTR)是释放内存块的控制字段,存储了线程池管理结构指针
work_ptr = ((CHAR_PTR) block_ptr) - sizeof(CHAR_PTR);
pool_ptr = *((TX_BLOCK_POOL_PTR *) work_ptr);
/* Determine if there are any threads suspended on the block pool. */
#def 检查挂起链表
thread_ptr = pool_ptr -> tx_block_pool_suspension_list;
if (thread_ptr)
{
#def 移除挂起链表线程,这里按照fifo,没有按照线程优先级高低顺序。
/* 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. */
pool_ptr -> tx_block_pool_suspension_list = TX_NULL;
}
else
{
/* At least one more thread is on the same expiration list. */
/* Update the list head pointer. */
pool_ptr -> tx_block_pool_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. */
pool_ptr -> tx_block_pool_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
/* Return this block pointer to the suspended thread waiting for
a block. */
#def 之前在tx_block_allocate函数中挂起线程时,tx_additional_suspend_info保存了应用程序传入的存储内存地址的指针
#def 所以这里把申请到的内存赋值给 *tx_additional_suspend_info
*((CHAR_PTR *) thread_ptr -> tx_additional_suspend_info) = (CHAR_PTR) block_ptr;
/* 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. */
#def 设置状态,tx_suspend_status 用于tx_block_allocate函数返回值
thread_ptr -> tx_suspend_status = TX_SUCCESS;
/* 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
{
/* No thread is suspended for a memory block. */
/* Put the block back in the available list. */
*((CHAR_PTR *) work_ptr) = pool_ptr -> tx_block_pool_available_list;
/* Adjust the head pointer. */
pool_ptr -> tx_block_pool_available_list = work_ptr;
/* Increment the count of available blocks. */
pool_ptr -> tx_block_pool_available++;
}
/* Restore interrupts. */
TX_RESTORE
/* Return completion status. */
return (TX_SUCCESS);
}