Notes for Comp 374, Operating Systems, Peter Dordal, Fall 2000 Week 1 Mon, August 28 What is an OS? *Not* a shell/windowmanager. Some basic strategies: Simplest: single-user. "DOS" (acronym first used on mainframes in the early 60s) stood for "Disk Operating System"; main purpose was to provide an abstract interface to the disk. We also need interfaces to the (text) console, the keyboard, and other devices like the network and printer. Only one program can run at a time. At this level, the OS looks a lot like a "library". EXCEPT for interrupts! Serial devices: interrupt cpu when data arrives Disks: interrupt when data arrives or a write completed; application first issues a *request* to read/write data. The application may wait during the interval, or may not. Applications *can't* wait for serial/net/keyboard data; this is "asynchronous". SOLUTION: Interrupt handlers. This now makes the primitive OS *unlike* a simple library. Wed, August 30 Brief overview of interrupt handling (See section 4.5 of Nutt) Context Switch: saving existing processor *state*. So now the OS "lives" in RAM, permanently. Synchronous disk I/O still looks like library calls, *but* disk integrity is so important that we don't trust it to applications. THis too is moved to RAM, through the use of TRAP instructions (=synchronous interrupts). Brief overview of trap instructions (see section 4.6 of Nutt). OS features so far: Device/network management Resource *abstraction* (it snuck in there; discuss Unix "everything is a file" model, NT "hardware abstraction layer" idea) Disk management (format, I/O, buffering, readahead[!], etc) We are still talking about single-tasking "batch" systems. For some people, OS *is* the interface between hardware and programs. Although there is perhaps more: Next step: multi-programming. Two programs loaded in memory at once, each one is scheduled while the other waits. Scheduling is now an issue, particularly if we load three programs and have two waiting. Friday, Sept 1 Time-sharing: two or more programs loaded at once; the system interrupts one to schedule the others. Also called preemptive multitasking. Note that we now must save the state of one program, and launch another. So we need "context switching". But we already had that, for interrupts. Preemptive multitasking is based on the TIMER interrupt. We can have several USERS on the system, each running the same program (eg the "shell", or an editor). We might thus have a single program, but several *processes*. We don't really mean "two or more *programs* at once"; we mean two or more *processes*. OS features added: Process management creation scheduling interprocess synchronization and communication deadlock Finally, we now want the processes not to interfere with each other, either maliciously or inadvertently. We don't want one user able to snoop on other, and we don't want the crash of one program to bring down the others. (developers used to *hate* DOS for that reason; a crash would kill their editor, for example.) But this is tricky: a process on the CPU has "full control". This brings us to MEMORY MANAGEMENT, and VIRTUAL MEMORY. The trick is that memory is really external to the CPU, and one can step in. Brief overview of VIRTUAL MEMORY But who sets up the page tables? What prevents user processes from doing this themselves, and making a mess? We introduce the MODE BIT, and SUPERVISOR v USER modes. (Threads v Processes) We also want user files to be protected. THe OS can enforce access restrictions on processes that use the OS-provided disk library, but what about processes that just do the low-level disk access machine instructions? Again, we make these supervisor-mode-only; now, processes *must* use the OS to access the disk. OS features added: Memory management Disk management In general, the OS is responsible for all RESOURCE MANAGEMENT. Friday, Sept 8: Unix v NT process creation. Chapters 1 and 2, officially. Monday, Sept 11: fork()/exec() in unix, NT file interface versus Friday, Sept 15: Ch 3: Issues: Performance, Protection/Security, Correctness, Commerce (the last is essentially the Unix v NT debate) Ch 4: miscellaneous hardware issues. The important things are: MAR/MDR interface to RAM supervisor/user modes TRAP instructions, and interrupts Ch 5: Device management Direct I/O (polling)_ Interrupt-driven I/O Memory-mapped I/O DMA Buffering user-provided: primitives: request(blocknum), waitfor(blocknum)( A traditional read(blocknum) does both of these. Here is how we can do readahead on our own; in this example I've assumed two buffers "a" and "b" were available, and added a second parameter to the request() call to specify which buffer to use. The data in each block is processed by the process() call. request(1,a) waitfor(1) // as soon as a block arrives, request the next one) request(2,b) process(1,a) waitfor(2) request(3,a) process(2,b) // i/o controller is working on #3 waitfor(3); request(4,b) process(3,a) The requests *could* be done a little earlier. Monday, Sept 18 Normally, though, one nowadays relies on the OS to provide read-ahead (or write-behind). Effect of N buffers Device-drivers Block v char uniform interface, API v Kernel (5.3.1) Wed, Sept 20 table-driven, p 110 Kernel interface top half / bottom half, p 97 Homework 1: Due Monday, Sept 25 p 91, #9. Assume that the device supports read() only, and does not require initialization. p 123, #3 (assume "best case"), #6 (consider read and write), #11, #12 Disk drivers rotational, seek delays FCFS SSTF, starvation Fri, Sept 22 Scan Look (=elevator) Circular variants: scan only in increasing direction Processes: 4 elements of a process: program (perhaps a shared executable) data (eg heap and stack) resources (eg open files, devices, network connections) process descriptor (eg the process table entry, plus u-area) state diagram ready, running, blocked Monday, Sept 25 Single-cpu v multiple-cpu 6.2: Boot-up and process creation: unix 0 => init(1) => /etc/inittab => rc files => daemons,gettys 6.3 (skim, at best): Address space mapping Process parent/child relationships 6.4: process descriptor stuff more process states: swapped sleeping stopped zombie Friday, 9/29 6.5: resource abstraction: resource Ri, with count ci. /proc filesystem, pmap, pcred, pldd, psig, pwdx, pstack, pfiles (utils are in /usr/proc/bin) Ch 7: the scheduler fcfs, 7.3.1 problem: high average waits, if long job blocks everyone else sjf, 7.3.2 problem: starvation (just like shortest-seek-time) problem: how do you tell? round robin 7.4.1 where do new processes go in the queue? what gets the short end of the stick? priority-based mechanisms unix strategy: maintain decaying-average cpu-use. cpu[i] = (cpu[i-1]+use[i])/2 priority = base + cpu[i]/2 + nice Wednesday, Oct 4: editor v cpu-intensive job NT scheduler: boost for threads waiting for I/O boost for threads waiting for windows messages boost for threads that haven't run in a while foreground boost (of time quantum, not priority) critical section Friday: critical section overview lock variable (flag) disabling interrupts TSET deadlock Monday, October 9 fork v unix fork semaphores basics of P & V, page 196. Atomicity, busywaiting. basic critical section problem basic synchronizing problem device driver example Oct 11 bounded-buffers problem Oct 13 Change producer/consumer to start of consumer: if (buf.size() == 0) P(sync); end of producer: if (buf.size() == 1) V(sync); readers/writers; policy v implementation semaphore implementations: TSET/TS perils of binary semaphores spin locking (busywaiting on a semaphore) having P put process into wait queue active/passive: active semaphores execute yield() on V(). dining philosophers Oct 20 AND Semaphores Signals (most) Oct 23 Monitors ADT (class) with mutex, sync provisions mutex: only one process at a time may run a monitor member fn. sync: condition vars, with wait/signal Hoare semantics: signal()ed thread runs immediately Brinch-Hansen: runs later Oct 25: readwrite java readwrite Oct 27: sync homework You will implement the tunnel traffic synchronizer on page 229 in Java, and then run some simulations with it considering light and heavy traffic. The existing implementation, if there is a constant stream of traffic from the north, never changes the light! So traffic from the south starves. You need to fix this. message passing pipes! messages blocking/nonblocking semantics mailbox model: accept messages from multiple senders connection model: connect to *one* sender async v sync send blocking v nonblocking receive semaphores implemented with messages one shared mbox all messages are empty inital value of sema = initial number of msgs P(): take a message out, or wait if empty V(): put a message in queues implemented with messages also easily implemented with semaphores, given a "master" process deadlock some examples resource graph models prevention: mutex, hold&wait, circular wait, no preemption livelock avoidance banker's algorithm detection versus cycles: cycles do *not* imply deadlock! Memory issues: Fragmentation best-fit, first-fit, worst-fit register-based relocation, PIC (position-independent code) mac relocation scheme segmentation VM simple paging page table sizes principle of locality performance, TLB disk-based VM expanding small address space, virtual < real 16 bit, 24 bit expanding physical address space, virtual > real VM implementation; Psi map in the book; page faults performance thrashing increasing/decreasing pagefile size at runtime Page Table implementations sidebar on page 328: inverted page tables (assoc lookup), TLB 2-level page tables dirty bit copy-on-write minimizing page faults in your software Static page replacement algorithms FIFO Optimal (Belady) LRU LFU Skip 12.3.3, Stack algorithms 12.3.4: implementing LRU use bit clock algorithm shift register Basics of ownership and access Unix model: Subjects S are (essentially) userids. Objects are files, also semaphores, memsegments, signals, etc Access: read-only v read-write How do you grant (selected) access to a file in Unix? files have user,group,other permissons processes have user, groupvector identities server processes (internal and network) setuid bit