tx_block_pool_id | 内存块池id |
tx_block_pool_name | 内存块池名字 |
tx_block_pool_available | 内存块池总的空闲块个数 |
tx_block_pool_total | 内存块池总的块个数 |
tx_block_pool_available_list | 内存块池空闲链表头部 |
tx_block_pool_start | 内存块池内存的起始地址 |
tx_block_pool_size | 内存块池整个内存大小 |
tx_block_pool_block_size | 内存块池固定块大小 |
tx_block_pool_suspension_list | 内存块池挂起线程链表 |
tx_block_pool_suspended_count | 内存块池挂起链表中线程个数 |
tx_block_pool_created_next | 指向下一个内存块池 |
tx_block_pool_created_previous | 指向前一个内存块池 |
tx_block_pool_used_size | |
tx_block_pool_min_available |
块内存分配和释放只需操作链表头部
- 内存块池链表
- 内存块池初始化
固定块个数=内存大小÷固定块大小(tx_block_pool_total=tx_block_pool_size÷tx_block_pool_block_size)
固定块通过单向链表连接起来,链表指针存储在每个固定块头部前4字节,也就是每个固定块头部指向相邻下一块的内存首地址,最后一块头部前4字节存储为NULL。
tx_block_pool_available_list指向第一个空闲内存块。
内存分配时,从tx_block_pool_available_list找到第一块空闲内存块,直接返回,并将tx_block_pool_available_list指向下一个空闲内存块。
分配的内存块头部4个字节不再指向下一个内存块首地址,而是存储了内存池TX_BLOCK_POOL控制块地址,用于后续内存释放时使用。
如果没有空闲内存块,线程可以挂起等待,插入tx_block_pool_suspension_list链表,插入规则为先进先出FIFO,而不是线程优先级高低顺序。
-
内存池分配
内存分配时,从tx_block_pool_available_list找到第一块空闲内存块,直接返回,再将tx_block_pool_available_list指向下一个空闲内存块。
分配的内存块头部4个字节不再指向下一个内存块首地址,而是存储了内存池TX_BLOCK_POOL控制块地址,用于后续内存释放时使用。
如果没有空闲内存块,线程可以挂起等待,插入suspension_list,插入规则为先进先出FIFO,而不是线程优先级高低顺序。
下图第一次分配,第一块被分配给应用程序使用,tx_block_pool_available_list指向第二块,也就是当前第一个空闲内存块。第一块头部4字节指向了TX_BLOCK_POOL控制块地址。操作简单,只改变了tx_block_pool_available_list指针和第一块头部4字节。
下图第二次分配,第二块块被分配给应用程序使用,tx_block_pool_available_list指向第三块,也就是当前第一个空闲内存块。第二块头部4字节指向了TX_BLOCK_POOL管理结构地址。操作简单,只改变了tx_block_pool_available_list指针和第二块头部4字节。
- 块内存池释放
内存释放时,找到tx_block_pool_available_list指向空闲块,将要释放的内存块前4字节指向tx_block_pool_available_list指向的空闲块,然后tx_block_pool_available_list指向释放的内存块。
下图释放第一块内存。
释放内存时,如果suspension list中有线程挂起,那么尝试为挂起线程重新申请内存,并恢复线程。通常恢复线程顺序为FIFO,而不是线程优先级高低。但应用程序可以在释放内存前,调用tx_block_pool_prioritize把挂起链表中最高优先级线程移动到最前面,保证最高优先级线程先恢复。