Threadx 块内存分配tx_block_allocate

tx_block_allocate

应用程序调用tx_block_allocate申请分配内存。
pool_ptr指向内存池指针
block_ptr指向指针的指针,用于存储申请的内存起始地址
wait_option等待选项,
如果没有足够内存,wait_option为0,直接返回;wait_option为TX_WAIT_FOREVER,永久挂起;
wait_option不为0,也不是TX_WAIT_FOREVER,开启定时器,定时值为wait_option。定时器超时,线程恢复,并清除相关数据。

如果有空闲内存,直接返回tx_block_pool_available_list指向的内存块;
如果内存不够,可以挂起线程到tx_block_pool_suspension_list链表,其他线程内存释放后,恢复挂起的线程。

UINT    _tx_block_allocate(TX_BLOCK_POOL *pool_ptr, VOID **block_ptr, ULONG wait_option)
{

    TX_INTERRUPT_SAVE_AREA

    REG_1   UINT        status;                 /* Return status           */
    REG_2   TX_THREAD   *thread_ptr;            /* Working thread pointer  */
    REG_3   CHAR_PTR    work_ptr;               /* Working block pointer   */


    /* Disable interrupts to get a block from the pool.  */
    #def 禁止中断,防止打断
    TX_DISABLE

    /* Determine if there is an available block.  */
    #def 检查是否还有可用内存块
    if (pool_ptr -> tx_block_pool_available)
    {
		#def 有可用内存块
        /* Yes, a block is available.  Decrement the available count.  */
        #def 可用内存块个数减1
        pool_ptr -> tx_block_pool_available--;

        /* Pickup the current block pointer.  */
        #def tx_block_pool_available_list指向可用内存链表中最前面块,返回给最前面块给用户
        work_ptr =  pool_ptr -> tx_block_pool_available_list;

        /* Return the first available block to the caller.  */
        #def 设置入参,址传递, 需要跨过控制字段sizeof(CHAR_PTR)
        *((CHAR_PTR *) block_ptr) =  work_ptr + sizeof(CHAR_PTR);

        /* Modify the available list to point at the next block in the pool. */
        #def *((CHAR_PTR *) work_ptr)中存储的是下一空闲块,下一空变为头部
        pool_ptr -> tx_block_pool_available_list =
            *((CHAR_PTR *) work_ptr);

        /* Save the pool's address in the block for when it is released!  */
        #def 把刚刚分配的块控制字段存储内存池管理结构指针
        *((CHAR_PTR *) work_ptr) = (CHAR_PTR) pool_ptr;

        /* Set status to success.  */
        status =  TX_SUCCESS;
    }
    else
    {
		#def 没有可用的内存空间
        /* Determine if the request specifies suspension.  */
        #def wait_option不为0,就挂起线程到tx_block_pool_suspension_list列表
        if (wait_option)
        {

            /* Prepare for suspension of this thread.  */

            /* Pickup thread pointer.  */
            thread_ptr =  _tx_thread_current_ptr;

            /* Setup cleanup routine pointer.  */
            thread_ptr -> tx_suspend_cleanup =  _tx_block_pool_cleanup;

            /* Setup cleanup information, i.e. this pool control
               block.  */
            #def 存储挂起时内存池指针
            thread_ptr -> tx_suspend_control_block = (VOID_PTR) pool_ptr;

            /* Save the return block pointer address as well.  */
            #def 保存应用程序传入的用于存储分配的内存地址的 指针,等到有其他线程释放内存时,恢复本线程重新申请内存时使用
            thread_ptr -> tx_additional_suspend_info = (VOID_PTR) block_ptr;

            /* Setup suspension list.  */
            #def 插入挂起list
            if (pool_ptr -> tx_block_pool_suspension_list)
            {

                /* This list is not NULL, add current thread to the end. */
                thread_ptr -> tx_suspended_next =
                    pool_ptr -> tx_block_pool_suspension_list;
                thread_ptr -> tx_suspended_previous =
                    (pool_ptr -> tx_block_pool_suspension_list) -> tx_suspended_previous;
                ((pool_ptr -> tx_block_pool_suspension_list) -> tx_suspended_previous) -> tx_suspended_next =
                    thread_ptr;
                (pool_ptr -> tx_block_pool_suspension_list) -> tx_suspended_previous =   thread_ptr;
            }
            else
            {

                /* No other threads are suspended.  Setup the head pointer and
                   just setup this threads pointers to itself.  */
                pool_ptr -> tx_block_pool_suspension_list =  thread_ptr;
                thread_ptr -> tx_suspended_next =            thread_ptr;
                thread_ptr -> tx_suspended_previous =        thread_ptr;
            }

            /* Increment the suspended thread count.  */
            pool_ptr -> tx_block_pool_suspended_count++;

            /* Set the state to suspended.  */
            thread_ptr -> tx_state =       TX_BLOCK_MEMORY;

            /* Set the suspending flag.  */
            thread_ptr -> tx_suspending =  TX_TRUE;

            /* Temporarily disable preemption.  */
            _tx_thread_preempt_disable++;

            /* Save the timeout value.  */
            thread_ptr -> tx_thread_timer.tx_remaining_ticks =  wait_option;

            /* Restore interrupts.  */
            TX_RESTORE

            /* See if we need to start a timer.  */
            #def 开启定时器,定时器超时清除相关结构,恢复线程
            if (wait_option != TX_WAIT_FOREVER)
            {

                /* A timeout is required.  */

                /* Activate the thread timer for the timeout.  */
                _tx_timer_activate(&(thread_ptr -> tx_thread_timer));
            }

            /* Call actual thread suspension routine.  */
            #def 挂起线程
            _tx_thread_suspend(thread_ptr);

            /* Return the completion status.  */
            #def 线程恢复后,函数从这里返回,tx_suspend_status值在tx_block_pool_delete,tx_block_release或_tx_block_pool_cleanup函数设置,这些函数设置这个值,然后恢复了本线程
            return (thread_ptr -> tx_suspend_status);
        }
        else

            /* Immediate return, return error completion.  */
            status =  TX_NO_MEMORY;
    }

    /* Restore interrupts.  */
    TX_RESTORE

    /* Return completion status.  */
    return (status);
}
发布了48 篇原创文章 · 获赞 2 · 访问量 4060

猜你喜欢

转载自blog.csdn.net/qq_45683435/article/details/104281079