Presentation is loading. Please wait.

Presentation is loading. Please wait.

System Control Flow, Processes CSE 351 Winter 2019

Similar presentations


Presentation on theme: "System Control Flow, Processes CSE 351 Winter 2019"— Presentation transcript:

1 System Control Flow, Processes CSE 351 Winter 2019
11/15/2017 System Control Flow, Processes CSE 351 Winter 2019 Instructors: Max Willsey Luis Ceze Teaching Assistants: Britt Henderson Daniel Snitkovsky Lukas Joswiak Luis Vega Josie Lee Kory Watson Wei Lin Ivy Yu

2 Administrivia HW4 due Friday (3/1) Lab4 out! Due Monday (3/4)
Start early! No OH on weekend

3 Caches: What about writes?
Multiple copies of data exist: L1, L2, possibly L3, main memory What to do on a write-hit? Write-through: write immediately to next level Write-back: defer write to next level until line is evicted (replaced) Must track which cache lines have been modified (“dirty bit”) What to do on a write-miss? Write-allocate: (“fetch on write”) load into cache, update line in cache Good if more writes or reads to the location follow No-write-allocate: (“write around”) just write immediately to memory Typical caches: Write-back + Write-allocate, usually Write-through + No-write-allocate, occasionally Why? Reuse is common Typically you would read, then write (incr) Or after you initialize a value (say, to 0), likely read and write it again soon

4 Write-back, write-allocate example
Contents of memory stored at address G Cache G 0xBEEF dirty bit Valid bit not shown Tiny cache, 1 set, tag is G Dirty bit because write back tag (there is only one set in this tiny cache, so the tag is the entire block address!) In this example we are sort of ignoring block offsets. Here a block holds 2 bytes (16 bits, 4 hex digits). Normally a block would be much bigger and thus there would be multiple items per block. While only one item in that block would be written at a time, the entire line would be brought into cache. Memory F 0xCAFE G 0xBEEF

5 Write-back, write-allocate example
mov 0xFACE, F Cache G 0xBEEF dirty bit Miss, need to maybe write back But not dirty, so I don’t have to Pull in F Memory F 0xCAFE G 0xBEEF

6 Write-back, write-allocate example
mov 0xFACE, F Cache F U 0xBEEF 0xCAFE 0xCAFE dirty bit Pull in F, then write Step 1: Bring F into cache Memory F 0xCAFE G 0xBEEF

7 Write-back, write-allocate example
mov 0xFACE, F Cache F U 0xBEEF 0xCAFE 0xFACE 1 dirty bit Write, make dirty (write-back) Step 2: Write 0xFACE to cache only and set dirty bit Memory F 0xCAFE G 0xBEEF

8 Write-back, write-allocate example
mov 0xFACE, F mov 0xFEED, F Cache F U 0xFACE 0xCAFE 0xBEEF 1 dirty bit Another write hit, don’t need to go to mem Write hit! Write 0xFEED to cache only Memory F 0xCAFE G 0xBEEF

9 Write-back, write-allocate example
mov 0xFACE, F mov 0xFEED, F mov G, %rax Cache F U 0xFEED 0xBEEF 0xCAFE 1 dirty bit Read miss, and my line is dirty! Write back Memory F 0xCAFE G 0xBEEF

10 Write-back, write-allocate example
mov 0xFACE, F mov 0xFEED, F mov G, %rax Cache G 0xBEEF dirty bit 1. Write F back to memory since it is dirty 2. Bring G into the cache so we can copy it into %rax Memory F 0xFEED G 0xBEEF

11 Optimizations for the Memory Hierarchy
Write code that has locality! Spatial: access data contiguously Temporal: make sure access to the same data is not too far apart in time How can you achieve locality? Adjust memory accesses in code (software) to improve miss rate (MR) Requires knowledge of both how caches work as well as your system’s parameters Proper choice of algorithm Loop transformations

12 Example: Matrix Multiplication
B ai* b*j cij = × Subscript indices given in (row,col). C = C + AB

