Lecture Notes for Monday, 1/24 By Scott Monasch and Xue (Cindy) Song Two readers: basic reader(~$25) and NACHOS reader(~$13) will be available in two weeks at Copy Central on Euclid. The Thur 3-4pm discussion is rescheduled to Thur 5-6pm. Topic 1: Intro to Processes; Dispatching (Ch 3.1-3.3) Operating system (simplified definition): Software which schedules tasks, allocates storage, and presents a default interface to the user between applications. We can divide the operating system into 2 basic functionalities: -Coordinator: This layer implements the illusion of each user having the whole computer to themselves. (In fact, each process has this illusion- more to come later) -The coordinator can be divided into 2 functions: -Resource allocation & management: This is all we would need if the computer was in fact running one process at a time -provide access to memory, files, I/O devices, etc. -swap one process out and the next one in -Sharing and protection: We need this because the computer actually runs multiple processes concurrently -sharing: CPU, memory, access to files, etc. Coordinate so each user appears to have the entire system to themselves. Also includes deadlock prevention (make sure no 2 processes are waiting for each other to finish), and networks (groups of workstations can work together) -protection: Do not allow one process to interfere with another's state, do not allow wrong users to access files. -"Extended machine": presents a default interface and provides standard facilities that the user needs. Without the OS the computer would just implement "POO" (principles of operation), meaning basically it's a box that can do calculations. Added functionality includes: -file system -I/O -multiple processes with scheduling -virtual memory Process: An instance of a running program, along with its address space and resources -Analogy: a program is like the script of a play. It is the static set of instructions to perform. A process is like the performance of the play, the actual execution of the instructions, which affects and is affected by the state of the surroundings. -Execution stream: a sequence of instructions performed by a process -Process state: The local state which may affect or be affected by a process (i.e. code, data values, open files, etc.) -Each instance of a program running creates a new process -One program can generate many processes The Illusion: each process is the only one running, and has the entire machine's resources to work with. -Why?: -Break down a task into manageable pieces. It is much easier and less error prone to abstract away the details of what is happening on a lower level, than to have each process be aware of all the other processes. -How?: -Share the CPU, to give the illusion of multiple processors -Store memory to disk if necessary, to give each process the illusion of having the entire memory -Provide each user the illusion of having their own file system, I/O devices, etc. -Why allow multiple processes to run concurrently (multiprogramming)?: -Some do not (uniprogramming). But this makes it hard to have background tasks running while you are working on something else Process Control Block (PCB): Stores the information necessary to be known about a process -The CPU must rapidly switch between processes. -When switching to a new process, we must save the state of the old one, and load the state of the new one -The state is stored in the PCB, and the system stores all the PCBs in the process table -Contents of a PCB: -Program counter -Processor status word (PSW): Pointer to virtual memory system, flag bits indicating status (e.g. interrupt status) -General purpose registers -Floating-point registers -Process ID (Each process is given a unique ID) -Pointer to the memory info -Scheduling information (elapsed time, when last run, etc.) -Pointers to information about open files, file descriptors, etc. -Accounting information -Other miscellaneous information (depends on the OS) CPU sharing: in order to work, the OS must synchronize processes properly: -Allow each process to run (not wait indefinitely) -Protect processes from modifying each other's state Dispatcher/Scheduler: *key part of the OS* -manages which processes run when -Scheduler: decides which process to run -Dispatcher: initiates the process -Dispatcher function: usually runs this loop: -run process for a while -save state -load state of next process -run it... The scheduling problem: 2 questions -How to decide what is the "best" process to run next? -What are the criteria? -Must be quick (if the OS makes very good decisions but takes a long time, the performance still suffers) -How does the OS regain control of the processor? -Sleeping Beauty approach: hope the process wakes the OS when complete -bad idea: OS does not have control in this approach, process may not do what it's supposed to -Alarm clock: interrupt the process at some point and take control -good idea: makes sure the OS regains control How to INTERRUPT a process? -If the CPU is running a process, it is not running OS code. So how does the OS regain control? -Answer: EIT EIT: Exceptions, Interrupts and Traps -These types of events all wake the OS up, so it can decide what to do next -Traps: -These are synchronous events, meaning they are caused by the execution of a process. -eg: page fault, divide by zero, SVC, physical memory error, out of bounds addressing, hardware error, illegal instruction -Interrupts: -These are asynchronous events, meaning they arise from a source external to the process. -eg: I/O device signals that it is done, OS timer expires -Useful for I/O devices: The device can do its own computation and signify when it is ready, while in the meantime the CPU does other work, instead of sitting idle waiting for the I/O device to finish -Difficult to program: Programs must run correctly even if they are interrupted. But an interrupt may occur at any time, during any process. So how can the OS make sure that an interrupt doesn't destroy the work that was interrupted? What happens if many interrupts occur at the same time? -Exceptions: -refers to both interrupts and traps -"Exception" as opposed to "normal": These events are relatively rare and are not part of the normal expected run of the process. Timer: A timer is what the OS uses as its "alarm clock" to regain control. There are 3 basic types: -Periodic: e.g. 60 times/second. -Bad: If the frequency is too low, there will be lots of idle time between interrupts. If it is too high, there will be a high overhead from all the interrupts -Time of day: interrupt when timer = TOD (time of day) clock -When a process starts, pick an absolute time to stop it -Elapsed Time (interval timer): interrupt when timer decrements to zero. -Same idea as the TOD clock Switching contexts between user and OS: -After an exception, control goes to the OS, so we need to switch to the OS context -Tricky: The OS needs to save and restore state information whenever switching processes. But in order to run the code to do that, it must be in its own state. How to keep everything intact? -Hardware support: There must be special hardware to load all the necessary state information at once. If it was done in code, it would have to be one piece at a time, and the state would be changing as the code was running. -General procedure: Hardware saves the essentials of the state, including the PC (position in the code) and PSW (mode bit, address space pointer, protection info). Then looks up the proper routine to run from a trap/interrupt table Creating a process 1. from scratch: - Create (empty) call stack. - Create and initialize process control block (or reuse existing one). - Load code and data into memory. - Make process known to dispatcher - put it on some list of processes. 2. Make a copy of an existing process - "forking" a process - For example, the shell makes a copy of itself for each command. One waits around, the other goes off and executes the command. Each process is given a new process ID (no duplicates) Three steps to Unix fork: - (1) Allocate and initialize new PROC structure for the child process. (Give it a new process ID.) - (2) Duplicate the context of the parent process (including the user structure and virtual memory resources) for the child. - Child process gets open files, signal state, the scheduling parameters, disk quota info. - (3) Schedule the child process to run. What's missing? -The new process is still a duplicate of the old one -In Unix, after the process is duplicated, a different program is copied into its memory. -Improvement: VFORK - doesn't copy the original process before overlaying the new one. Saves a copy operation. TOPIC: CPU SCHEDULING The OS makes 2 kinds of decisions about resources: -Allocation: -Decide which processes get which resources. -Occurs before the processes are run, because the resources are not easily preemptible -Goal: Make the most efficient use of resources, while avoiding deadlock -Scheduling: -Providing preemptible resources (usually CPU and memory) -Occurs while processes are running. Inovlves choosing their order and duration to be run on the CPU, and memory scheduling in virtual memory systems. Resource #1: the processor Processes have three states: 1. running 2. ready: waiting for CPU time. Scheduler and dispatcher determine transitions between ready and running state. 3. blocked: waiting for some other event: disk I/O, message, semaphore, user input, etc. Scheduling diagrams: Simplified: +-----WAIT | (BLOCKED) | | ^ | | | v V | SUBMIT--> HOLD--> READY--> RUN--> DONE ^ | | | +------+ Figure 1. A submitted job is held until it is ready, at which point the scheduling algorithm decides when to run it. It may have to wait (for an I/O device for example), or it could be swapped out (because another job has higher priority, for instance.) It may go back to the READY queue, and repeat the process until it is complete. More accurate: +---------------+----------------WAIT TIMESHARING | | (BLOCKED) JOBS-+ | | ^ | | | | | | | | ------+ | | ------+ | ------+ | BATCH | v v | v | +-----+ -------> ||||||---------> |||||---------> |||||---->| CPU |---> DONE | ^ | ^ | +-----+ ------+ | ------+ | ------+ | HOLD | RUNNABLE | IN-MEMORY | QUEUE | QUEUE | QUEUE | +---------------+-----------------+ Figure 2. A more complex version of Figure 1. Jobs can follow any path along the arrows. Terms are defined below. -Job: all of the computations associated with a single "submission" (e.g. one command from your terminal). The job is the unit of scheduling. -Note: The professor will use "jobs" and "processes" interchangably. Jobs are usually associated with scheduling, while processes are associated with synchronization. -Timesharing: sharing CPU cycles among several processes, so each has the illusion of having its own CPU -Hold Queue: holds jobs until the system is prepared to give them some service. Used to avoid overloading the machine. Jobs can be held here to avoid deadlock. Resources are allocated here. -Used for batch jobs, such as jobs submitted to a supercomputer, which are expected to take a significant amount of time -Runnable Queue: processes which are considered for scheduling, but are not yet in memory. -In Memory Queue: processes which are (mostly) in memory; can be scheduled very cheaply. Functions of job scheduler and dispatcher: -Keep track of job status (which queue, elapsed time, priority, etc.) -Choose which jobs will "run". -Allocate necessary resources (memory, I/O devices, etc.) -Deallocate resources when necessary. Note: The professor will use "scheduler" and "dispatcher" interchangably most of the time. If there is a distinction, it is as follows: -The (job) scheduler usually determines which jobs go from the hold-queue to the runable-queue, and the runable queue to the in-memory-queue. -The dispatcher usually determines which process in the in-memory-queue gets to actually run. Goals for scheduling disciplines: Students' answers: - Minimize overhead - Avoid idle time and maximize CPU utilization - Maximize jobs/unit-time (throughput) - Avoid starvation - Avoid conflicts of resources