diff --git a/22451111/exam1/assets/image1.png b/22451111/exam1/assets/image1.png new file mode 100644 index 0000000000000000000000000000000000000000..356bae3a8dadf9af9a2104ed2c9a20e18a34508c Binary files /dev/null and b/22451111/exam1/assets/image1.png differ diff --git a/22451111/exam1/assets/image2.png b/22451111/exam1/assets/image2.png new file mode 100644 index 0000000000000000000000000000000000000000..18843a1bda1f884c39eab75e4d57cda20ac7b8f5 Binary files /dev/null and b/22451111/exam1/assets/image2.png differ diff --git a/22451111/exam1/foo.c b/22451111/exam1/foo.c new file mode 100644 index 0000000000000000000000000000000000000000..c3bda6f59dccc80861aa10e6db583050eb0ed88e --- /dev/null +++ b/22451111/exam1/foo.c @@ -0,0 +1,98 @@ +static void bbuddy_pfree(struct uk_alloc *a, void *obj, unsigned long num_pages) +{ + struct uk_bbpalloc *b; + chunk_head_t *freed_ch, *to_merge_ch; + chunk_tail_t *freed_ct; + unsigned long mask; + + UK_ASSERT(a != NULL); + + uk_alloc_stats_count_pfree(a, obj, num_pages); + b = (struct uk_bbpalloc *)&a->priv; + + freelist_sanitycheck(b->free_head); + + size_t order = (size_t)num_pages_to_order(num_pages); + + /* if the object is not page aligned it was clearly not from us */ + UK_ASSERT((((uintptr_t)obj) & (__PAGE_SIZE - 1)) == 0); + + /* First free the chunk */ + map_free(b, (uintptr_t)obj, 1UL << order); + +#if 0 + /* Create free chunk */ + freed_ch = (chunk_head_t *)obj; + freed_ct = (chunk_tail_t *)((char *)obj + + (1UL << (order + __PAGE_SHIFT))) - 1; + + /* Now, possibly we can conseal chunks together */ + while (order < FREELIST_SIZE) { + mask = 1UL << (order + __PAGE_SHIFT); + if ((unsigned long)freed_ch & mask) { + to_merge_ch = (chunk_head_t *)((char *)freed_ch - mask); + if (allocated_in_map(b, (uintptr_t)to_merge_ch) + || to_merge_ch->level != order) + break; + + /* Merge with predecessor */ + freed_ch = to_merge_ch; + } else { + to_merge_ch = (chunk_head_t *)((char *)freed_ch + mask); + if (allocated_in_map(b, (uintptr_t)to_merge_ch) + || to_merge_ch->level != order) + break; + + /* Merge with successor */ + freed_ct = + (chunk_tail_t *)((char *)to_merge_ch + mask) - 1; + } + + /* We are commited to merging, unlink the chunk */ + *(to_merge_ch->pprev) = to_merge_ch->next; + to_merge_ch->next->pprev = to_merge_ch->pprev; + + order++; + } + + /* Link the new chunk */ + freed_ch->level = order; + freed_ch->next = b->free_head[order]; + freed_ch->pprev = &b->free_head[order]; + freed_ct->level = order; + + freed_ch->next->pprev = &freed_ch->next; + b->free_head[order] = freed_ch; +#else + uk_pr_crit("--------before free--------\n"); + uk_bbpalloc_dump_freelist(); + + chunk_head_t **head = &b->free_head[0]; + + while(num_pages) { + freed_ch = (chunk_head_t *)obj; + freed_ct = (chunk_tail_t *)(obj + + (1UL << __PAGE_SHIFT)) - 1; + + freed_ch->level = 0; + freed_ct->level = 0; + + while (*head) { + if ((uintptr_t)freed_ch > (uintptr_t)(*head)) //寻找插入位置 + break; + head = &(*head)->next; + } + + freed_ch->next = *head; //待插入节点的next指向当前节点 + freed_ch->pprev = &freed_ch; //待插入节点的pprev指向自身 + (*head)->pprev = &freed_ch->next; //当前节点的pprev指向待插入节点 + *head = freed_ch; //更改头指针 + + num_pages--; + obj = freed_ct + 1; //强制转换带来地址不准问题 + } +#endif + freelist_sanitycheck(b->free_head); + + uk_bbpalloc_dump_freelist(); +} \ No newline at end of file diff --git a/22451111/exam1/report.md b/22451111/exam1/report.md new file mode 100644 index 0000000000000000000000000000000000000000..4db073d48a6116941f7b9da8e61fbdf4b4b27c0c --- /dev/null +++ b/22451111/exam1/report.md @@ -0,0 +1,54 @@ +# 考核1 +> 学号:22451111 +> +> 姓名:刘赛 + +## 代码问题一:不需要order变量 + +原代码 +``` + int nr_page_left = 1UL << order; + while(nr_page_left) { + ··· + } +``` + +该代码逻辑采用逐一释放单个成连续的内存块,并不存在在伙伴算法中存在的内存块阶数(order)的概念,直接将while循环内条件更改为num_pages所释空间的页面数量即可。 + +## 代码问题二:释放时应该按序重新加入空闲列表 + +先进行三次次malloc,然后反序进行free +``` + int *a = malloc(1); + int *b = malloc(2); + int *c = malloc(3); + printf("Hello world!\n"); + free(b); + free(c); + free(a); +``` + +此时结果如图1所示 +![image1](assets/image1.png) +第二次释放后,内存块1和内存块2乱序了 + +应当更改为按序插入,对每个内存块定义到该插入的位置后进行插入 +``` + while (*head) { + if ((uintptr_t)freed_ch > (uintptr_t)(*head)) //寻找插入位置 + break; + head = &(*head)->next; + } + + freed_ch->next = *head; //待插入节点的next指向当前节点 + freed_ch->pprev = &freed_ch; //待插入节点的pprev指向自身 + (*head)->pprev = &freed_ch->next; //当前节点的pprev指向待插入节点 + *head = freed_ch; //更改头指针 + + num_pages--; + obj = freed_ct + 1; //强制转换带来地址不准问题 +``` + +此时结果如图2所示 +![image2](assets/image2.png) +此时内存块均有序 \ No newline at end of file