13 Matrices in Memory How do cache blocks fit into this scheme?
Row major matrix in memory: Cache blocks COLUMN of matrix (blue) is spread among cache blocks shown in red

14 Naïve Matrix Multiply = + ×
# move along rows of A for (i = 0; i < n; i++) # move along columns of B for (j = 0; j < n; j++) # EACH k loop reads row of A, col of B # Also read & write c(i,j) n times for (k = 0; k < n; k++) c[i*n+j] += a[i*n+k] * b[k*n+j]; Note the += leads to an additional read of matrix C = + × C(i,j) A(i,:) B(:,j)

15 Cache Miss Analysis (Naïve)
Ignoring matrix c Scenario Parameters: Square matrix (𝑛×𝑛), elements are doubles Cache block size 𝐾 = 64 B = 8 doubles Cache size 𝐶≪𝑛 (much smaller than 𝑛) Each iteration: 𝑛 8 +𝑛= 9𝑛 8 misses Cache size << n is key! 8 elems per cache block A: stride 1 B: stride n (all miss) B is all or nothing! Either column 2 is in cache or we’ve evicted it = ×

16 Cache Miss Analysis (Naïve)
Ignoring matrix c Scenario Parameters: Square matrix (𝑛×𝑛), elements are doubles Cache block size 𝐾 = 64 B = 8 doubles Cache size 𝐶≪𝑛 (much smaller than 𝑛) Each iteration: 𝑛 8 +𝑛= 9𝑛 8 misses Afterwards in cache: (schematic) = × × = 8 doubles wide

17 Cache Miss Analysis (Naïve)
Ignoring matrix c Scenario Parameters: Square matrix (𝑛×𝑛), elements are doubles Cache block size 𝐾 = 64 B = 8 doubles Cache size 𝐶≪𝑛 (much smaller than 𝑛) Each iteration: 𝑛 8 +𝑛= 9𝑛 8 misses Total misses: 9𝑛 8 ×𝑛2= 9 8 𝑛3 = × once per element

18 Linear Algebra to the Rescue
This is extra (non-testable) material Linear Algebra to the Rescue Can get the same result of a matrix multiplication by splitting the matrices into smaller submatrices Multiplication operates on small “block” matrices Choose size so that they fit in the cache! This technique called “cache blocking”

19 Blocked Matrix Multiply
Blocked version of the naïve algorithm: 𝑟 = block matrix size (assume 𝑟 divides 𝑛 evenly) # move by rxr BLOCKS now for (i = 0; i < n; i += r) for (j = 0; j < n; j += r) for (k = 0; k < n; k += r) # block matrix multiplication for (ib = i; ib < i+r; ib++) for (jb = j; jb < j+r; jb++) for (kb = k; kb < k+r; kb++) c[ib*n+jb] += a[ib*n+kb]*b[kb*n+jb]; More loops, but way faster!

20 Cache Miss Analysis (Blocked)
Ignoring matrix c Scenario Parameters: Cache block size 𝐾 = 64 B = 8 doubles Cache size 𝐶≪𝑛 (much smaller than 𝑛) Three blocks (𝑟×𝑟) fit into cache: 3𝑟2<𝐶 Each block iteration: 𝑟 2 /8 misses per block 2𝑛/𝑟×𝑟2/8=𝑛𝑟/4 𝑛/𝑟 blocks 𝑟2 elements per block, 8 per cache block 3 whole blocks in cache! So going column is ok 3B2 < C: need to be able to fit three full blocks in the cache (one for c, one for a, one for b) while executing the algorithm = × 𝑛/𝑟 blocks in row and column

