Пример #1
0
//释放用户进程资源
//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++;
	}
}
Пример #2
0
/* 关闭文件描述符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;
}