Example #1
1
File: fork.c Project: wuxy/mitjos
// Challenge!
int
sfork(void)
{
	int r;
	pde_t *pde;
	pte_t *pte;
	unsigned i;
	uint32_t addr;
	envid_t envid;
	envid = sys_exofork();//创建子环境
	if(envid < 0)
		panic("sys_exofork: %e", envid);
	if(envid==0)//子环境中
	{
		env = &envs[ENVX(sys_getenvid())];
		return 0;
	}
	else{//父环境中,注意:这里需要设置父环境的缺页异常栈,还需要设置子环境的缺页异常栈,
	//父子环境的页异常栈不共享?具体原因还得思考
		env = &envs[ENVX(sys_getenvid())];
		set_pgfault_handler(pgfault);//设置缺页异常处理函数,这里设置了父环境的缺页异常栈
		for(i=0;i<(unsigned)VPN(UTOP);i++)//重映射writable or copy-to-write的页面
		{
			addr=i*PGSIZE;
			pde =(pde_t*) &vpd[VPD(addr)];
			if(*pde&PTE_P)//这里只处理有物理页面映射的页表项
			{
				pte=(pte_t*)&vpt[VPN(addr)];
			}
			else    continue;
			if((i==(unsigned)VPN(USTACKTOP-PGSIZE))||(i==(unsigned)VPN(PFTEMP)))
								//特殊处理,用户层普通栈
			{	
				if((r=duppage(envid,i))<0)
					return r;
				continue;
			}
			if((r=sduppage(envid,i))<0)
				return r;
		}
		if((r=sys_page_alloc(envid,(void*)(UXSTACKTOP-PGSIZE),PTE_W|PTE_U|PTE_P))<0)
                        return r;//设置子环境的缺页异常栈
		if((r=sys_env_set_pgfault_upcall(envid,(void*)_pgfault_upcall))<0)
			return r;//设置子环境的缺页异常处理入口点
		if((r=sys_env_set_status(envid,ENV_RUNNABLE))<0)
			return r;//设置子环境的状态为可运行
		return envid;
	}
	//panic("sfork not implemented");
	//return -E_INVAL;
}
Example #2
0
// Challenge!
int
sfork(void)
{
/*	panic("sfork not implemented");
	return -E_INVAL;*/
	extern void _pgfault_upcall(void);
	set_pgfault_handler(pgfault);
	envid_t id = sys_exofork();
	int r;
	if (id < 0)
		panic("exofork: child");
	if (id == 0)
	{
		thisenv = envs + ENVX(sys_getenvid());
		return 0;
	}
	uint32_t i;
/*	for (i=0;i<UTOP-PGSIZE;i+=PGSIZE)
		if ((vpd[PDX(i)] & PTE_P) && (vpt[PGNUM(i)] & PTE_P))
			if ((r=duppage(id,PGNUM(i)))<0)
				return r;*/
	if ((r=sys_page_alloc(id, (void*)(UXSTACKTOP-PGSIZE), PTE_U | PTE_W | PTE_P))<0)
		return r;
//	cprintf("begin to map!\nUSTACKTOP-PGSIZE: %x\nUTEXT: %x\n",USTACKTOP-PGSIZE,UTEXT);
	for (i=USTACKTOP-PGSIZE;i>=UTEXT;i-=PGSIZE)
	{
		if ((vpd[PDX(i)] & PTE_P) && (vpt[PGNUM(i)] & PTE_P))
		{
			if ((r=sduppage(id,PGNUM(i),1))<0)
				return r;	
		}else
			break;
	}
	for (;i>=UTEXT;i-=PGSIZE)
		if ((vpd[PDX(i)] & PTE_P) && (vpt[PGNUM(i)] & PTE_P))
			if ((r=sduppage(id,PGNUM(i),0))<0)
				return r;

	if ((r=sys_env_set_pgfault_upcall(id,(void*)_pgfault_upcall))<0)
		return r;
	if ((r=sys_env_set_status(id, ENV_RUNNABLE))<0)
		return r;
//	cprintf("sfork succeed!\n");
	return id;
}