21 Cache Miss Analysis (Blocked)
Ignoring matrix c Scenario Parameters: Cache block size 𝐾 = 64 B = 8 doubles Cache size 𝐶≪𝑛 (much smaller than 𝑛) Three blocks (𝑟×𝑟) fit into cache: 3𝑟2<𝐶 Each block iteration: 𝑟 2 /8 misses per block 2𝑛/𝑟×𝑟2/8=𝑛𝑟/4 Afterwards in cache (schematic) 𝑛/𝑟 blocks 𝑟2 elements per block, 8 per cache block 3r2 < C: need to be able to fit three full blocks in the cache (one for c, one for a, one for b) while executing the algorithm = × 𝑛/𝑟 blocks in row and column = ×

22 Cache Miss Analysis (Blocked)
Ignoring matrix c Scenario Parameters: Cache block size 𝐾 = 64 B = 8 doubles Cache size 𝐶≪𝑛 (much smaller than 𝑛) Three blocks (𝑟×𝑟) fit into cache: 3𝑟2<𝐶 Each block iteration: 𝑟 2 /8 misses per block 2𝑛/𝑟×𝑟2/8=𝑛𝑟/4 Total misses: (𝑛𝑟/4)×(𝑛/𝑟)2=𝑛3/(4𝑟) 𝑛/𝑟 blocks 𝑟2 elements per block, 8 per cache block 3r2 < C: need to be able to fit three full blocks in the cache (one for c, one for a, one for b) while executing the algorithm vs 9n3 / 8 = × 𝑛/𝑟 blocks in row and column

23 Cache-Friendly Code Programmer can optimize for cache performance
How data structures are organized How data are accessed Nested loop structure Blocking is a general technique All systems favor “cache-friendly code” Getting absolute optimum performance is very platform specific Cache size, cache block size, associativity, etc. Can get most of the advantage with generic code Keep working set reasonably small (temporal locality) Use small strides (spatial locality) Focus on inner loop code

24 Roadmap C: Java: Assembly language: OS: Machine code: Computer system:
Memory & data Integers & floats x86 assembly Procedures & stacks Executables Arrays & structs Memory & caches Processes Virtual memory Memory allocation Java vs. C car *c = malloc(sizeof(car)); c->miles = 100; c->gals = 17; float mpg = get_mpg(c); free(c); Car c = new Car(); c.setMiles(100); c.setGals(17); float mpg = c.getMPG(); Assembly language: get_mpg: pushq %rbp movq %rsp, %rbp ... popq %rbp ret OS: Machine code: Computer system:

25 Leading Up to Processes
System Control Flow Control flow Exceptional control flow Asynchronous exceptions (interrupts) Synchronous exceptions (traps & faults)

26 Control Flow So far: we’ve seen how the flow of control changes as a single program executes Reality: multiple programs running concurrently How does control flow across the many components of the system? In particular: More programs running than CPUs Exceptional control flow is basic mechanism used for: Transferring control between processes and OS Handling I/O and virtual memory within the OS Implementing multi-process apps like shells and web servers Implementing concurrency

27 Control Flow Processors do only one thing:
From startup to shutdown, a CPU simply reads and executes (interprets) a sequence of instructions, one at a time This sequence is the CPU’s control flow (or flow of control) <startup> instr1 instr2 instr3 instrn <shutdown> Physical control flow time

28 Altering the Control Flow
Up to now, two ways to change control flow: Jumps (conditional and unconditional) Call and return Both react to changes in program state Processor also needs to react to changes in system state Unix/Linux user hits “Ctrl-C” at the keyboard User clicks on a different application’s window on the screen Data arrives from a disk or a network adapter Instruction divides by zero System timer expires Can jumps and procedure calls achieve this? No – the system needs mechanisms for “exceptional” control flow!

29 This is extra (non-testable) material
Java Digression Java has exceptions, but they’re something different Examples: NullPointerException, MyBadThingHappenedException, … throw statements try/catch statements (“throw to youngest matching catch on the call-stack, or exit-with-stack-trace if none”) Java exceptions are for reacting to (unexpected) program state Can be implemented with stack operations and conditional jumps A mechanism for “many call-stack returns at once” Requires additions to the calling convention, but we already have the CPU features we need System-state changes on previous slide are mostly of a different sort (asynchronous/external except for divide-by- zero) and implemented very differently

