//释放用户进程资源 //1 页表中对应的物理页 //2 虚拟内存池占物理页框 //3 关闭打开的文件 static void release_prog_resource(struct task_struct* release_thread){ uint32_t* pgdir_vaddr = release_thread->pgdir; uint16_t user_pde_nr = 768,pde_idx = 0; uint32_t pde = 0; uint32_t* v_pde_ptr = NULL; //v表示var,和函数pde_ptr区分 uint16_t user_ptr_nr = 1024,pte_idx = 0; uint32_t pte = 0; uint32_t* v_pte_ptr = NULL; //v表示var,和函数pte_ptr区分 uint32_t* first_pte_vaddr_in_pde = NULL; //用来记录pde中第0个pte的地址 uint32_t pg_phy_addr = 0; //回收页表中用户空间的页框 while(pde_idx < user_pde_nr){ v_pde_ptr = pgdir_vaddr + pde_idx; pde = *v_pde_ptr; if(pde & 0x00000001){ //如果页目录项p位表示1,表示该页目录项下可能有页表项 first_pte_vaddr_in_pde = pte_ptr(pde_idx * 0x400000); //一个页表表示的内存容量是4M,即0x400000 pte_idx = 0; while(pte_idx < user_ptr_nr){ v_pte_ptr = first_pte_vaddr_in_pde + pte_idx; pte = *v_pte_ptr; if(pte & 0x00000001){ //将pte中记录的物理页框直接在相应内存池的位图中清0 pg_phy_addr = pte & 0xfffff000; free_a_phy_page(pg_phy_addr); } pte_idx++; } //将pde中记录的物理页框直接在相应内存池中清0 pg_phy_addr = pde & 0xfffff000; free_a_phy_page(pg_phy_addr); } pde_idx++; } //回收用户虚拟地址池所占的物理内存 uint32_t bitmap_pg_cnt = (release_thread->userprog_vaddr.vaddr_bitmap.btmp_bytes_len) / PG_SIZE; uint8_t* user_vaddr_pool_bitmap = release_thread->userprog_vaddr.vaddr_bitmap.bits; mfree_page(PF_KERNEL,user_vaddr_pool_bitmap,bitmap_pg_cnt); //关闭进程打开的文件 uint8_t local_fd = 3; while(local_fd < MAX_FILES_OPEN_PER_PROC){ if(release_thread->fd_table[local_fd] != -1){ if(is_pipe(local_fd)){ uint32_t global_fd = fd_local2global(local_fd); if(--file_table[global_fd].fd_pos == 0){ mfree_page(PF_KERNEL,file_table[global_fd].fd_inode,1); file_table[global_fd].fd_inode = NULL; } }else{ sys_close(local_fd); } } local_fd++; } }
/* 关闭文件描述符fd指向的文件,成功返回0,否则返回-1 */ int32_t sys_close(int32_t fd) { int32_t ret = -1; // 返回值默认为-1,即失败 if (fd > 2) { uint32_t _fd = fd_local2global(fd); ret = file_close(&file_table[_fd]); running_thread()->fd_table[fd] = -1; // 使该文件描述符位可用 } return ret; }