Thread 字节内存管理 内存搜索_tx_byte_pool_search

26 篇文章 3 订阅

_tx_byte_pool_search

_tx_byte_pool_search用于搜索可用内存,在_tx_byte_allocate和 _tx_byte_release函数中调用。
使用first-fit算法,从上次操作的空闲内存开始搜索,搜索过程中找到第一块合适大小内存,就返回成功。
内存块链表是一个循环链表,最后一块为固定块,不用内存分配,只为了适配搜索算法。
如果把一块大内存分成了两块,一块返回给应用程序,另一块需要插入链表。
搜索过程中,发现两块连续内存都是空闲内存,那么把这两块内存合并为一块,插入链表。

VOID    *_tx_byte_pool_search(TX_BYTE_POOL *pool_ptr, ULONG memory_size)
{

    TX_INTERRUPT_SAVE_AREA

    REG_1 CHAR_PTR  current_ptr;                /* Current block pointer      */
    REG_2 CHAR_PTR  next_ptr;                   /* Next block pointer         */
    REG_3 ULONG     available_bytes;            /* Calculate bytes available  */
    REG_4 ULONG     examine_blocks;             /* Blocks to be examined      */


    /* Disable interrupts.  */
    #def 禁止中断
    TX_DISABLE

    /* First, determine if there are enough bytes in the pool.  */
    #def 如果可用内存不够,直接返回失败。tx_byte_pool_available为内存池整个可用空间。
    if (memory_size >= pool_ptr -> tx_byte_pool_available)
    {

        /* Restore interrupts.  */
        TX_RESTORE

        /* Not enough memory, return a NULL pointer.  */
        return (TX_NULL);
    }

    /* Walk through the memory pool in search for a large enough block.  */
    #def 临时保存搜索内存起始位置, 搜索最大块数,tx_byte_pool_fragments + 1这里加1是为了方便计算
    current_ptr =      pool_ptr -> tx_byte_pool_search;
    examine_blocks =   pool_ptr -> tx_byte_pool_fragments + 1;
    available_bytes =  0;

    do
    {
        /* Check to see if this block is free.  */
        #def 检查控制字段第4到8个字节为TX_BYTE_BLOCK_FREE,表示为空闲内存
        if (*((ULONG_PTR)(current_ptr + sizeof(CHAR_PTR))) == TX_BYTE_BLOCK_FREE)
        {

            /* Block is free, see if it is large enough.  */

            /* Pickup the next block's pointer.  */
            #def 控制字段前4个字节存储了下一相邻块的首地址
            next_ptr =  *((CHAR_PTR *) current_ptr);

            /* Calculate the number of byte available in this block.  */
            #def 计算current_ptr 块内存的大小
            available_bytes =  next_ptr - current_ptr - sizeof(CHAR_PTR) - sizeof(ULONG);

            /* If this is large enough, we are done because our first-fit algorithm
               has been satisfied!  */
            #def 本块内存空间足够,那么可以退出搜索了
            if (available_bytes >= memory_size)
            {
                /* Get out of the search loop!  */
                break;
            }
            else
            {
				#def 本块内存大小不够,需要继续搜索下一块
                /* Clear the available bytes variable.  */
                available_bytes =  0;

                /* Not enough memory, check to see if the neighbor is
                   free and can be merged.  */
                #def 检查下一块释放为空闲内存
                if (*((ULONG_PTR)(next_ptr + sizeof(CHAR_PTR))) == TX_BYTE_BLOCK_FREE)
                {
					#def 下一块也为空闲内存,那么可以把这两个内存合并为一块大的内存
                    /* Yes, neighbor block can be merged!  This is quickly accomplished
                       by updating the current block with the next blocks pointer.  */
                    #def 当前块控制字段前4字节存储 下下块内存的首地址。*((CHAR_PTR *) next_ptr)中存储了下下块内存首地址
                    #def 这样就想相当于,下一块内存从链表中去掉了。
                    *((CHAR_PTR *) current_ptr) =  *((CHAR_PTR *) next_ptr);

                    /* Reduce the fragment total.  We don't need to increase the bytes
                       available because all free headers are also included in the available
                       count.  */
                    #def 减少一块
                    pool_ptr -> tx_byte_pool_fragments--;

                    /* See if the search pointer is affected.  */
                    #def 需要把搜索指针重新设置为刚刚合并的大块首地址
                    if (pool_ptr -> tx_byte_pool_search ==  next_ptr)
                        pool_ptr -> tx_byte_pool_search =  current_ptr;
                }
                else
                {
					#def 下一块不是空闲块,那么查找下下块
                    /* Neighbor is not free so we can skip over it!  */
                    current_ptr =  *((CHAR_PTR *) next_ptr);

                    /* Decrement the examined block count to account for this one.  */
                    #def 检查块数减1
                    if (examine_blocks)
                        examine_blocks--;
                }
            }
        }
        else
        {

            /* Block is not free, move to next block.  */
            current_ptr =      *((CHAR_PTR *) current_ptr);
        }

        /* Another block has been searched... decrement counter.  */
        if (examine_blocks)
            examine_blocks--;

        /* Restore interrupts temporarily.  */
        #def 开中断,这里主要是给其他高优先级任务调度机会。因为在这里进行内存搜索耗时可能时间较长。 提升系统实时性,响应能力。
        TX_RESTORE

        /* Disable interrupts.  */
        TX_DISABLE

        /* Determine if anything has changed in terms of pool ownership.  */
        #def 如果线程被打断过,且高优先级线程操作过这个内存池
        if (pool_ptr -> tx_byte_pool_owner != _tx_thread_current_ptr)
        {

            /* Pool changed ownership in the brief period interrupts were
               enabled.  Reset the search.  */
            #def 从第一个空闲块开始搜索
            current_ptr =      pool_ptr -> tx_byte_pool_search;
            examine_blocks =   pool_ptr -> tx_byte_pool_fragments + 1;

            /* Setup our ownership again.  */
            #def 重新记录内存池拥有者为当前线程
            pool_ptr -> tx_byte_pool_owner =  _tx_thread_current_ptr;
        }
    }
    #def examine_blocks不为0,继续搜索
    while (examine_blocks);

    /* Determine if a block was found.  If so, determine if it needs to be
       split.  */
    #def available_bytes不为0,说明前面搜索成功
    if (available_bytes)
    {
		#def 搜索成功,如果这块内存减去申请大小 超过了TX_BYTE_BLOCK_MIN字节,只需要返回申请大小的内存,
		#def 剩下内存自己成为一块,插入链表。
		#def 分裂
        /* Determine if we need to split this block.  */
        if ((available_bytes - memory_size) >= ((ULONG) TX_BYTE_BLOCK_MIN))
        {

            /* Split the block.  */
            #def 分裂后的首地址计算,首地址+申请大小+控制字段大小,就是分裂后 后一块内存首地址
            next_ptr =  current_ptr + memory_size + sizeof(CHAR_PTR) + sizeof(ULONG);

            /* Setup the new free block.  */
            #def 插入链表,标记为空闲块,并指向下一块内存
            *((CHAR_PTR *) next_ptr) =  *((CHAR_PTR *) current_ptr);
            *((ULONG_PTR)(next_ptr + sizeof(CHAR_PTR))) =  TX_BYTE_BLOCK_FREE;

            /* Increase the total fragment counter.  */
            #def 块数加1
            pool_ptr -> tx_byte_pool_fragments++;

            /* Update the current pointer to point at the newly created block.  */
            #def 当前块也要执行新分裂出来的下一块
            *((CHAR_PTR *) current_ptr) = next_ptr;

            /* Set available equal to memory size for subsequent calculation.  */
            available_bytes =  memory_size;
        }

        /* In any case, mark the current block as allocated.  */
        #def 当前分配块,标记为已占用,不在存储TX_BYTE_BLOCK_FREE,而是存储内存池管理结构指针
        *((TX_BYTE_POOL **)(current_ptr + sizeof(CHAR_PTR))) =  pool_ptr;

        /* Reduce the number of available bytes in the pool.  */
        #def 重新计算总的可用内存大小
        pool_ptr -> tx_byte_pool_available =  pool_ptr -> tx_byte_pool_available -
                                              available_bytes - sizeof(CHAR_PTR) - sizeof(ULONG);

        /* Update the search pointer to the next block.  */
        #def 搜索起始地址给为下一块,这里不一定是第一块空闲块。前面可能有空闲块被太小,被跨过了
        pool_ptr -> tx_byte_pool_search =  *((CHAR_PTR *) current_ptr);

        /* Restore interrupts.  */
        TX_RESTORE

        /* Adjust the pointer for the application.  */
        #def 返回给应用程序的地址,跨过控制字段
        current_ptr =  current_ptr + sizeof(CHAR_PTR) + sizeof(ULONG);
    }
    else
    {

        /* Restore interrupts.  */
        TX_RESTORE

        /* Set current pointer to NULL to indicate nothing was found.  */
        current_ptr =  TX_NULL;
    }

    /* Return the search pointer.  */
    return (current_ptr);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值