30 Exceptional Control Flow
Exists at all levels of a computer system Low level mechanisms Exceptions Change in processor’s control flow in response to a system event (i.e. change in system state, user-generated interrupt) Implemented using a combination of hardware and OS software Higher level mechanisms Process context switch Implemented by OS software and hardware timer Signals Implemented by OS software We won’t cover these – see CSE451 and CSE/EE474

31 Exceptions An exception is transfer of control to the operating system (OS) kernel in response to some event (i.e. change in processor state) Kernel is the memory-resident part of the OS Examples: division by 0, page fault, I/O request completes, Ctrl-C How does the system know where to jump to in the OS? User Code OS Kernel Code exception event current_instr next_instr exception processing by exception handler, then: return to current_instr, return to next_instr, OR abort

32 Exception Table A jump table for exceptions (also called Interrupt Vector Table) Each type of event has a unique exception number 𝑘 𝑘 = index into exception table (a.k.a interrupt vector) Handler 𝑘 is called each time exception 𝑘 occurs code for exception handler 0 (Jump tables for switch statements: x86 Programming III slides) The book calls this an Exception table. I am using that at the top of the slide to be consistent with the book and with the previous slide. Exception Table code for exception handler 1 1 code for exception handler 2 2 ... n-1 ... Exception numbers code for exception handler n-1

33 Exception Table (Excerpt)
Exception Number Description Exception Class Divide error Fault 13 General protection fault 14 Page fault 18 Machine check Abort 32-255 OS-defined Interrupt or trap According to the book: Ones in gray are Intel-defined, Others are OS-defined Intel® 64 and IA-32 Architectures Software Developer's Manual, Volume 1: Basic Architecture - Describes the architecture and programming environment of processors supporting IA-32 and Intel 64 Architectures. “Systems often use an interrupt controller to group the device interrupts together before passing on the signal to a single interrupt pin on the CPU. This saves interrupt pins on the CPU…” This is why cat /proc/interrupts doesn’t match this slide - /proc/interrupts shows APIC’s “IRQ numbers”, not the OS’s exception numbers

34 Leading Up to Processes
System Control Flow Control flow Exceptional control flow Asynchronous exceptions (interrupts) Synchronous exceptions (traps & faults)

35 Asynchronous Exceptions (Interrupts)
Caused by events external to the processor Indicated by setting the processor’s interrupt pin(s) (wire into CPU) After interrupt handler runs, the handler returns to “next” instruction Examples: I/O interrupts Hitting Ctrl-C on the keyboard Clicking a mouse button or tapping a touchscreen Arrival of a packet from a network Arrival of data from a disk Timer interrupt Every few ms, an external timer chip triggers an interrupt Used by the OS kernel to take back control from user programs Also: Hard reset interrupt hitting the reset button on front panel Soft reset interrupt hitting Ctrl-Alt-Delete on a PC

36 Synchronous Exceptions
Caused by events that occur as a result of executing an instruction: Traps Intentional: transfer control to OS to perform some function Examples: system calls, breakpoint traps, special instructions Returns control to “next” instruction Faults Unintentional but possibly recoverable Examples: page faults, segment protection faults, integer divide-by-zero exceptions Either re-executes faulting (“current”) instruction or aborts Aborts Unintentional and unrecoverable Examples: parity error, machine check (hardware failure detected) Aborts current program

37 System Calls Each system call has a unique ID number
Examples for Linux on x86-64: Number Name Description read Read file 1 write Write file 2 open Open file 3 close Close file 4 stat Get info about file 57 fork Create process 59 execve Execute a program 60 _exit Terminate process 62 kill Send signal to process

