<<

2/21/20

COMP 790: OS Implementation COMP 790: OS Implementation Housekeeping Signals and Inter- • Paper reading assigned for next class Communication

Don Porter

1 2 1 2

COMP 790: OS Implementation COMP 790: OS Implementation Logical Diagram Last … Binary Memory • We’ve discussed how the OS schedules the CPU Threads Formats Allocators User – And how to block a process on a resource (disk, network) Today’s Lecture System Calls Kernel Process • Today: RCU FileCoordination System Networking Sync – How do processes block on each other? – And generally communicate? Memory Device CPU Management Drivers Scheduler

Hardware Disk Net Consistency

3 4 3 4

COMP 790: OS Implementation COMP 790: OS Implementation Outline What is a ? • Signals • Like an , but for applications – Overview and – <64 numbers with specific meanings – Handlers – A process can raise a signal to another process or – Kernel-level delivery – A process or thread registers a handler function – Interrupted system calls • For both IPC and delivery of hardware exceptions • Interprocess Communication (IPC) – Application-level handlers: divzero, segfaults, etc. – Pipes and FIFOs • No “message” beyond the signal was raised – System V IPC – And maybe a little metadata – Windows Analogs • PID of sender, faulting address, etc. • But platform-specific (non-portable)

5 6 5 6

1 2/21/20

COMP 790: OS Implementation COMP 790: OS Implementation Example Example

Pid 300 Pid 300 Pid 400

