Processes and Exceptions int main( void ) { doing nothing on a busy system 3 } output_timings(times); 1 end = get_time(); /* do nothing */ start = get_time(); long start, end; for ( int i = 0; i < N; ++i) { } long times[NUM_TIMINGS]; /* waste CPU time */ timing nothing an infjnite loop int main( void ) { while (1) { 4 } } If I run this on a lab machine, can you still use it? …even if the machine only has one core? 2 time for empty loop body 10 8 10 7 10 6 time (ns) 10 5 10 4 times[i] = end − start; 10 3 10 2 10 1 0 200000 400000 600000 800000 1000000 same instructions — same difgerence each time? sample #
doing nothing on a busy system time multiplexing loop.exe ssh.exe CPU: time ... call get_time // whatever get_time does movq %rax, %rbp million cycle delay call get_time // whatever get_time does subq %rbp, %rax ... 6 loop.exe ssh.exe // whatever get_time does ... subq %rbp, %rax // whatever get_time does call get_time million cycle delay movq %rax, %rbp call get_time ssh.exe ... time CPU: ssh.exe loop.exe firefox.exe firefox.exe loop.exe 6 time 5 time multiplexing loop.exe time multiplexing firefox.exe loop.exe ssh.exe CPU: ssh.exe ... // whatever get_time does movq %rax, %rbp million cycle delay call get_time // whatever get_time does subq %rbp, %rax ... 6 call get_time time for empty loop body 10 8 10 7 10 6 time (ns) 10 5 10 4 10 3 10 2 10 1 0 200000 400000 600000 800000 1000000 sample #
illusion: dedicated processor time multiplexing: illusion of dedicated processor saved information called context sets new registers, jumps to new program counter saves old program counter, registers somewhere starts running instead of normal program OS and time multiplexing 8 return from exception exception happens = operating system ssh.exe loop.exe firefox.exe ssh.exe loop.exe time multiplexing really ssh.exe including dedicated registers illusion is perfect — except for performance 7 time multiplexing really 8 loop.exe firefox.exe loop.exe ssh.exe = operating system exception happens return from exception 9 sometimes called a thread mechanism for this: exceptions (later) called context switch
context SF %raxSF %rbxZF %rcxPC … … in Memory 12 contexts (B running) %rax %rbx %rcx %rsp … ZF code, stack, etc. PC in CPU Process A memory: code, stack, etc. Process B memory: code, stack, etc. OS memory: %raxSF %rbxZF %rcxPC … … in Memory OS memory: Process B memory: all registers values 11 condition codes program counter i.e. all visible state in your CPU except memory address space: map from program to real addresses 10 context switch pseudocode context_switch(last, next): ... code, stack, etc. 13 contexts (A running) %rsp Process A memory: in CPU %rbx PC %rcx ZF SF … %rax copy_preexception_pc last − >pc %rax %rbx , …, %rsp , … mov rax,last − >rax mov rcx, last − >rcx mov rdx, last − >rdx mov next − >rdx, rdx mov next − >rcx, rcx mov next − >rax, rax jmp next − >pc
memory protection 15 14 Recall: program memory 0xFFFF FFFF FFFF FFFF 0xFFFF 8000 0000 0000 0x7F… 0x0000 0000 0040 0000 Used by OS Stack Heap / other dynamic Writable data Code + Constants program memory (two programs) result: %rax is 42 (always) Used by OS Program A Stack Heap / other dynamic Writable data Code + Constants Used by OS Program B Stack Heap / other dynamic Writable data Code + Constants result: might crash ... reading from another program’s memory? result: %rax is 42 (always) Program A Program B 0x10000: .word 42 // ... // do work // ... movq 0x10000, %rax // while A is working: movq $99, %rax movq %rax, 0x10000 ... result: might crash movq %rax, 0x10000 14 memory protection reading from another program’s memory? Program A Program B 0x10000: .word 42 // ... // do work // ... movq 0x10000, %rax // while A is working: movq $99, %rax 16
address space Program A code 18 address space programs have illusion of own memory called a program’s address space Program A addresses Program B addresses mapping (set by OS) mapping (set by OS) Program B code Writable data Program A data Program B data OS data … real memory trigger error = kernel-mode only 19 address space mechanisms next week’s topic called virtual memory mapping called page tables mapping part of what is changed in context switch Code + Constants Heap / other dynamic programs have illusion of own memory OS data called a program’s address space Program A addresses Program B addresses mapping (set by OS) mapping (set by OS) Program A code Program B code Program A data Program B data … Stack real memory trigger error = kernel-mode only 17 program memory (two programs) Used by OS Program A Stack Heap / other dynamic Writable data Code + Constants Used by OS Program B 20
context firefox.exe keeps our infjnite loop from running forever example: from timer expiring usually from user programs to the OS but often not requested by the program similar efgect to function call special control transfer exceptions 23 return from exception exception happens = operating system ssh.exe loop.exe ssh.exe all registers values loop.exe time multiplexing really 22 address space = illusion of own memory thread = illusion of own CPU illusion of dedicated machine: process = thread(s) + address space The Process 21 address space: map from program to real addresses i.e. all visible state in your CPU except memory program counter condition codes 24 %rax %rbx , …, %rsp , …
types of exceptions system calls — ask OS to do something I/O devices — key presses, hard drives, networks, … faults — errors/events in programs memory not in address space (“Segmentation fault”) divide by zero invalid instruction traps — intentionally triggered exceptions aborts interrupts — externally-triggered 27 protection fault when program tries to access memory it doesn’t own e.g. trying to write to bad address OS gets control — can crash the program or more interesting things timer — keep program from hogging CPU types of exceptions interrupts — externally-triggered traps — intentionally triggered exceptions timer — keep program from hogging CPU I/O devices — key presses, hard drives, networks, … faults — errors/events in programs memory not in address space (“Segmentation fault”) divide by zero invalid instruction system calls — ask OS to do something 26 aborts 25 timer interrupt (conceptually) external timer device OS confjgures before starting program sends signal to CPU after a fjxed interval 28
synchronous versus asynchronous handle_divide_by_zero: … … base + 0x40 … … exception table (in memory) exception table base register movq %rax, save_rax base + 0x10 movq %rbx, save_rbx ... handle_timer_interrupt: movq %rax, save_rax movq %rbx, save_rbx ... … … … base + 0x18 base + 0x08 synchronous — triggered by a particular instruction base + 0x00 particular mov instruction asynchronous — comes from outside the program timer event keypress, other input event 29 exception implementation detect condition (program error or external event) save current value of PC somewhere jump done without program instruction to do so 30 exception implementation: notes I/textbook describe a simplifjed version real x86/x86-64 is a bit more complicated (mostly for historical reasons) 31 locating exception handlers address pointer 32 jump to exception handler (part of OS)
running the exception handler 35 new instruction: set exception table base new logic: jump based on exception table new logic: save the old PC to special register or to memory new instruction: return from exception i.e. jump to saved PC added to CPU for exceptions 34 new instruction: set exception table base new logic: jump based on exception table new logic: save the old PC to special register or to memory new instruction: return from exception i.e. jump to saved PC added to CPU for exceptions return_from_exception hardware saves the old program counter 2. do work to handle exception identifjes location of exception handler via table then jumps to that location OS code can save registers, etc., etc. 33 exception handler structure 1. save process’s state somewhere 3. restore a process’s state (maybe a difgerent one) mov_to_saved_pc new_pc 4. jump back to program handle_timer_interrupt: mov_from_saved_pc save_pc_loc movq %rax, save_rax_loc ... // choose new process to run here movq new_rax_loc, %rax 35
added to CPU for exceptions my_exception_table: ... ... set_address_space ssh_address_space mov_to_saved_pc saved_ssh_pc return_from_exception 37 defeating time slices? ... timer interrupt my_handle_timer_interrupt: // HA! Keep running me! return_from_exception main: set_exception_table_base my_exception_table loop: jmp loop handle_timer_interrupt: exception table lookup new instruction: set exception table base not just ret — can’t modify process’s stack new logic: jump based on exception table to special register or to memory new instruction: return from exception i.e. jump to saved PC 35 why return from exception? would break the illusion of dedicated CPU ssh.exe reasons related to address spaces, protection (later) 36 exceptions and time slicing loop.exe ssh.exe firefox.exe loop.exe 38 new logic: save the old PC
Recommend
More recommend