38 Traps Example: Opening File
User calls open(filename, options) Calls __open function, which invokes system call instruction syscall e5d70 <__open>: ... e5d79: b mov $0x2,%eax # open is syscall 2 e5d7e: 0f syscall # return value in %rax e5d80: d 01 f0 ff ff cmp $0xfffffffffffff001,%rax e5dfa: c retq Note: on x86-64, syscall and sysret are used instead of int 0x80. Interrupt number 0x80 tells OS that this is a system call; to specify which system call, the system call’s number is stored in a register (%eax on IA32 Linux) before executing the int instruction. User code OS Kernel code %rax contains syscall number Other arguments in %rdi, %rsi, %rdx, %r10, %r8, %r9 Return value in %rax Negative value is an error corresponding to negative errno Exception syscall cmp Open file Returns

39 Fault Example: Page Fault
int a[1000]; int main () { a[500] = 13; } User writes to memory location That portion (page) of user’s memory is currently on disk Page fault handler must load page into physical memory Returns to faulting instruction: mov is executed again! Successful on second try 80483b7: c d d movl $0xd,0x8049d10 User code OS Kernel code Can SIGSEGV ever be handled without aborting? Yes, but program can’t really run afterwards: exception: page fault handle_page_fault: movl Create page and load into memory returns

40 Fault Example: Invalid Memory Reference
int a[1000]; int main() { a[5000] = 13; } 80483b7: c e d movl $0xd,0x804e360 Can SIGSEGV ever be handled without aborting? Yes, but program can’t really run afterwards: User Process OS exception: page fault handle_page_fault: movl detect invalid address signal process Page fault handler detects invalid address Sends SIGSEGV signal to user process User process exits with “segmentation fault”

41 Summary Exceptions Events that require non-standard control flow
Generated externally (interrupts) or internally (traps and faults) After an exception is handled, one of three things may happen: Re-execute the current instruction Resume execution with the next instruction Abort the process that caused the exception

42 Processes Processes and context switching Creating new processes
fork(), exec*(), and wait() Zombies

43 What is a process? It’s an illusion! Memory Stack Heap Data Code CPU
11/15/2017 What is a process? It’s an illusion! Process 1 Memory Stack Heap Code Data CPU Registers %rip Disk Chrome.exe

44 What is a process? Another abstraction in our computer system
11/15/2017 What is a process? Another abstraction in our computer system Provided by the OS OS uses a data structure to represent each process Maintains the interface between the program and the underlying hardware (CPU + memory) What do processes have to do with exceptional control flow? Exceptional control flow is the mechanism the OS uses to enable multiple processes to run on the same system What is the difference between: A processor? A program? A process? The data structure is the process control block (PCB).

45 Processes A process is an instance of a running program
11/15/2017 Processes A process is an instance of a running program One of the most profound ideas in computer science Not the same as “program” or “processor” Process provides each program with two key abstractions: Logical control flow Each program seems to have exclusive use of the CPU Provided by kernel mechanism called context switching Private address space Each program seems to have exclusive use of main memory Provided by kernel mechanism called virtual memory Memory Stack Heap Code Data CPU Registers

46 What is a process? It’s an illusion! Computer Process 3 Process 2
11/15/2017 What is a process? It’s an illusion! Computer Process 3 Process 2 “Memory” Stack Heap Code Data “Memory” Stack Heap Code Data Process 4 Process 1 “Memory” Stack Heap Code Data “CPU” Registers “CPU” Registers “Memory” Stack Heap Code Data “CPU” Registers CPU “CPU” Registers Disk /Applications/ Chrome.exe Slack.exe PowerPoint.exe

47 What is a process? It’s an illusion! Computer Process 3 Process 2
11/15/2017 What is a process? It’s an illusion! Computer Process 3 “Memory” Stack Heap Code Data “CPU” Registers Process 2 “Memory” Stack Heap Code Data “CPU” Registers Process 4 “Memory” Stack Heap Code Data “CPU” Registers Process 1 “Memory” Stack Heap Code Data “CPU” Registers CPU Operating System Disk /Applications/ Chrome.exe Slack.exe PowerPoint.exe