main() { int main() { ...... PC signal(SIGUSR1, &usr_handler); } (300, SIGUSR1); ... } int usr_handler() { …

Register usr_handler() to handle SIGUSR1 7 Send signal to PID 300 8 7 8

COMP 790: OS Implementation COMP 790: OS Implementation Basic Model Signal Types • Application registers handlers with signal or sigaction • See man 7 signal for the full list: (varies by sys/arch) • Send signals with kill and friends SIGTSTP – 1 – Stop typed terminal (Ctrl+Z) – Or raised by hardware exception handlers in kernel SIGKILL – 9 – Kill a process, for realzies • Signal delivery jumps to signal handler SIGSEGV – 11 – – Irregular , similar to an interrupt SIGPIPE – 13 – Broken pipe ( with no readers) SIGALRM – 14 – Timer SIGUSR1 – 10 – User-defined signal 1 SIGCHLD – 17 – Child stopped or terminated SIGSTOP – 19 – Stop a process SIGCONT – 18 – Continue if stopped

API names are admittedly confusing 9 10 9 10

COMP 790: OS Implementation COMP 790: OS Implementation Language Exceptions Signal Handler Control Flow • Signals are the underlying mechanism for Exceptions and catch blocks • JVM or other runtime system sets signal handlers – Signal handler causes execution to jump to the catch block

11 From Understanding the Kernel 12 11 12

2 2/21/20

COMP 790: OS Implementation COMP 790: OS Implementation Alternate Stacks Nested Signals • Signal handlers execute on a different stack than • What happens when you get a signal in the signal program execution. handler? – Why? • And why should you care? • Safety: App can ensure stack is actually mapped – And avoid assumptions about application not using space below rsp – Set with sigaltstack() • Like an interrupt handler, kernel pushes register state on interrupt stack – Return to kernel with sigreturn() system call – App can change its own on-stack register state!

13 14 13 14

COMP 790: OS Implementation COMP 790: OS Implementation The Problem with Nesting Nested Signals int main() { • The original signal() specification was a total mess! /* ... */ – Now deprecated---do not use! Another signal signal(SIGINT, &handler); • New sigaction() API lets you specify this in detail Double free! delivered on signal(SIGTERM, &handler); return – What signals are blocked (and delivered on sigreturn) /* ... */ PC Calls – Similar to disabling hardware interrupts munmap() } Signal Stack • As you might guess, blocking system calls inside of a int handler() { SIGINT signal handler are only safe with careful use of

free(buf1); SIGTERM sigaction() free(buf2); }

15 16 15 16

COMP 790: OS Implementation COMP 790: OS Implementation Application vs. Kernel Example • App: signals appear to be delivered roughly Mark pending immediately … Pid 300 10 signal, • Kernel (lazy): Pid 300 … Pid 400 RUNNINGINTERRUPTIBLE Block onunblock disk – Send a signal == mark a pending signal in the task ! • And runnable if blocked with TASK_INTERRUPTIBLE flag – Check pending signals on return from interrupt or syscall int main() { • Deliver if pending What happens read(); PC to read? } kill(300, SIGUSR1);

int usr_handler() { …

17 Send signal to PID 300 18 17 18

3 2/21/20

COMP 790: OS Implementation COMP 790: OS Implementation Interrupted System Calls Default handlers • If a system call blocks in the INTERRUPTIBLE state, a • Signals have default handlers: signal wakes it up – Ignore, kill, suspend, continue, core • Yet signals are delivered on return from a system call – These execute inside the kernel • How is this resolved? • Installing a handler with signal/sigaction overrides • The system call fails with a special error code the default – EINTR and friends • A few (SIGKILL) cannot be overridden – Many system calls transparently retry after sigreturn – Some do not – check for EINTR in your applications!

19 20 19 20

COMP 790: OS Implementation COMP 790: OS Implementation RT Signals Signal Summary • Default signals are only in 2 states: signaled or not • Abstraction like hardware interrupts – If I send 2 SIGUSR1’s to a process, only one may be – Some care must be taken to block other signals delivered – Easy to write buggy handlers and miss EINTR – If system is slow and I furiously hit Ctrl+C over and over, • Understand control flow from application and kernel only one SIGINT delivered perspective • Real time (RT) signals keep a count • Understand basic APIs – Deliver one signal for each one sent

21 22 21 22

COMP 790: OS Implementation COMP 790: OS Implementation Other IPC Pipes • Pipes, Sockets, and FIFOs • Stream of bytes between two processes • System V IPC • Read and write like a handle • Windows comparison – But not anywhere in the hierarchical file system – And not persistent – And no cursor or seek()-ing – Actually, 2 handles: a read handle and a write handle • Primarily used for parent/child communication – Parent creates a pipe, child inherits it

23 24 23 24

4 2/21/20

COMP 790: OS Implementation COMP 790: OS Implementation Example FIFOs (aka Named Pipes) int pipe_fd[2]; • Existing pipes can’t be opened---only inherited int rv = pipe(pipe_fd); int pid = fork(); – Or passed over a Domain Socket (beyond today’s lec) if (pid == 0) { • FIFOs, or Named Pipes, add an interface for opening (pipe_fd[1]); //Close unused write end dup2(pipe_fd[0], 0); // Make the read end stdin existing pipes exec(“”, “quack”); } else { close (pipe_fd[0]); // Close unused read end …

25 26 25 26

COMP 790: OS Implementation COMP 790: OS Implementation Sockets Select • Similar to pipes, except for network connections • What if I want to block until one of several handles • Setup and connection management is a bit trickier has data ready to read? – A topic for another day (or class) • Read will block on one handle, but perhaps miss data on a second… • Select will block a process until a handle has data available – Useful for applications that use pipes, sockets, etc.

27 28 27 28

COMP 790: OS Implementation COMP 790: OS Implementation Synthesis Example: The Shell Shell Example • Almost all ‘commands’ are really binaries • : | grep foo – /bin/ls • Implementation sketch: • Key abstraction: Redirection over pipes – Shell parses the entire string – ‘>’, ‘<‘, and ‘|’implemented by the shell itself – Sets up chain of pipes – Forks and exec’s ‘ls’ and ‘grep’ separately – on output from ‘grep’, print to console

29 30 29 30

5 2/21/20

COMP 790: OS Implementation COMP 790: OS Implementation in a shell Other hints • Shell keeps its own “scheduler” for background processes • Splice(), (), and similar calls are useful for • How to: connecting pipes together – Put a process in the background? – Avoids copying data into and out-of application • SIGTSTP handler catches Ctrl-Z • Send SIGSTOP to current foreground child – Resume execution (fg)? • Send SIGCONT to paused child, use waitpid() to block until finished – Execute in background (bg)? • Send SIGCONT to paused child, but block on terminal input

31 32 31 32

COMP 790: OS Implementation COMP 790: OS Implementation System V IPC System V Keys and IDs • Semaphores – Lock • Programmers pick arbitrary 32-bit keys • Message Queues – Like a box, “small” messages – Use these keys to name shared abstractions • – particularly useful • a key using shmget(), msgget(), etc. – A region of non-COW anonymous memory – Kernel internally maps key to a 32-bit ID – Map at a given address using shmat() • Can persist longer than an application – Must be explicitly deleted – Can leak at system level – But cleared after a reboot

33 34 33 34

COMP 790: OS Implementation COMP 790: OS Implementation Windows Comparison Summary • Hardware exceptions are treated separately from IPC • Understand signals – Upcalls to ntdll.dll (libc equivalent), to call handlers • Understand high-level properties of pipes and other • All IPC types can be represented as handles Unix IPC abstractions – Process termination/suspend/resume signaled with – High-level comparison with Windows process handles – Signals can be an handle – Semaphores and Mutexes have handles – Shared memory equally complicated (but still handles) • Single select()-like API to wait on a handle to be signaled

35 36 35 36

6