Lwbtmem分配是通过一个大的字节数组memp_memory来派发的。在这个数组中规定了哪一段是属于哪个类型的,这样做的方法不是很科学,是通过规定各个类型结构的最大能用的个数来取的。Hci_pcb的个数就一个。memp_num数组中的元素就是每个类型的最大可用个数。而memp_sizes数组中的元素是每个类型的大小。memp_tab数组中的元素则是每个类型分配内存的第一个可用空间指针。
 
       Size(memp_memory[type]) =  memp_sizes[type] * memp_num[type]
lwbt的内存分配详解_休闲
 
首先来看下memp这个结构体的定义:
struct memp
{
  struct memp *next;
};
它只有一个指向下一个结构的指针。同时注意到memp_tab数组中的元素都是这个结构的指针。
 
在这个文条件中主要有3个函数:lwbt_memp_initlwbt_memp_malloclwbt_memp_free。上面说过对个结构的内存分配都是从一个指定的数组中来分配的。
 
下面看下lwbt_memp_init的实现,从整体上来说,这个函数是把各个结构在memp_memory中的首地址赋值给memp_tab中的各对应元素。对于限制数大于1的情况,还要将该类型的各个实例的地址串接起来。说起来比较难理解一些。下面用图解的方式给出:
                      Memp_memory
lwbt的内存分配详解_职场_02
上图中显现的是以hci_link的初始化作为实例,其中预分配的数目为4个。
 
       我们从图中看到了有链表的实现,但是在lwbt_memp_init中没有明显的字样提及到链表的。这个功能,这里暂且称为隐式链表。它的实现,是通过在分配多个连续块内存的时候,在每一块前加分一个指针大小的内存,并通过这个指针指向下一块内存的起始地址。
p_temp=p1; *p1=(int)p_temp+size(struct)+1;//这里架设了struct是以int对齐。
 
这个例子是一个普遍的更隐晦的实现(相对lwbt_memp_init),在lwbt_memp_init中的实现要明显一些,主要是通过了struct memp这个结构来替代了上面的p1,这样就更清楚了一些。
 
接着,在讲下mallocfree函数。通过上面对初始化函数的理解,这里,我们不难猜测这两个函数的实现:
malloc:通过类型从memp_tab数组中获取struct memp型指针,并将其next指针赋值给memp_tab[该类型]。相当于从隐式链表中删除节点。
free:通过类型将memp_tab[该类型]赋值给要回收的地址指针,即struct memp类型指针,的next指针,并将要回收的地址指针赋值给memp_tab[该类型]。相当向隐式链表中增加节点。
 
       不难看出memp_tab[该类型]一直都是指向该类型第一个可用的内存地址。
 
值得注意的是
malloc中:mem = MEM_ALIGN((u8_t *)memp + sizeof(struct memp));其中mem是函数返回的地址,这句话就是要将开头的struct memp(隐式链表节点信息)去掉,从真正的结构类型起始地址开始。
free中:memp = (struct memp *)((u8_t *)mem - sizeof(struct memp));其中mem是要回收的地址,这句话的意思与上面的相反,它是要加入隐式链表节点信息,以确保,memp_tab中隐式链表的正常运行。
 
Malloc:【第一个是已分配的】
lwbt的内存分配详解_休闲_03
 
Free:memp_tab前面的两个都以分配,现在首要free第一个】
lwbt的内存分配详解_职场_04