48 Multiprocessing: The Illusion
Memory Memory Memory Stack Stack Stack Heap Heap Heap Data Data Data Code Code Code CPU CPU CPU Registers Registers Registers Computer runs many processes simultaneously Applications for one or more users Web browsers, clients, editors, … Background tasks Monitoring network & I/O devices

49 Multiprocessing: The Reality
Memory Stack Stack Stack Heap Heap Heap Data Data Data Code Code Code Saved registers Saved registers Saved registers CPU Registers Single processor executes multiple processes concurrently Process executions interleaved, CPU runs one at a time Address spaces managed by virtual memory system (later in course) Execution context (register values, stack, …) for other processes saved in memory

50 Multiprocessing … Context switch Save current registers in memory
Stack Stack Stack Heap Heap Heap Data Data Data Code Code Code Saved registers Saved registers Saved registers CPU Registers Context switch Save current registers in memory

51 Multiprocessing … Context switch Save current registers in memory
Stack Stack Stack Heap Heap Heap Data Data Data Code Code Code Saved registers Saved registers Saved registers CPU Registers Context switch Save current registers in memory Schedule next process for execution

52 Multiprocessing … Context switch Save current registers in memory
Stack Stack Stack Heap Heap Heap Data Data Data Code Code Code Saved registers Saved registers Saved registers CPU Registers Context switch Save current registers in memory Schedule next process for execution Load saved registers and switch address space

53 Multiprocessing: The (Modern) Reality
Memory Stack Stack Stack Heap Heap Heap Data Data Data Code Code Code Saved registers Saved registers Saved registers CPU CPU Multicore processors Multiple CPUs (“cores”) on single chip Share main memory (and some of the caches) Each can execute a separate process Kernel schedules processes to cores Still constantly swapping processes Registers Registers

54 Concurrent Processes Each process is a logical control flow
11/15/2017 Concurrent Processes Assume only one CPU Each process is a logical control flow Two processes run concurrently (are concurrent) if their instruction executions (flows) overlap in time Otherwise, they are sequential Example: (running on single core) Concurrent: A & B, A & C Sequential: B & C Process A Process B Process C time

55 User’s View of Concurrency
11/15/2017 User’s View of Concurrency Assume only one CPU Control flows for concurrent processes are physically disjoint in time CPU only executes instructions for one process at a time However, the user can think of concurrent processes as executing at the same time, in parallel Process A Process B Process C time Process A Process B Process C User View

56 11/15/2017 Context Switching Assume only one CPU Processes are managed by a shared chunk of OS code called the kernel The kernel is not a separate process, but rather runs as part of a user process In x86-64 Linux: Same address in each process refers to same shared memory location

57 11/15/2017 Context Switching Assume only one CPU Processes are managed by a shared chunk of OS code called the kernel The kernel is not a separate process, but rather runs as part of a user process Context switch passes control flow from one process to another and is performed using kernel code Process A Process B user code Exception kernel code context switch time user code kernel code context switch user code

58 Processes Processes and context switching Creating new processes
fork() , exec*(), and wait() Zombies

59 Creating New Processes & Programs
“Memory” Stack Heap Code Data “CPU” Registers Process 2 “Memory” Stack Heap Code Data fork() “CPU” Registers exec*() Chrome.exe

60 Creating New Processes & Programs
11/15/2017 Creating New Processes & Programs fork-exec model (Linux): fork() creates a copy of the current process exec*() replaces the current process’ code and address space with the code for a different program Family: execv, execl, execve, execle, execvp, execlp fork() and execve() are system calls Other system calls for process management: getpid() exit() wait(), waitpid() Review: system calls are traps (intentional exception). “Microsoft Windows does not support the fork-exec model, as it does not have a system call analogous to fork(). The spawn() family of functions declared in process.h can replace it in cases where the call to fork() is followed directly by exec().”

