ipc implemented.
[mit-jos.git] / user / dumbfork.c
blob55859ea8128cb8cbed15d1749e95b094b9c25b63
1 // Ping-pong a counter between two processes.
2 // Only need to start one of these -- splits into two, crudely.
4 #include <inc/string.h>
5 #include <inc/lib.h>
7 envid_t dumbfork(void);
9 void
10 umain(void)
12 envid_t who;
13 int i;
15 // fork a child process
16 who = dumbfork();
18 // print a message and yield to the other a few times
19 for (i = 0; i < (who ? 10 : 20); i++) {
20 cprintf("%d: I am the %s!\n", i, who ? "parent" : "child");
21 sys_yield();
25 void
26 duppage(envid_t dstenv, void *addr)
28 int r;
30 // This is NOT what you should do in your fork.
31 if ((r = sys_page_alloc(dstenv, addr, PTE_P|PTE_U|PTE_W)) < 0)
32 panic("sys_page_alloc: %e", r);
33 if ((r = sys_page_map(dstenv, addr, 0, UTEMP, PTE_P|PTE_U|PTE_W)) < 0)
34 panic("sys_page_map: %e", r);
35 memmove(UTEMP, addr, PGSIZE);
36 if ((r = sys_page_unmap(0, UTEMP)) < 0)
37 panic("sys_page_unmap: %e", r);
40 envid_t
41 dumbfork(void)
43 envid_t envid;
44 uint8_t *addr;
45 int r;
46 extern unsigned char end[];
48 // Allocate a new child environment.
49 // The kernel will initialize it with a copy of our register state,
50 // so that the child will appear to have called sys_exofork() too -
51 // except that in the child, this "fake" call to sys_exofork()
52 // will return 0 instead of the envid of the child.
53 envid = sys_exofork();
54 if (envid < 0)
55 panic("sys_exofork: %e", envid);
56 if (envid == 0) {
57 // We're the child.
58 // The copied value of the global variable 'env'
59 // is no longer valid (it refers to the parent!).
60 // Fix it and return 0.
61 env = &envs[ENVX(sys_getenvid())];
62 return 0;
65 // We're the parent.
66 // Eagerly copy our entire address space into the child.
67 // This is NOT what you should do in your fork implementation.
68 for (addr = (uint8_t*) UTEXT; addr < end; addr += PGSIZE)
69 duppage(envid, addr);
71 // Also copy the stack we are currently running on.
72 duppage(envid, ROUNDDOWN(&addr, PGSIZE));
74 // Start the child environment running
75 if ((r = sys_env_set_status(envid, ENV_RUNNABLE)) < 0)
76 panic("sys_env_set_status: %e", r);
78 return envid;