🆕 回收堆内存给操作系统

This commit is contained in:
fslongjin
2022-05-11 20:42:53 +08:00
parent edb21695ae
commit 1cc3db5e88
6 changed files with 311 additions and 88 deletions

View File

@ -8,6 +8,18 @@
ul Total_Memory = 0;
ul total_2M_pages = 0;
static ul root_page_table_phys_addr = 0; // 内核层根页表的物理地址
/**
* @brief 从页表中获取pdt页表项的内容
*
* @param proc_page_table_addr 页表的地址
* @param is_phys 页表地址是否为物理地址
* @param virt_addr_start 要清除的虚拟地址的起始地址
* @param length 要清除的区域的长度
* @param clear 是否清除标志位
*/
uint64_t mm_get_PDE(ul proc_page_table_addr, bool is_phys, ul virt_addr, bool clear);
void mm_init()
{
kinfo("Initializing memory management unit...");
@ -444,36 +456,6 @@ void page_table_init()
for (int j = 0; j < z->count_pages; ++j)
{
mm_map_phys_addr((ul)phys_2_virt(p->addr_phys), p->addr_phys, PAGE_2M_SIZE, PAGE_KERNEL_PAGE);
/*
// 计算出PML4页表中的页表项的地址
tmp_addr = (ul *)((ul)pml4_addr + ((((ul)phys_2_virt(p->addr_phys)) >> PAGE_GDT_SHIFT) & 0x1ff) * 8);
// 说明该页还没有分配pdpt页表使用kmalloc分配一个
if (*tmp_addr = 0)
{
ul *virt_addr = kmalloc(PAGE_4K_SIZE, 0);
set_pml4t(tmp_addr, mk_pml4t(virt_2_phys(virt_addr), PAGE_KERNEL_PGT));
}
// 计算出pdpt页表的页表项的地址
tmp_addr = (ul *)((ul)(phys_2_virt(*tmp_addr & (~0xfffUL))) + ((((ul)phys_2_virt(p->addr_phys)) >> PAGE_1G_SHIFT) & 0x1ff) * 8);
// 说明该页还没有分配pd页表使用kmalloc分配一个
if (*tmp_addr = 0)
{
ul *virt_addr = kmalloc(PAGE_4K_SIZE, 0);
set_pdpt(tmp_addr, mk_pdpt(virt_2_phys(virt_addr), PAGE_KERNEL_DIR));
}
// 计算出pd页表的页表项的地址
tmp_addr = (ul *)((ul)(phys_2_virt(*tmp_addr & (~0xfffUL))) + ((((ul)phys_2_virt(p->addr_phys)) >> PAGE_2M_SHIFT) & 0x1ff) * 8);
// 填入pd页表的页表项映射2MB物理页
set_pdt(tmp_addr, mk_pdt(virt_2_phys(p->addr_phys), PAGE_KERNEL_PAGE));
*/
// 测试
if (j % 50 == 0)
kdebug("pd_addr=%#018lx, *pd_addr=%#018lx", tmp_addr, *tmp_addr);
}
}
@ -631,19 +613,14 @@ void mm_map_proc_page_table(ul proc_page_table_addr, bool is_phys, ul virt_addr_
else
tmp = (ul *)((ul)proc_page_table_addr & (~0xfffUL)) + ((virt_addr_start >> PAGE_GDT_SHIFT) & 0x1ff);
// kdebug("tmp = %#018lx", tmp);
if (*tmp == 0)
{
ul *virt_addr = kmalloc(PAGE_4K_SIZE, 0);
memset(virt_addr, 0, PAGE_4K_SIZE);
set_pml4t(tmp, mk_pml4t(virt_2_phys(virt_addr), (user ? PAGE_USER_PGT : PAGE_KERNEL_PGT)));
}
// kdebug("*tmp = %#018lx", *tmp);
if (is_phys)
tmp = phys_2_virt((ul *)(*tmp & (~0xfffUL)) + ((virt_addr_start >> PAGE_1G_SHIFT) & 0x1ff));
else
tmp = (ul *)(*tmp & (~0xfffUL)) + ((virt_addr_start >> PAGE_1G_SHIFT) & 0x1ff);
if (*tmp == 0)
{
@ -657,10 +634,8 @@ void mm_map_proc_page_table(ul proc_page_table_addr, bool is_phys, ul virt_addr_
for (ul i = 0; i < (length); i += PAGE_2M_SIZE)
{
// 计算当前2M物理页对应的pdt的页表项的物理地址
if (is_phys)
tmp1 = phys_2_virt(((ul *)(*tmp & (~0xfffUL)) + (((ul)(virt_addr_start + i) >> PAGE_2M_SHIFT) & 0x1ff)));
else
tmp1 = ((ul *)(*tmp & (~0xfffUL)) + (((ul)(virt_addr_start + i) >> PAGE_2M_SHIFT) & 0x1ff));
// 页面写穿,禁止缓存
set_pdt(tmp1, mk_pdt((ul)phys_addr_start + i, flags | (user ? PAGE_USER_PAGE : PAGE_KERNEL_PAGE)));
@ -669,6 +644,148 @@ void mm_map_proc_page_table(ul proc_page_table_addr, bool is_phys, ul virt_addr_
flush_tlb();
}
/**
* @brief 从页表中获取pdt页表项的内容
*
* @param proc_page_table_addr 页表的地址
* @param is_phys 页表地址是否为物理地址
* @param virt_addr_start 要清除的虚拟地址的起始地址
* @param length 要清除的区域的长度
* @param clear 是否清除标志位
*/
uint64_t mm_get_PDE(ul proc_page_table_addr, bool is_phys, ul virt_addr, bool clear)
{
ul *tmp;
if (is_phys)
tmp = phys_2_virt((ul *)((ul)proc_page_table_addr & (~0xfffUL)) + ((virt_addr >> PAGE_GDT_SHIFT) & 0x1ff));
else
tmp = (ul *)((ul)proc_page_table_addr & (~0xfffUL)) + ((virt_addr >> PAGE_GDT_SHIFT) & 0x1ff);
// pml4页表项为0
if (*tmp == 0)
return 0;
tmp = phys_2_virt((ul *)(*tmp & (~0xfffUL)) + ((virt_addr >> PAGE_1G_SHIFT) & 0x1ff));
// pdpt页表项为0
if (*tmp == 0)
return 0;
// 读取pdt页表项
tmp = phys_2_virt(((ul *)(*tmp & (~0xfffUL)) + (((ul)(virt_addr) >> PAGE_2M_SHIFT) & 0x1ff)));
if (clear) // 清除页表项的标志位
return *tmp & (~0x1fff);
else
return *tmp;
}
/**
* @brief 从页表中清除虚拟地址的映射
*
* @param proc_page_table_addr 页表的地址
* @param is_phys 页表地址是否为物理地址
* @param virt_addr_start 要清除的虚拟地址的起始地址
* @param length 要清除的区域的长度
*/
void mm_unmap_proc_table(ul proc_page_table_addr, bool is_phys, ul virt_addr_start, ul length)
{
ul *tmp;
if (is_phys)
tmp = phys_2_virt((ul *)((ul)proc_page_table_addr & (~0xfffUL)) + ((virt_addr_start >> PAGE_GDT_SHIFT) & 0x1ff));
else
tmp = (ul *)((ul)proc_page_table_addr & (~0xfffUL)) + ((virt_addr_start >> PAGE_GDT_SHIFT) & 0x1ff);
// pml4页表项为0
if (*tmp == 0)
return;
tmp = phys_2_virt((ul *)(*tmp & (~0xfffUL)) + ((virt_addr_start >> PAGE_1G_SHIFT) & 0x1ff));
// pdpt页表项为0
if (*tmp == 0)
return;
ul *tmp1;
for (ul i = 0; i < (length); i += PAGE_2M_SIZE)
{
// 计算当前2M物理页对应的pdt的页表项的物理地址
tmp1 = phys_2_virt(((ul *)(*tmp & (~0xfffUL)) + (((ul)(virt_addr_start + i) >> PAGE_2M_SHIFT) & 0x1ff)));
// 清除映射
*tmp1 = 0;
}
flush_tlb();
}
/**
* @brief 从mms中寻找Page结构体
*
* @param phys_addr
* @return struct Page*
*/
static struct Page *mm_find_page(uint64_t phys_addr, uint32_t zone_select)
{
uint32_t zone_start, zone_end;
switch (zone_select)
{
case ZONE_DMA:
// DMA区域
zone_start = 0;
zone_end = ZONE_DMA_INDEX;
break;
case ZONE_NORMAL:
zone_start = ZONE_DMA_INDEX;
zone_end = ZONE_NORMAL_INDEX;
break;
case ZONE_UNMAPPED_IN_PGT:
zone_start = ZONE_NORMAL_INDEX;
zone_end = ZONE_UNMAPPED_INDEX;
break;
default:
kerror("In mm_find_page: param: zone_select incorrect.");
// 返回空
return NULL;
break;
}
for (int i = zone_start; i <= zone_end; ++i)
{
if ((memory_management_struct.zones_struct + i)->count_pages_using == 0)
continue;
struct Zone *z = memory_management_struct.zones_struct + i;
// 区域对应的起止页号
ul page_start = (z->zone_addr_start >> PAGE_2M_SHIFT);
ul page_end = (z->zone_addr_end >> PAGE_2M_SHIFT);
ul tmp = 64 - page_start % 64;
for (ul j = page_start; j < page_end; j += ((j % 64) ? tmp : 64))
{
// 按照bmp中的每一个元素进行查找
// 先将p定位到bmp的起始元素
ul *p = memory_management_struct.bmp + (j >> 6);
ul shift = j % 64;
for (ul k = shift; k < 64; ++k)
{
if ((*p >> k) & 1) // 若当前页已分配
{
uint64_t page_num = j + k - shift;
struct Page *x = memory_management_struct.pages_struct + page_num;
if (x->addr_phys == phys_addr) // 找到对应的页
return x;
}
}
}
}
return NULL;
}
/**
* @brief 调整堆区域的大小(暂时只能增加堆区域)
*
@ -679,16 +796,38 @@ void mm_map_proc_page_table(ul proc_page_table_addr, bool is_phys, ul virt_addr_
*/
uint64_t mm_do_brk(uint64_t old_brk_end_addr, int64_t offset)
{
// 暂不支持缩小堆内存
if (offset < 0)
return old_brk_end_addr;
uint64_t end_addr = old_brk_end_addr + offset;
uint64_t end_addr = PAGE_2M_ALIGN(old_brk_end_addr + offset);
if (offset >= 0)
{
for (uint64_t i = old_brk_end_addr; i < end_addr; i += PAGE_2M_SIZE)
{
kdebug("map [%d]", i);
kdebug("map [%#018lx]", i);
mm_map_proc_page_table((uint64_t)current_pcb->mm->pgd, true, i, alloc_pages(ZONE_NORMAL, 1, PAGE_PGT_MAPPED)->addr_phys, PAGE_2M_SIZE, PAGE_USER_PAGE, true);
}
current_pcb->mm->brk_end = end_addr;
}
else
{
// 释放堆内存
for (uint64_t i = end_addr; i < old_brk_end_addr; i += PAGE_2M_SIZE)
{
uint64_t phys = mm_get_PDE((uint64_t)phys_2_virt((uint64_t)current_pcb->mm->pgd), false, i, true);
// 找到对应的页
struct Page *p = mm_find_page(phys, ZONE_NORMAL);
if (p == NULL)
{
kerror("cannot find page addr=%#018lx", phys);
return end_addr;
}
free_pages(p, 1);
}
mm_unmap_proc_table((uint64_t)phys_2_virt((uint64_t)current_pcb->mm->pgd), false, end_addr, PAGE_2M_ALIGN(ABS(offset)));
// 在页表中取消映射
}
return end_addr;
}

View File

@ -53,7 +53,7 @@ void sched_cfs()
cli();
current_pcb->flags &= ~PF_NEED_SCHED;
struct process_control_block *proc = sched_cfs_dequeue();
// kdebug("sched_cfs_ready_queue[proc_current_cpu_id].count = %d", sched_cfs_ready_queue[proc_current_cpu_id].count);
if (current_pcb->virtual_runtime >= proc->virtual_runtime || current_pcb->state != PROC_RUNNING) // 当前进程运行时间大于了下一进程的运行时间,进行切换
{

View File

@ -357,7 +357,7 @@ uint64_t sys_brk(struct pt_regs *regs)
{
uint64_t new_brk = PAGE_2M_ALIGN(regs->r8);
kdebug("sys_brk input= %#010lx , new_brk= %#010lx bytes current_pcb->mm->brk_start=%#018lx current->end_brk=%#018lx", regs->r8, new_brk, current_pcb->mm->brk_start, current_pcb->mm->brk_end);
// kdebug("sys_brk input= %#010lx , new_brk= %#010lx bytes current_pcb->mm->brk_start=%#018lx current->end_brk=%#018lx", regs->r8, new_brk, current_pcb->mm->brk_start, current_pcb->mm->brk_end);
if ((int64_t)regs->r8 == -1)
{
@ -372,10 +372,20 @@ uint64_t sys_brk(struct pt_regs *regs)
if (new_brk > current_pcb->addr_limit) // 堆地址空间超过限制
return -ENOMEM;
if (new_brk < current_pcb->mm->brk_end) // todo: 释放堆内存空间
return 0;
int64_t offset;
if (new_brk >= current_pcb->mm->brk_end)
offset = (int64_t)(new_brk - current_pcb->mm->brk_end);
else
offset = -(int64_t)(current_pcb->mm->brk_end - new_brk);
new_brk = mm_do_brk(current_pcb->mm->brk_end, new_brk - current_pcb->mm->brk_end); // 扩展堆内存空间
/*
if (offset < 0)
{
kdebug("decrease brk, offset = %#010lx", (uint64_t)(-offset));
}
*/
new_brk = mm_do_brk(current_pcb->mm->brk_end, offset); // 扩展堆内存空间
current_pcb->mm->brk_end = new_brk;
return 0;
@ -390,12 +400,25 @@ uint64_t sys_brk(struct pt_regs *regs)
uint64_t sys_sbrk(struct pt_regs *regs)
{
uint64_t retval = current_pcb->mm->brk_end;
regs->r8 = (int64_t)current_pcb->mm->brk_end + (int64_t)regs->r8;
if ((int64_t)regs->r8 > 0)
{
if (sys_brk(regs) == 0)
return retval;
else
uint64_t new_brk = PAGE_2M_ALIGN(retval + regs->r8);
if (new_brk > current_pcb->addr_limit) // 堆地址空间超过限制
{
kdebug("exceed mem limit, new_brk = %#018lx", new_brk);
return -ENOMEM;
}
}
else
{
if ((__int128_t)current_pcb->mm->brk_end + (__int128_t)regs->r8 < current_pcb->mm->brk_start)
return retval;
}
uint64_t new_brk = mm_do_brk(current_pcb->mm->brk_end, (int64_t)regs->r8); // 调整堆内存空间
current_pcb->mm->brk_end = new_brk;
return retval;
}
ul sys_ahci_end_req(struct pt_regs *regs)

View File

@ -45,8 +45,9 @@ int main()
if (*(uint64_t *)((uint64_t)(ptr[i]) - sizeof(uint64_t)) > 0x4008)
printf("[%d] start_addr = %#018lx, len = %#010lx\n", (uint64_t)(ptr[i]) - 8, *(uint64_t *)((uint64_t)(ptr[i]) - sizeof(uint64_t)));
}
printf("ptr[0]->len=%lld\n", *(uint64_t *)((uint64_t)ptr[0] - sizeof(uint64_t)));
printf("ptr[1]->len=%lld\n", *(uint64_t *)((uint64_t)ptr[1] - sizeof(uint64_t)));
// printf("ptr[0]->len=%lld\n", *(uint64_t *)((uint64_t)ptr[0] - sizeof(uint64_t)));
// printf("ptr[1]->len=%lld\n", *(uint64_t *)((uint64_t)ptr[1] - sizeof(uint64_t)));
// printf("ptr[24]->len=%lld\n", *(uint64_t*)((uint64_t)ptr[24] - sizeof(uint64_t)));
printf("alloc done. total used: %lld bytes\n", js);
printf("try to free...\n");

View File

@ -5,6 +5,24 @@
#include <libc/errno.h>
#include <libc/stdio.h>
#define PAGE_4K_SHIFT 12
#define PAGE_2M_SHIFT 21
#define PAGE_1G_SHIFT 30
#define PAGE_GDT_SHIFT 39
// 不同大小的页的容量
#define PAGE_4K_SIZE (1UL << PAGE_4K_SHIFT)
#define PAGE_2M_SIZE (1UL << PAGE_2M_SHIFT)
#define PAGE_1G_SIZE (1UL << PAGE_1G_SHIFT)
// 屏蔽低于x的数值
#define PAGE_4K_MASK (~(PAGE_4K_SIZE - 1))
#define PAGE_2M_MASK (~(PAGE_2M_SIZE - 1))
// 将addr按照x的上边界对齐
#define PAGE_4K_ALIGN(addr) (((unsigned long)(addr) + PAGE_4K_SIZE - 1) & PAGE_4K_MASK)
#define PAGE_2M_ALIGN(addr) (((unsigned long)(addr) + PAGE_2M_SIZE - 1) & PAGE_2M_MASK)
/**
* @brief 显式链表的结点
*
@ -23,14 +41,9 @@ static uint64_t brk_managed_addr = 0; // 堆区域已经被管理的地址
// 空闲链表
// 按start_addr升序排序
static malloc_mem_chunk_t *malloc_free_list = NULL;
static malloc_mem_chunk_t *malloc_free_list_end = NULL; // 空闲链表的末尾结点
/**
* @brief 获取一块堆内存(不尝试扩大堆内存)
*
* @param size
* @return void* 内存的地址指针,获取失败时返回-ENOMEM
*/
static void *malloc_no_enlarge(ssize_t size);
static uint64_t count_last_free_size = 0; // 统计距离上一次回收内存已经free了多少内存
/**
* @brief 将块插入空闲链表
@ -39,6 +52,12 @@ static void *malloc_no_enlarge(ssize_t size);
*/
static void malloc_insert_free_list(malloc_mem_chunk_t *ck);
/**
* @brief 当堆顶空闲空间大于2个页的空间的时候释放1个页
*
*/
static void release_brk();
/**
* @brief 在链表中检索符合要求的空闲块best fit
*
@ -52,7 +71,6 @@ static malloc_mem_chunk_t *malloc_query_free_chunk_bf(uint64_t size)
if (malloc_free_list == NULL)
{
printf("free list is none.\n");
return NULL;
}
malloc_mem_chunk_t *ptr = malloc_free_list;
@ -114,15 +132,16 @@ static int malloc_enlarge(int32_t size)
if (brk_base_addr == 0) // 第一次调用,需要初始化
{
brk_base_addr = brk(-1);
printf("brk_base_addr=%#018lx\n", brk_base_addr);
// printf("brk_base_addr=%#018lx\n", brk_base_addr);
brk_managed_addr = brk_base_addr;
brk_max_addr = brk(-2);
}
int64_t tmp = brk_managed_addr + size - brk_max_addr;
if (tmp > 0) // 现有堆空间不足
int64_t free_space = brk_max_addr - brk_managed_addr;
if (free_space < size) // 现有堆空间不足
{
if (sbrk(tmp) != (void *)(-1))
if (sbrk(size - free_space) != (void *)(-1))
brk_max_addr = brk((-2));
else
{
@ -133,10 +152,12 @@ static int malloc_enlarge(int32_t size)
// 扩展管理的堆空间
// 在新分配的内存的底部放置header
// printf("managed addr = %#018lx\n", brk_managed_addr);
malloc_mem_chunk_t *new_ck = (malloc_mem_chunk_t *)brk_managed_addr;
new_ck->length = brk_max_addr - brk_managed_addr;
printf("new_ck->start_addr=%#018lx\tbrk_max_addr=%#018lx\tbrk_managed_addr=%#018lx\n", (uint64_t)new_ck, brk_max_addr, brk_managed_addr);
new_ck->prev = new_ck->next = NULL;
// printf("new_ck->start_addr=%#018lx\tbrk_max_addr=%#018lx\tbrk_managed_addr=%#018lx\n", (uint64_t)new_ck, brk_max_addr, brk_managed_addr);
new_ck->prev = NULL;
new_ck->next = NULL;
brk_managed_addr = brk_max_addr;
malloc_insert_free_list(new_ck);
@ -153,14 +174,19 @@ static void malloc_merge_free_chunk()
if (malloc_free_list == NULL)
return;
malloc_mem_chunk_t *ptr = malloc_free_list->next;
while (ptr)
while (ptr != NULL)
{
// 内存块连续
if (((uint64_t)(ptr->prev) + ptr->prev->length == (uint64_t)ptr))
{
// printf("merged %#018lx and %#018lx\n", (uint64_t)ptr, (uint64_t)(ptr->prev));
// 将ptr与前面的空闲块合并
ptr->prev->length += ptr->length;
ptr->prev->next = ptr->next;
if (ptr->next == NULL)
malloc_free_list_end = ptr->prev;
else
ptr->next->prev = ptr->prev;
// 由于内存组成结构的原因不需要free掉header
ptr = ptr->prev;
}
@ -178,14 +204,15 @@ static void malloc_insert_free_list(malloc_mem_chunk_t *ck)
if (malloc_free_list == NULL) // 空闲链表为空
{
malloc_free_list = ck;
malloc_free_list_end = ck;
ck->prev = ck->next = NULL;
return;
}
else
{
uint64_t ck_end = (uint64_t)ck + ck->length;
malloc_mem_chunk_t *ptr = malloc_free_list;
while (ptr)
while (ptr != NULL)
{
if ((uint64_t)ptr < (uint64_t)ck)
{
@ -194,13 +221,14 @@ static void malloc_insert_free_list(malloc_mem_chunk_t *ck)
ptr->next = ck;
ck->next = NULL;
ck->prev = ptr;
malloc_free_list_end = ck;
break;
}
else if ((uint64_t)(ptr->next) > (uint64_t)ck)
{
ck->prev = ptr;
ck->next = ptr->next;
ck->prev->next = ck;
ptr->next = ck;
ck->next->prev = ck;
break;
}
@ -254,7 +282,6 @@ void *malloc(ssize_t size)
{
// 尝试合并空闲块
printf("merge\n");
malloc_merge_free_chunk();
ck = malloc_query_free_chunk_bf(size);
@ -262,11 +289,11 @@ void *malloc(ssize_t size)
if (ck)
goto found;
// 找不到合适的块,扩容堆区域
printf("enlarge\n");
if (malloc_enlarge(size) == -ENOMEM)
return (void *)-ENOMEM; // 内存不足
// 扩容后再次尝试获取
printf("query\n");
ck = malloc_query_free_chunk_bf(size);
}
found:;
@ -285,9 +312,11 @@ found:;
if (ck->next != NULL) // 当前不是最后一个块
ck->next->prev = ck->prev;
else
malloc_free_list_end = ck->prev;
// 当前块剩余的空间还能容纳多一个结点的空间,则分裂当前块
if (ck->length - size > sizeof(malloc_mem_chunk_t))
if ((int64_t)(ck->length) - size > sizeof(malloc_mem_chunk_t))
{
malloc_mem_chunk_t *new_ck = (malloc_mem_chunk_t *)(((uint64_t)ck) + size);
new_ck->length = ck->length - size;
@ -297,11 +326,34 @@ found:;
malloc_insert_free_list(new_ck);
}
// printf("ck=%lld\n", (uint64_t)ck);
// 此时链表结点的指针的空间被分配出去
return (void *)((uint64_t)ck + sizeof(uint64_t));
}
/**
* @brief 当堆顶空闲空间大于2个页的空间的时候释放1个页
*
*/
static void release_brk()
{
// 先检测最顶上的块
// 由于块按照开始地址排列,因此找最后一个块
if (malloc_free_list_end == NULL)
return;
if ((uint64_t)malloc_free_list_end + malloc_free_list_end->length == brk_max_addr && (uint64_t)malloc_free_list_end <= brk_max_addr - (PAGE_2M_SIZE << 1))
{
int64_t delta = (brk_max_addr - (uint64_t)malloc_free_list_end) & PAGE_2M_MASK - PAGE_2M_SIZE;
if (delta <= 0) // 不用释放内存
return;
sbrk(-delta);
brk_max_addr = brk(-2);
brk_managed_addr = brk_max_addr;
malloc_free_list_end->length = brk_max_addr - (uint64_t)malloc_free_list_end;
}
}
/**
* @brief 释放一块堆内存
*
@ -310,7 +362,15 @@ found:;
void free(void *ptr)
{
// 找到结点此时prev和next都处于未初始化的状态
malloc_mem_chunk_t * ck = (malloc_mem_chunk_t *)((uint64_t)ptr-sizeof(uint64_t));
malloc_mem_chunk_t *ck = (malloc_mem_chunk_t *)((uint64_t)ptr - sizeof(uint64_t));
// printf("free(): addr = %#018lx\t len=%#018lx\n", (uint64_t)ck, ck->length);
count_last_free_size += ck->length;
malloc_insert_free_list(ck);
if (count_last_free_size > PAGE_2M_SIZE)
{
count_last_free_size = 0;
malloc_merge_free_chunk();
release_brk();
}
}

View File

@ -63,8 +63,8 @@ pid_t vfork(void);
* @brief 将堆内存调整为end_brk
*
* @param end_brk 新的堆区域的结束地址
* end_brk=0 ===> 返回堆区域的起始地址
* end_brk=-1 ===> 返回堆区域的结束地址
* end_brk=-1 ===> 返回堆区域的起始地址
* end_brk=-2 ===> 返回堆区域的结束地址
* @return uint64_t 错误码
*
*/