61 fork: Creating New Processes
11/15/2017 fork: Creating New Processes pid_t fork(void) Creates a new “child” process that is identical to the calling “parent” process, including all state (memory, registers, etc.) Returns 0 to the child process Returns child’s process ID (PID) to the parent process Child is almost identical to parent: Child gets an identical (but separate) copy of the parent’s virtual address space Child has a different PID than the parent fork is unique (and often confusing) because it is called once but returns “twice” pid_t pid = fork(); if (pid == 0) { printf("hello from child\n"); } else { printf("hello from parent\n"); }

62 Understanding fork Process X (parent) Process Y (child)
11/15/2017 Understanding fork Process X (parent) Process Y (child) pid_t pid = fork(); if (pid == 0) { printf("hello from child\n"); } else { printf("hello from parent\n"); } pid_t pid = fork(); if (pid == 0) { printf("hello from child\n"); } else { printf("hello from parent\n"); }

63 Understanding fork Process X (parent) Process Y (child) pid = Y
11/15/2017 Understanding fork Process X (parent) Process Y (child) pid_t pid = fork(); if (pid == 0) { printf("hello from child\n"); } else { printf("hello from parent\n"); } pid_t pid = fork(); if (pid == 0) { printf("hello from child\n"); } else { printf("hello from parent\n"); } pid_t pid = fork(); if (pid == 0) { printf("hello from child\n"); } else { printf("hello from parent\n"); } pid_t pid = fork(); if (pid == 0) { printf("hello from child\n"); } else { printf("hello from parent\n"); } pid = Y pid = 0

64 Which one appears first?
11/15/2017 Understanding fork Process X (parent) Process Y (child) pid_t pid = fork(); if (pid == 0) { printf("hello from child\n"); } else { printf("hello from parent\n"); } pid_t pid = fork(); if (pid == 0) { printf("hello from child\n"); } else { printf("hello from parent\n"); } pid_t pid = fork(); if (pid == 0) { printf("hello from child\n"); } else { printf("hello from parent\n"); } pid_t pid = fork(); if (pid == 0) { printf("hello from child\n"); } else { printf("hello from parent\n"); } pid = Y pid = 0 hello from parent hello from child Which one appears first?

65 Fork Example Both processes continue/start execution after fork
11/15/2017 Fork Example void fork1() { int x = 1; pid_t pid = fork(); if (pid == 0) printf("Child has x = %d\n", ++x); else printf("Parent has x = %d\n", --x); printf("Bye from process %d with x = %d\n", getpid(), x); } Both processes continue/start execution after fork Child starts at instruction after the call to fork (storing into pid) Can’t predict execution order of parent and child Both processes start with x=1 Subsequent changes to x are independent Shared open files: stdout is the same in both parent and child

66 Modeling fork with Process Graphs
A process graph is a useful tool for capturing the partial ordering of statements in a concurrent program Each vertex is the execution of a statement a → b means a happens before b Edges can be labeled with current value of variables printf vertices can be labeled with output Each graph begins with a vertex with no inedges Any topological sort of the graph corresponds to a feasible total ordering Total ordering of vertices where all edges point from left to right

67 Fork Example: Possible Output
11/15/2017 Fork Example: Possible Output void fork1() { int x = 1; pid_t pid = fork(); if (pid == 0) printf("Child has x = %d\n", ++x); else printf("Parent has x = %d\n", --x); printf("Bye from process %d with x = %d\n", getpid(), x); } printf --x fork Child Bye x=1 ++x Parent x=2 x=0

68 Fork Example: Possible Output
11/15/2017 Fork Example: Possible Output void fork1() { int x = 1; pid_t pid = fork(); if (pid == 0) printf("Child has x = %d\n", ++x); else printf("Parent has x = %d\n", --x); printf("Bye from process %d with x = %d\n", getpid(), x); } printf --x fork Child Bye x=1 ++x Parent x=2 x=0

