physical control flow
play

Physical Control Flow Physical control flow <startup> inst 1 - PDF document

Physical Control Flow Physical control flow <startup> inst 1 inst 2 Time inst 3 inst n <shutdown> Sean Barker 1 Operating System User-level Applications Operating System Hardware Resources Sean Barker 2 Processes


  1. Physical Control Flow Physical control flow <startup> inst 1 inst 2 Time inst 3 … inst n <shutdown> Sean Barker 1 Operating System User-level Applications Operating System Hardware Resources Sean Barker 2

  2. Processes Memory Memory Memory Stack Stack Stack Heap Heap Heap … Data Data Data Code Code Code CPU CPU CPU Registers Registers Registers Sean Barker 3 Control Flow Abstraction Process A Process B Process C Time Sean Barker 4

  3. Control Flow Time-Sharing Process A Process B Process C Time Sean Barker 5 Context Switching Process A Process B user code context switch kernel code Time user code context switch kernel code user code Sean Barker 6

  4. Exceptions User-Process OS exception event' exception'processing by/ exception'handler return'or'abort Sean Barker 7 Example: Segmentation Fault int a[1000]; main () { a[5000] = 13; } 80483b7: c7 05 60 e3 04 08 0d movl $0xd,0x804e360 User code Kernel code Excep&on: page fault movl Detect invalid address Signal process Sean Barker 8

  5. Exception Table Excep&on numbers Code for excep&on handler 0 Excep&on Code for Table excep&on handler 1 0 1 Code for 2 excep&on handler 2 ... ... n-1 Code for excep&on handler n-1 Sean Barker 9 Process Management Memory Memory Memory Stack Stack Stack Heap Heap Heap … Data Data Data Code Code Code CPU CPU CPU Registers Registers Registers Sean Barker 10

  6. Fork/Exec Stack 1 Code/state.of.shell.process. Heap Replaced.by.code/state.of.ls. Copy.of.code/state. Data of.shell.process. Code:./usr/bin/bash fork() : child parent child Stack Stack Stack 2 2 3 exec() : Heap Heap Data Data Data Code:./usr/bin/bash Code:./usr/bin/bash Code:./usr/bin/ls Code/state.of.shell.process. 7 Sean Barker 11 Zombies! Sean Barker 12

  7. Reaping: waitpid wait pid_t waitpid(pid_t pid, int* stat, int ops ) Suspend.current.process.(i.e..parent).until.child.with. pid ends. wait set Sean Barker 13 Status Macros wait pid_t waitpid(pid_t pid, int* stat, int ops ) Suspend.current.process.(i.e..parent).until.child.with. pid ends. WEXITSTATUS(stat) child exit code true if terminated normally WIFEXITED(stat) (called exit or returned from main) WIFSIGNALED(stat) true if terminated by signal WIFSTOPPED(stat) true if paused by signal Sean Barker 14

  8. Option Macros wait pid_t waitpid(pid_t pid, int* stat, int ops ) Suspend.current.process.(i.e..parent).until.child.with. pid ends. return immediately if child not WNOHANG already terminated WUNTRACED also wait for paused (stopped) children WCONTINUED also wait for resumed children Sean Barker 15 System Call Error Handling Always check return values! if ((pid = fork()) < 0) { ! fprintf(stderr, "fork error: %s\n", strerror(errno)); ! exit(0); ! } Sean Barker 16

  9. Basic Shell Design others... while (true) { Print command prompt. Read command line from user. Parse command line. If command is built-in, do it. Else fork process to execute command. in child: Execute requested command with execv. (never returns) in parent: Wait for child to complete. } Sean Barker 17 Signals ID Name Corresponding2Event Default2Action Can2 Override? 2 SIGINT Interrupt((Ctrl?C) T erminate Yes 9 SIGKILL Kill(process((immediately) T erminate No 11 SIGSEGV Segmentation(violation T erminate( &(Dump Yes 14 SIGALRM Timer(signal T erminate Yes 15 SIGTERM Kill(process((politely) T erminate Yes 17 SIGCHLD Child(stopped(or(terminated Ignore Yes 18 SIGCONT Continue(stopped(process Continue((Resume) No 19 SIGSTOP Stop(process((immediately) Stop((Suspend) No 20 SIGTSTP Stop(process((politely) Stop((Suspend) Yes (Ctrl-Z) … Sean Barker 18

  10. Recap: Segmentation Fault int a[1000]; main () { a[5000] = 13; } 80483b7: c7 05 60 e3 04 08 0d movl $0xd,0x804e360 User code Kernel code Excep&on: page fault movl Detect invalid address Signal process Sean Barker 19 Signal Control Flow (1) Signal received (2) Control passes by process to signal handler I curr I next (3) Signal handler runs (4) Signal handler returns to next instruction Sean Barker 20

  11. Signal Handler as Concurrent Flow Process A Process A Process B while (1) handler(){ ; … } Time Sean Barker 21 Signal Handler as Concurrent Flow (alt) Process A Process B Signal delivered user code (main) I curr to process A context switch kernel code user code (main) context switch kernel code Signal received user code (handler) by process A kernel code I next user code (main) Sean Barker 22

  12. Process Groups pid=10 Shell pgid=10 Fore- Back- Back- pid=20 pid=32 pid=40 ground ground ground pgid=20 pgid=32 pgid=40 job #1 job job #2 Background Background process group 32 process group 40 Child Child pid=21 pid=22 pgid=20 pgid=20 Foreground process group 20 Sean Barker 23 Signal Handler as Concurrent Flow Process A Process A Process B while (1) handler(){ ; … } Time Sean Barker 24

  13. ! Concurrency Example (1) int main(int argc, char** argv) { ! int pid; ! ! // add handler Signal(SIGCHLD, handler); ! initjobs(); /* Initialize the job list */ ! while (1) { ! if ((pid = fork()) == 0) { /* Child */ ! execve("/bin/date", argv, NULL); ! } ! addjob(pid); /* Add child to job list */ } ! exit(0); ! } ! void handler(int sig) { ! pid_t pid; ! ! while ((pid = waitpid(-1, NULL, 0)) > 0) { /* Reap child */ deletejob(pid); /* Delete the child from the job list */ } ! // handle case where waitpid returns if (errno != ECHILD) ! // -1 but not an error unix_error("waitpid error"); ! } ! Sean Barker 25 Concurrency Example (2) int main(int argc, char** argv) { ! int pid; ! sigset_t mask_all, prev_all; ! sigfillset(&mask_all); ! Signal(SIGCHLD, handler); ! initjobs(); /* Initialize the job list */ ! while (1) { ! if ((pid = fork()) == 0) { /* Child */ ! execve("/bin/date", argv, NULL); ! } ! sigprocmask(SIG_BLOCK, &mask_all, &prev_all); ! addjob(pid); /* Add child to the job list */ ! sigprocmask(SIG_SETMASK, &prev_all, NULL); ! } ! exit(0); ! } ! void handler(int sig) { ! sigset_t mask_all, prev_all; ! pid_t pid; ! sigfillset(&mask_all); ! while ((pid = waitpid(-1, NULL, 0)) > 0) { /* Reap child */ ! sigprocmask(SIG_BLOCK, &mask_all, &prev_all); ! deletejob(pid); /* Delete child from job list */ ! sigprocmask(SIG_SETMASK, &prev_all, NULL); ! } ! if (errno != ECHILD) ! unix_error("waitpid error"); ! } ! Sean Barker 26

  14. ! ! Concurrency Example (3) int main(int argc, char** argv) { ! int pid; ! sigset_t mask_all, mask_one, prev_one; ! sigfillset(&mask_all); ! sigemptyset(&mask_one); ! sigaddset(&mask_one, SIGCHLD); ! Signal(SIGCHLD, handler); ! initjobs(); /* Initialize the job list */ ! while (1) { ! sigprocmask(SIG_BLOCK, &mask_one, &prev_one); /* Block SIGCHLD */ ! if ((pid = fork()) == 0) { /* Child process */ ! sigprocmask(SIG_SETMASK, &prev_one, NULL); /* Unblock SIGCHLD */ ! execve("/bin/date", argv, NULL); ! } ! sigprocmask(SIG_BLOCK, &mask_all, NULL); /* Parent process */ ! addjob(pid); /* Add the child to the job list */ ! sigprocmask(SIG_SETMASK, &prev_one, NULL); /* Unblock SIGCHLD */ ! } ! exit(0); ! } ! Sean Barker 27 Key System Calls • fork – Create a new process • execve – Run a new program • kill – Send a signal • waitpid – Wait for and/or reap child process • setpgid – Set process group ID • sigprocmask – Block or unblock signals • sigemptyset – Create empty signal set • sigfillset – Add every signal number to set • sigaddset – Add signal number to set • sigdelset – Delete signal number from set • sigsuspend – Wait until signal received Sean Barker 28

  15. Processes Memory Memory Memory Stack Stack Stack Heap Heap Heap … Data Data Data Code Code Code CPU CPU CPU Registers Registers Registers Sean Barker 29 Threads Sean Barker 30

  16. ! ! ! Thread Example /* * hello.c - Pthreads "hello, world" program */ ! Thread attributes Thread ID (usually NULL) void* thread(void* vargp); ! int main() { ! Thread routine pthread_t tid; ! pthread_create(&tid, NULL, thread, NULL); ! pthread_join(tid, NULL); ! Thread arguments exit(0); ! (void *p) hello.c } ! Return value (void **p) void* thread(void* vargp) { /* thread routine */ ! printf("Hello, world!\n"); ! return NULL; ! } hello.c Sean Barker 31

Recommend


More recommend