Pintos源码学习进度(5)
1. page allocate内存分配方式
struct pool
{
struct lock lock; /* Mutual exclusion. */
struct bitmap *used_map; /* Bitmap of free pages. */
uint8_t *base; /* Base of pool. */
};
palloc_init
①allocate的初始存放位置是从1M的位置开始的,结束位置为ram的大小
②获得user page与kernel page的大小,默认为一半,一半
③调用init_pool初始化user pool 与 kernel pool
init_pool
①根据page_count求得存放bitmap的page数量
②为pool中的bitmap创建空间,并全部置为false
③pool的基地址指向除去bitmap的首位地址
palloc_get_multiple
①根据传入的flag来判断是内存空间还是用户空间
②对pool中的bitmap进行扫描,找到连续的没有使用过的page
③对没有使用过的page空间置为0
④返回page所对应的首个地址
palloc_free_multiple
①通过page的地址,与pool的base可以找到page的index
②将pool中的bitmap中相应的bit置为false
2. block allocate内存分配方式
struct desc
{
size_t block_size; 一个block的大小,用byte表示
size_t blocks_per_arena; 一个arena中的block大小,arena类似于一个pages,具体描述如下
struct list free_list; /* List of free blocks. */
struct lock lock; /* Lock. */
};
struct arena
{
unsigned magic; 用于放置内存泄漏
struct desc *desc; /* Owning descriptor, null for big block. */
size_t free_cnt; /* Free blocks; pages in big block. */
};
struct block
{
struct list_elem free_elem; /* Free list element. */
};
malloc_init
①对于每种2的幂次为大小的block,对discriptor进行初始化
②blocks_per_arena的大小为 PAGESIZE - sizeof(arena) / block_size
③对free_list进行初始化
malloc
①通过size计算出合适的discriptor.
②如果size的大小无法用所有的discriptor来描述,就直接使用palloc_get_multiple为其分配地址
③并且设置arena的desc为NULL,free_cnt为page_cnt
④返回page地址
⑤如果size的大小满足其中一个discriptor的描述,
⑥判断discriptor中的free_list是否为空,如果free_list为空,将一个page通过手段变为arena,划分为block并加入free_list中。
⑦从discriptor中获取其中一个block,再通过block获取对应的arena,并将free_cnt--,返回block的地址.