69 Peer Instruction Question
11/15/2017 Peer Instruction Question Are the following sequences of outputs possible? Seq 1: L0 L1 Bye L2 Seq 2: L0 Bye L1 L2 void nestedfork() { printf("L0\n"); if (fork() == 0) { printf("L1\n"); printf("L2\n"); } printf("Bye\n"); B No No No Yes Yes No Yes Yes We’re lost…

70 Note: the return values of fork and exec* should be checked for errors
11/15/2017 Fork-Exec Note: the return values of fork and exec* should be checked for errors fork-exec model: fork() creates a copy of the current process exec*() replaces the current process’ code and address space with the code for a different program Whole family of exec calls – see exec(3) and execve(2) man 3 exec man 2 execve - v is for “vector” (of arguments), e is for “environment” Note: the return values of fork() and execv() should be checked for errors! // Example arguments: path="/usr/bin/ls", // argv[0]="/usr/bin/ls", argv[1]="-ahl", argv[2]=NULL void fork_exec(char *path, char *argv[]) { pid_t pid = fork(); if (pid != 0) { printf("Parent: created a child %d\n", pid); } else { printf("Child: about to exec a new program\n"); execv(path, argv); } printf("This line printed by parent only!\n");

71 11/15/2017 Exec-ing a new program Stack Code: /usr/bin/bash Data Heap Very high-level diagram of what happens when you run the command “ls” in a Linux shell: This is the loading part of CALL! DEMO: ps -ef and pstree. fork() parent child child Stack Code: /usr/bin/bash Data Heap Stack Code: /usr/bin/bash Data Heap Stack Code: /usr/bin/ls Data exec*()

72 This is extra (non-testable) material
11/15/2017 This is extra (non-testable) material execve Example Execute "/usr/bin/ls –l lab4" in child process using current environment: myargv[argc] = NULL myargv[2] myargv[1] myargv[0] (argc == 3) "lab4" "-l" "/usr/bin/ls" myargv envp[n] = NULL envp[n-1] ... envp[0] "PWD=/homes/iws/jhsia" "USER=jhsia" environ if ((pid = fork()) == 0) { /* Child runs program */ if (execve(myargv[0], myargv, environ) < 0) { printf("%s: Command not found.\n", myargv[0]); exit(1); } Run the printenv command in a Linux shell to see your own environment variables

73 Structure of the Stack when a new program starts
11/15/2017 Bottom of stack Structure of the Stack when a new program starts Null-terminated environment variable strings Null-terminated command-line arg strings envp[n] == NULL envp[n-1] environ (global var) ... envp[0] argv[argc] = NULL envp (in %rdx) argv[argc-1] ... argv (in %rsi) argv[0] Stack frame for libc_start_main argc (in %rdi) Top of stack This is extra (non-testable) material Future stack frame for main

74 exit: Ending a process void exit(int status)
11/15/2017 exit: Ending a process void exit(int status) Explicitly exits a process Status code: 0 is used for a normal exit, nonzero for abnormal exit The return statement from main() also ends a process in C The return value is the status code exit(3) and atexit(3) have more details.

75 Summary Processes Process management
11/15/2017 Summary Processes At any given time, system has multiple active processes On a one-CPU system, only one can execute at a time, but each process appears to have total control of the processor OS periodically “context switches” between active processes Implemented using exceptional control flow Process management fork: one call, two returns execve: one call, usually no return wait or waitpid: synchronization exit: one call, no return

76 BONUS SLIDES Detailed examples: Consecutive forks CSE 351 Lecture 6
11/15/2017 BONUS SLIDES Detailed examples: Consecutive forks

77 Example: Two consecutive forks
11/15/2017 Example: Two consecutive forks printf fork Bye L0 L1 void fork2() { printf("L0\n"); fork(); printf("L1\n"); printf("Bye\n"); } Forks.c Feasible output: L0 L1 Bye Infeasible output: L0 Bye L1

78 Example: Three consecutive forks
11/15/2017 Example: Three consecutive forks Both parent and child can continue forking void fork3() { printf("L0\n"); fork(); printf("L1\n"); printf("L2\n"); printf("Bye\n"); } L1 L2 Bye L0


Download ppt "System Control Flow, Processes CSE 351 Winter 2019"

Similar presentations


Ads by Google