tos arno puder
play

TOS Arno Puder 1 Objectives Explain how to create new processes - PowerPoint PPT Presentation

TOS Arno Puder 1 Objectives Explain how to create new processes under Unix Explain how fork() could be implemented under TOS 2 Review: create_process() New processes are created in TOS using create_process() create_process()


  1. TOS Arno Puder 1

  2. Objectives • Explain how to create new processes under Unix • Explain how fork() could be implemented under TOS 2

  3. Review: create_process() • New processes are created in TOS using create_process() • create_process() does: – Allocate a free PCB entry – Initialize the PCB entry – Setup the initial stack frame • The entry point of a TOS process is defined via a function pointer 3

  4. Example: create_process() void test_process (PROCESS self, PARAM param) { // assert (self->name == “ Test process ” ) // assert (param == 42) } void kernel_main () { // … create_process (test_process, 5, 42, "Test process"); } 4

  5. Stack of the new process 1 MB param PARAM actual parameter 640 KB 30 K stack self PROCESS actual parameter { frame for Return address (dummy argument) process 0 Address of new process (EIP) func { EAX 30 K stack frame for ECX process 1 EDX EBX EBP ESI EDI ∞ Address TOS code 0 Address ∞ will be saved in PCB.esp 5

  6. Overview of fork() • In Unix, a new process is created via a call to fork(). • fork() creates an exact copy of the calling process. • Exact copy of: – Program code – Heap – Stack 6

  7. fork() man page NAME fork - create a child process SYNOPSIS #include <sys/types.h> #include <unistd.h> pid_t fork(void); DESCRIPTION fork creates a child process that differs from the parent process only in its PID and PPID. Parent Process ID Process ID RETURN VALUE On success, the PID of the child process is returned in the parent's thread of execution, and a 0 is returned in the child's thread of execution. On failure, a -1 will be returned in the parent's context, no child process will be created, and errno will be set appropriately. 7

  8. fork() – Example under Unix #include <iostream> Output: #include <unistd.h> Parent process. x=42 void main() Child process. x=42 { int x = 42; if (fork() != 0) cout << "Parent process. x=" << x << endl; else cout << "Child process. x=" << x << endl; } 8

  9. Stack for Boot Process RET addr 1 Before calling fork() a i 42 RET addr 2 z %ESP void f (int x) { int z; Before fork() fork(); } void g() { Unsued Stack char a; int i; f (42); RET addr 2 } void kernel_main () { g(); RET addr 1 } 9

  10. Stack for Boot Process RET addr 1 After calling fork() a i 42 RET addr 2 z %ESP void f (int x) { int z; RET addr 1 fork(); a Location 3 i } 42 RET addr 2 void g() z Stack for new Process { 512 (%EFLAGS) char a; 8 (%CS) Location 3 int i; EAX f (42); RET addr 2 ECX } EDX EBX pcb[i].esp void kernel_main () EBP ESI { EDI g(); RET addr 1 } 10

  11. Loading Processes • If fork() only creates a copy of the parent process, how can different programs be run under Unix? • Solution: execve() loads a new program. – A call to execve() loads a new program into the running process. – A call to execve() therefore never returns (unless there is an error). 11

  12. fork/wait/execve Example #include <iostream> #include <unistd.h> #include <sys/wait.h> void main() { int x = 42; if (fork() != 0) { int status; cout << "Parent process. x=" << x << endl; wait (&status); } else { cout << "Child process. x=" << x << endl; char* args[] = {"ls", NULL}; char* env[] = {NULL}; execve ("/bin/ls", args, env); cout << "Never reached" << endl; } 12 }

Recommend


More recommend