9/15/15 CS 422/522 Design & Implementation of Operating Systems Lecture 4:The Programming Interface Zhong Shao Dept. of Computer Science Yale University Acknowledgement: some slides are taken from previous versions of the CS422/522 lectures taught by Prof. Bryan Ford and Dr. David Wolinsky, and also from the official set of slides accompanying the OSPP textbook by Anderson and Dahlin. The programming interface Compilers Web Servers Source Code Control Databases Word Processing Web Browsers Email Portable OS Library System Call Interface Portable Operating System Kernel x86 ARM PowerPC 10Mbps/100Mbps/1Gbps Ethernet 802.11 a/b/g/n Graphics Accelerators SCSI IDE LCD Screens 1 9/15/15 Abstraction: process & file system ◆ Problem – Multiple CPU cores, many I/O devices and lots of interrupts – Users feel they have machine to themselves ◆ Answer – – – – ◆ Decompose hard problems into simple ones Deal with one at a time Process is such a unit (reflecting something dynamic) File system is another high-level abstraction (for “data”) Future – How processes differ from threads? What is a process really? – Generalizing “processes” to “containers” & “virtual machines” Simplest process ◆ Sequential execution – No concurrency inside a process – Everything happens sequentially – Some coordination may be required ◆ Process state – Registers – Main memory – I/O devices * File system * Communication ports 2 9/15/15 Program vs. process main() { ... foo() ... } main() { ... foo() ... } foo() { ... } foo() { ... } Program heap stack main foo registers PC Process Program vs. process (cont’d) ◆ Process > program – Program is just part of process state – Example: many users can run the same program (but different processes) ◆ Process < program – A program can invoke more than one process – Example: cc starts up cpp, cc1, cc2, as, ld (each are programs themselves) 3 9/15/15 Shell ◆ A shell is a job control system – Allows programmer to create and manage a set of programs to do some task – Windows, MacOS, Linux all have shells ◆ Example: to compile a C program cc –c sourcefile1.c cc –c sourcefile2.c ln –o program sourcefile1.o sourcefile2.o Question ◆ If the shell runs at user-level, what system calls does it make to run each of the programs? – Ex: cc, ln 4 9/15/15 Process control block (PCB) ◆ Process management info – State * Ready: ready to run * Running: currently running * Blocked: waiting for resources – Registers, EFLAGS, and other CPU state – Stack, code and data segment – Parents, etc ◆ Memory management info ◆ I/O and file management ◆ How OS takes care of processes – Segments, page table, stats, etc – Communication ports, directories, file descriptors, etc. – Resource allocation and process state transition Primitives of processes ◆ Creation and termination – Exec, Fork, Wait, Kill ◆ Signals – Action, Return, Handler ◆ Operations – Block, Yield ◆ Synchronization – We will talk about this later 5 9/15/15 Make a process ◆ Creation – – – – ◆ Load code and data into memory Create an empty call stack Initialize state to same as after a process switch Make the process ready to run Clone – Stop current process and save state – Make copy of current code, data, stack and OS state – Make the process ready to run Windows CreateProcess ◆ System call to create a new process to run a program – Create and initialize the process control block (PCB) in the kernel – Create and initialize a new address space – Load the program into the address space – Copy arguments into memory in the address space – Initialize the hardware context to start execution at ``start'’ – Inform the scheduler that the new process is ready to run 6 9/15/15 Windows CreateProcess API (simplified) if (!CreateProcess( NULL, // No module name (use command line) argv[1], // Command line NULL, // Process handle not inheritable NULL, // Thread handle not inheritable FALSE, // Set handle inheritance to FALSE 0, // No creation flags NULL, // Use parent's environment block NULL, // Use parent's starting directory &si, // Pointer to STARTUPINFO structure &pi ) // Pointer to PROCESS_INFORMATION structure ) UNIX process management ◆ UNIX fork – system call to create a copy of the current process, and start it running – No arguments! ◆ ◆ ◆ UNIX exec – system call to change the program being run by the current process UNIX wait – system call to wait for a process to finish UNIX signal – system call to send a notification to another process 7 9/15/15 UNIX process management fork pid = fork(); if (pid == 0) exec(...); else wait(pid); exec main () { ... } pid = fork(); if (pid == 0) exec(...); else wait(pid); pid = fork(); if (pid == 0) exec(...); else wait(pid); wait Question: What does this code print? int child_pid = fork(); if (child_pid == 0) { // I'm the child process printf("I am process #%d\n", getpid()); return 0; } else { // I'm the parent process printf("I am parent of process #%d\n", child_pid); return 0; } 8 9/15/15 Implementing UNIX fork Steps to implement UNIX fork – Create and initialize the process control block (PCB) in the kernel – Create a new address space – Initialize the address space with a copy of the entire contents of the address space of the parent – Inherit the execution context of the parent (e.g., any open files) – Inform the scheduler that the new process is ready to run Implementing UNIX exec ◆ Steps to implement UNIX fork – Load the program into the current address space – Copy arguments into memory in the address space – Initialize the hardware context to start execution at ``start'' 9 9/15/15 Process context switch ◆ Save a context (everything that a process may damage) – – – – ◆ All registers (general purpose and floating point) All co-processor state Save all memory to disk? What about cache and TLB stuff? Very machine dependent ! Start a context – Does the reverse ◆ Challenges – OS code must save state without changing any state – How to run without touching any registers? * CISC machines have a special instruction to save and restore all registers on stack * RISC: reserve registers for kernel or have way to carefully save one and then continue Process state transition Terminate or Finish or it f ce Wa sour Re Sleep or Running Create a process Ready Running: executing now Ready: waiting for CPU Blocked: waiting for I/O or lock Blocked Resource becomes available 10 9/15/15 Which ready process to pick? 0 ready processes: run idle loop 1 ready process: easy! > 1: what to do? ◆ FIFO? – put threads on back of list, pull them off from front – (nachos does this: schedule.cc) ◆ ◆ Pick random? (could result in starvation) Priority? – give some threads a better shot at the CPU Scheduling policies ◆ Scheduling issues – – – – ◆ fairness: don’t starve process prioritize: more important first deadlines: must do by time ‘x’ (car brakes) optimization: some schedules >> faster than others No universal policy: – many variables, can’t maximize them all – conflicting goals * more important jobs vs starving others * I want my job to run first, you want yours. ◆ Given some policy, how to get control ? 11 9/15/15 How to get control? ◆ Traps: events generated by current process – system calls – errors (illegal instructions) – page faults ◆ Interrupts: events external to the process – I/O interrupt – timer interrupt (every 100 milliseconds or so) ◆ Process perspective: – explicit: process yields processor to another – implicit: causes an expensive blocking event, gets switched UNIX I/O --- a key innovation (“files”) ◆ Uniformity – All operations on all files, devices use the same set of system calls: open, close, read, write ◆ Open before use – Open returns a handle (file descriptor) for use in later calls on the file ◆ ◆ ◆ Byte-oriented Kernel-buffered reads/writes Explicit close – To garbage collect the open file descriptor ◆ Pipes (for interprocess communication à a kernel buffer with two file descriptors, one for reading, one for writing) 12 9/15/15 UNIX file system interface ◆ UNIX file open is a Swiss Army knife: – Open the file, return file descriptor – Options: * * * * * * * if file doesn’t exist, return an error If file doesn’t exist, create file and open it If file does exist, return an error If file does exist, open file If file exists but isn’t empty, nix it then open If file exists but isn’t empty, return an error … Interface design question ◆ Why not separate syscalls for open/create/exists? if (!exists(name)) create(name); // can create fail? fd = open(name); // does the file exist? 13 9/15/15 Implementing a shell char *prog, **args; int child_pid; // Read and parse the input a line at a time while (readAndParseCmdLine(&prog, &args)) { child_pid = fork(); // create a child process if (child_pid == 0) { exec(prog, args); // I'm the child process. Run program // NOT REACHED } else { wait(child_pid); // I'm the parent, wait for child return 0; } } 14