Linux 0.11版 lib/Malloc.c是一个内核内存动态分配模块,该模块服务于内核内存动态分配,注意是服务于内核,而不是一般用户进程。该模块代码量很少,对链表的使用很到位,值得一读。
lib/Malloc.c 模块中涉及到的数据结构和全局变量如下:
struct bucket_desc { /* 16 bytes */
void *page; /*物理页的基址,4KB对齐 */
struct bucket_desc *next; /*指向下一个bucket_desc结构*/
void *freeptr; /*page页面中下一个可供分配出去的内存块地址*/
unsigned short refcnt; /*page页面中已经分配出去的内存块的个数*/
unsigned short bucket_size; /*page页面中每一个内存块的大小,共有4KB/bucket_size个内存块*/
};
struct _bucket_dir { /* 8 bytes */
int size; /*bucket_desc链表节点指向的页面可分配的内存块的大小*/
struct bucket_desc *chain; /*指向bucket_desc类型链表*/
};
struct _bucket_dir bucket_dir[] = {
{ 16, (struct bucket_desc *) 0},
{ 32, (struct bucket_desc *) 0},
{ 64, (struct bucket_desc *) 0},
{ 128, (struct bucket_desc *) 0},
{ 256, (struct bucket_desc *) 0},
{ 512, (struct bucket_desc *) 0},
{ 1024, (struct bucket_desc *) 0},
{ 2048, (struct bucket_desc *) 0},
{ 4096, (struct bucket_desc *) 0},
{ 0, (struct bucket_desc *) 0}};
/* 通常一个物理页面4KB,按照不同的块大小,页面可以被分成(4KB/块大小)个内存块,这个全局变量维护着16B~4096B不同大小的内存块链表。因此内核内存动态分配最小是16B,最大是4096B。 */
struct bucket_desc *free_bucket_desc = (struct bucket_desc *) 0; /*指向下一个可用的 bucket_desc 节点*/
lib/Malloc.c 模块中主要有三个主要函数
static inline void init_bucket_desc();
void *malloc(unsigned int len);
void free_s(void *obj, int size);
static inline void init_bucket_desc();
这个函数首先调用get_free_page获得一个4KB大小的物理页面,即为4KB大小的一块内存,将这块内存初始化为一个bucket_desc结构链表,将这个链表插入到free_bucket_desc的前端。
void *malloc(unsigned int len);
这个函数首先根据len,从bucket_dir数组中找到大小适合的内存桶,即bucket_desc结构指针,bucket_desc的page包含一系列大小为len的内存块
lib/Malloc.c 模块中涉及到的数据结构和全局变量如下:
struct bucket_desc { /* 16 bytes */
void *page; /*物理页的基址,4KB对齐 */
struct bucket_desc *next; /*指向下一个bucket_desc结构*/
void *freeptr; /*page页面中下一个可供分配出去的内存块地址*/
unsigned short refcnt; /*page页面中已经分配出去的内存块的个数*/
unsigned short bucket_size; /*page页面中每一个内存块的大小,共有4KB/bucket_size个内存块*/
};
struct _bucket_dir { /* 8 bytes */
int size; /*bucket_desc链表节点指向的页面可分配的内存块的大小*/
struct bucket_desc *chain; /*指向bucket_desc类型链表*/
};
struct _bucket_dir bucket_dir[] = {
{ 16, (struct bucket_desc *) 0},
{ 32, (struct bucket_desc *) 0},
{ 64, (struct bucket_desc *) 0},
{ 128, (struct bucket_desc *) 0},
{ 256, (struct bucket_desc *) 0},
{ 512, (struct bucket_desc *) 0},
{ 1024, (struct bucket_desc *) 0},
{ 2048, (struct bucket_desc *) 0},
{ 4096, (struct bucket_desc *) 0},
{ 0, (struct bucket_desc *) 0}};
/* 通常一个物理页面4KB,按照不同的块大小,页面可以被分成(4KB/块大小)个内存块,这个全局变量维护着16B~4096B不同大小的内存块链表。因此内核内存动态分配最小是16B,最大是4096B。 */
struct bucket_desc *free_bucket_desc = (struct bucket_desc *) 0; /*指向下一个可用的 bucket_desc 节点*/
lib/Malloc.c 模块中主要有三个主要函数
static inline void init_bucket_desc();
void *malloc(unsigned int len);
void free_s(void *obj, int size);
static inline void init_bucket_desc();
这个函数首先调用get_free_page获得一个4KB大小的物理页面,即为4KB大小的一块内存,将这块内存初始化为一个bucket_desc结构链表,将这个链表插入到free_bucket_desc的前端。
void *malloc(unsigned int len);
这个函数首先根据len,从bucket_dir数组中找到大小适合的内存桶,即bucket_desc结构指针,bucket_desc的page包含一系列大小为len的内存块