Files
MIT6.828_OS/lab/user/dumbfork.c
2019-07-06 10:39:40 +08:00

91 lines
2.4 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// Ping-pong a counter between two processes.
// Only need to start one of these -- splits into two, crudely.
#include <inc/string.h>
#include <inc/lib.h>
envid_t dumbfork(void);
void
umain(int argc, char **argv)
{
envid_t who;
int i;
// fork a child process
who = dumbfork();
// print a message and yield to the other a few times
for (i = 0; i < (who ? 10 : 20); i++) {
cprintf("%d: I am the %s!\n", i, who ? "parent" : "child");
sys_yield();
}
}
void
duppage(envid_t dstenv, void *addr)
{
int r;
// This is NOT what you should do in your fork.
if ((r = sys_page_alloc(dstenv, addr, PTE_P|PTE_U|PTE_W)) < 0)
panic("sys_page_alloc: %e", r);
// dstenv 的 addr 映射到 envs[0]的UTEMP
if ((r = sys_page_map(dstenv, addr, 0, UTEMP, PTE_P|PTE_U|PTE_W)) < 0)
panic("sys_page_map: %e", r);
memmove(UTEMP, addr, PGSIZE);
if ((r = sys_page_unmap(0, UTEMP)) < 0)
panic("sys_page_unmap: %e", r);
}
envid_t
dumbfork(void)
{
envid_t envid;
uint8_t *addr;
int r;
extern unsigned char end[];
// Allocate a new child environment.
// The kernel will initialize it with a copy of our register state,
// so that the child will appear to have called sys_exofork() too -
// except that in the child, this "fake" call to sys_exofork()
// will return 0 instead of the envid of the child.
envid = sys_exofork();
cprintf("envid: %d\n",envid);
if (envid < 0)
panic("sys_exofork: %e", envid);
if (envid == 0) {
// We're the child.
// The copied value of the global variable 'thisenv'
// is no longer valid (it refers to the parent!).
// Fix it and return 0.
// "child, sysgetenvid() : 1
// cprintf("child, sysgetenvid() :%d\n", ENVX(sys_getenvid()));
thisenv = &envs[ENVX(sys_getenvid())];
return 0;
}
// We're the parent.
// Eagerly copy our entire address space into the child.
// This is NOT what you should do in your fork implementation.
// 用户程序通常从 UTEXT处开始。
for (addr = (uint8_t*) UTEXT; addr < end; addr += PGSIZE) {
// copying addr :00800000
// copying addr :00801000
// copying addr :00802000
cprintf("copying addr :%08x\n", (uint32_t)addr);
duppage(envid, addr);
}
// Also copy the stack we are currently running on.
duppage(envid, ROUNDDOWN(&addr, PGSIZE));
// Start the child environment running
if ((r = sys_env_set_status(envid, ENV_RUNNABLE)) < 0)
panic("sys_env_set_status: %e", r);
return envid;
}