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>
7 envid_t
dumbfork(void);
15 // fork a child process
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");
26 duppage(envid_t dstenv
, void *addr
)
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
);
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();
55 panic("sys_exofork: %e", envid
);
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())];
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
)
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
);