Operating Systems
1999-2000 Fall
Mon 5-6:50
Ciww 109

Allan Gottlieb
gottlieb@nyu.edu
http://allan.ultra.nyu.edu/gottlieb
715 Broadway, Room 1001
212-998-3344
609-951-2707
email is best

Administrivia

Web Pages

There is a web page for the course. You can find it from my home page.

Textbook

Text is Tanenbaum, "Modern Operating Systems".

Computer Accounts and majordomo mailing list

Homeworks and Labs

I make a distinction between homework and labs.

Labs are

Homeworks are

Upper left board for assignments and announcements.

Homework: Read Chapter 1 (Introduction)

1. Introduction

Levels of abstraction (virtual machines)

1.1: What is an operating system?

The kernel itself raises the level of abstraction and hides details. Can write to a file (a concept present in hardware) and ignore whether it is a floppy or hard disk.

The kernel is a resource manager (so users don't conflict).

How is an OS fundamentally different from a compiler (say)?

Answer: Concurrency! Per Brinch Hansen in Operating Systems Principles (Prentice Hall, 1973) writes.

The main difficulty of multiprogramming is that concurrent activities can interact in a time-dependent manner, which makes it practically impossibly to locate programming errors by systematic testing. Perhaps, more than anything else, this explains the difficulty of making operating systems reliable.

1.2 History of Operating Systems

  1. Single user (no OS)
  2. Batch, uniprogrammed, run to completion
  3. Multiprogrammed
  4. Multiple computers
  5. Real time systems
Homework:1, 2, 5 (unless otherwise stated, problems numbers are from the end of the chapter in Tanenbaum.)

1.3: Operating System Concepts

This will be brief. Much of the rest of the course will consist in ``filling in the details''.

1.3.1: Processes

A program in execution.

Often one distinguishes the state or context (memory image, open file) from the thread of control. Then if one has many threads running in the same task, the result is a ``multithreaded processes''.

The OS keeps information about all processes in the process table. Indeed, the OS views the process as the entry. An example of an active entity being viewed as a data structure (cf. discrete event simulations).

The set of processes forms a tree via the fork system call. The forker is the parent of the forkee.

A signal can be sent to a process to cause it to execute a predefined function (the signal handler). This can be tricky to program since the programmer does not know when in his ``main'' program the signal handler will be invoked.

1.3.2: Files

Modern systems have a hierarchy of files. A file system tree.

Files and directories normally have permissions

Devices (mouse, tape drive, cdrom) are often view as ``special files''. In a unix system these are normally found in the /dev directory. Some utilities that are normally applied to (ordinary) files can as well be applied to some special files. For example, when you do not have anything serious going on (i.e. as soon as you log in), type the following on unix

    cat /dev/mouse
and then move the mouse. You kill the cat by typing cntl-C. I tried this on my linux box and no damage occurred. Your mileage may vary.

Many systems have standard files that are automatically made available to a process upon startup. There (initial) file descriptors are fixed

A convenience offered by some command interpretors is a pipe

  ls | wc
Will give the number of files. Homework: 3

1.3.3: System Calls

The way a user (i.e. program) directly interfaces with the OS. Often the component of the OS responsible for fielding system calls and dispatching them is called the envelope. Here is a picture showing some of the components and the external events for which they are the interface.

What happens when a user writes a function call like read?

  1. Normal function call (in C, ada, etc.)
  2. Library routine (in C)
  3. Small assembler routine
    1. Move arguments to predefined place (perhaps registers)
    2. Poof (a trap instruction) and then the OS proper runs in supervisor mode
    3. Fixup result (move to correct place)
Homework: 6

1.3.4: The shell

Assumed knowledge

Homework: 9.

1.4: OS Structure

I must note that tanenbaum is a big advocate of the so called microkernel approach in which as much as possible is moved out of the (protected) microkernel into usermode components.

In the early 90s this was popular. Digital Unix and windows NT were examples. Digital unix was based on Mach a research OS from carnegie mellon university. Lately, the growing popularity of linux has called this into question.

1.4.1: Monolithic approach

The previous picture: one big program

The system switches from user mode to kernel mode during the poof and then back when the OS does a ``return''.

But of course we can structure the system better, which brings us to.

1.4.2: Layered Systems

Some systems have more layers and are more strictly structured.

An early layered system was ``THE'' by dijkstra

  1. The operator
  2. User programs
  3. I/O mgt
  4. Operator-process communication
  5. Memory and drum management

The layering was done by convention, i.e. there was no enforcement by hardware and the entire OS is linked together as one program. This is true of man modern OS systems as well (e.g., linux).

The multics system was layered in a more formal manner. The hardware provided several protection layers and the OS used them.

1.4.4: Virtual machines

Use a ``hypervisor'' (beyond supervisor) to switch between multiple Operating Systems


================ Start Lecture 2 ================

14.4: Client Server

When done on one computer this is the microkernel approach in which the microkernel just supplies interprocess communication and the main OS functions are provided by a number of usermode processes.

This does have advantages. For example an error in the file server cannot corrupt memory in the process server. This makes errors easier to track down.

But it does mean that when a (real) user process makes a system call there are more switches from user to kernel mode and back. These are not free.

A distributed system can be thought of as an extension of the client server concept where the servers are remote.

Homework: 11

Chapter 2: Process Management

Tanenbaum's chapter title is ``processes''. I prefer process management. The subject matter is process scheduling, interrupt handling, and IPC (Interprocess communication--and coordination).

2.1: Processes

Definition: A process is a program in execution.

Even though in actuality there are many processes running at once, the OS gives each process the illusion that it is running alone.

Some systems have user processes and system processes. The latter act as servers satisfying requests from the former (which act as clients). The natural structure of such a system is to have process management (i.e. process switching, interrupt handling, and IPC) in the lowest layer and have the rest of the OS consist of system processes.

This is called the client-server model and is one tanenbaum likes. Indeed, there was reason to believe that it would dominate. But that hasn't happened as yet. One calls such an OS server based. Systems like traditional unix or linux can be called self-service in that the user process itself switches to kernel mode and performs the system call. That is, the same process changes back and forth from/to user<-->system mode and services itself.

Process Hierarchies

Modern general purpose operating systems permit a user to create (and distroy) processes. In unix this is done by the fork system call which creates a child process. Both parent and child keep running (indeed they have the same program text) and each can fork off other processes. A process tree results. The root of the tree is a special process created by the OS during startup.

Process states and transitions

This diagram contains a great deal of information.

One can organize an OS around the scheduler.

2.1.3: Implementation of Processes

Process table

An aside on interupts

In a well defined location in memory (specified by the hardware) the OS store aninterrupt vector, which contains the address of the (first level) interrupt handler.

Assume a process P is running and an interrupt occurs (say a disk interrupt for the completion of a disk read previously issued by process Q). Note that the interrupt is unlikely to be for process P.

  1. The hardware stacks the program counter etc (possibly some registers)
  2. Hardware loads new program counter from the interrupt vector.
  3. Assembly language routine saves registers
  4. Assembly routine sets up new stack
  5. Assembly routine calls C procedure (tanenbaum forgot this one)
  6. C procedure does the real work
  7. The C procedure (that did the real work in the interrupt processing) continues and returns to the assembly code.
  8. Assembly language starts P at the point it was when the interrupt occurred.

2.2: Interprocess Communication (IPC)

2.2.1: Race Conditions

A race condition occurs when two processes can interact and the outcome depends on the order in which the processes execute.

Homework: 2

2.2.2: Critical sections

Prevent interleaving of sections of code that need to be atomic with respect to each other. That is, the conflicting sections need mutual exclusion. If process A is executing its critical section, it excludes process B from executing its critical section. Conversely if process B is executing is critical section, it excludes process A from executing its critical section.

Goals for a critical section implementation.

  1. No two processes may be simultaneously inside their critical section
  2. No assumption may be made about the speeds or the number of CPUs
  3. No process outside its critical section may block other processes
  4. No process should have to wait forever to enter its critical section

2.2.3 Mutual exclusion with busy waiting

The operating system can choose not to preempt itself. That is, no preemption for system processes (if the OS is client server) or for processes running in system mode (if the OS is self service)

But this is not adequate

Software solutions for two processes

Initially P1wants=P2wants=false

Code for P1                             Code for P2

Loop forever {                          Loop forever {
    P1wants <-- true         ENTRY          P2wants <-- true
    while (P2wants) {}       ENTRY          while (P1wants) {}
    critical-section                        critical-section
    P1wants <-- false        EXIT           P2wants <-- false
    non-critical-section }                  non-critical-section }

Explain why this works.

But it is wrong! Why?

Initially turn=1

Code for P1                      Code for P2

Loop forever {                   Loop forever {
    while (turn = 2) {}              while (turn = 1) {}
    critical-section                 critical-section
    turn <-- 2                       turn <-- 1
    non-critical-section }           non-critical-section }

This one forces alternation, so is not general enough.

In fact, it took years (way back when) to find a correct solution. The first one was found by dekker. It is very clever, but I am skipping it (I cover it when I teach OS II).

Initially P1wants=P2wants=false  and  turn=1

Code for P1                        Code for P2

Loop forever {                     Loop forever {
    P1wants <-- true                   P2wants <-- true
    turn <-- 2                         turn <-- 1
    while (P2wants and turn=2) {}      while (P1wants and turn=1) {}
    critical-section                   critical-section
    P1wants <-- false                  P2wants <-- false
    non-critical-section               non-critical-section

This is Peterson's solution. When it was published, it was a surprise to see such a simple soluntion. In fact Peterson gave a solution for any number of processes. Subsequently, algorithms with better fairness properties were found (e.g. no task has to wait for another task to enter the CS twice). We will not cover these.

Hardware assist (test and set)

TAS(b) where b is a binary variable ATOMICALLY sets b<--true and returns the OLD value of b. Of course it would be silly to return the new value of b since we know the new value is true

Now implementing a critical section for any number of processes is trivial.

while (TAS(s)) {}   ENTRY
s<--false           EXIT

P and V and Semaphores

Note: Tanenbaum does both busy waiting (like above) and blocking (process switching) solutions. We will only do busy waiting.

Homework: 3

The entry code is often called P and the exit code V (tanenbaum only uses P and V for blocking, but we use it for busy waiting). So the critical section problem is to write P and V so that

loop forever
    P
    critical-section
    V
    non-critical-section
satisfies
  1. Mutual exclusion
  2. Forward progress (my weaken version of tanenbaum's condition
  3. No speed assumptions
  4. No blocking by processes in NCS

Note that I use indenting carefully and hence do not need (and sometimes omit) the braces {}

A binary semaphore abstracts the TAS solution we gave for the critical section problem.

So for any number of processes the critical section problem can be solved by

loop forever
    P(S)
    CS     <== critical-section
    V(S)
    NCS    <== non-critical-section

The only solution we have seen for arbitrary number of processes is with test and set.

To solve other coordination problems we want to extend binary semaphores

The solution to both of these shortcomings is to remove the restriction to a binary variable and define a generalized or counting semaphore.

These counting semaphores can solve what I call the semi-critical-section problem, where you premit up to k processes in the section. When k=1 we have the original critical-section problem.

initially S=k

loop forever
    P(S)
    SCS   <== semi-critical-section
    V(S)
    NCS

Start of Lecture 3

Producer-consumer problem

initially e=k, f=0 (counting semaphore); b=open (binary semaphore)

Producer                         Consumer

loop forever                     loop forever
    produce-item                     P(f)
    P(e)                             P(b); take item from buf; V(b)
    P(b); add item to buf; V(b)      V(e)
    V(f)                             consume-item

Dining Philosophers

A classical problem from Dijkstra

What algorithm do you use for access to the shared resource (the forks)?

The point of mentioning this without giving the solution is to give a feel of what coordination problems are like. The book gives others as well. We are skipping these (2nd semester, depending on instructor).

Homework: 14,15

Readers and writers

Quite useful in multiprocessor operating systems. The ``easy way out'' is to treat all as writers (i.e., give up reader concurrency).

2.4: Process Scheduling

Scheduling the processor is often called just scheduling or process scheduling.

The objectives of a good scheduling policy include

Recall the basic diagram about process states

For now we are discussing short-term scheduling running <--> ready.

Medium term scheduling is discussed a little later.

Preemption

This is an important distinction.

Deadline scheduling

This is used for real time systems. The objective of the scheduler is to find a schedule for all the tasks (there are a fixed set of tasks) so that each meets its deadline. You know how long each task executes

Actually it is more complicated.

We do not cover deadline schedling in this course.

The name game

There is an amazing inconsistency in naming the different (short-term) scheduling algorithms. Over the years I have used primarily 4 books: In chronological order they are Finkel, Deitel, Silberschatz, and Tanenbaum. The table just below illustrates the name game for these three books. After the table we discuss each scheduling policy in turn.

Finkel  Deitel  Silbershatz Tanenbaum
-------------------------------------
FCFS    FIFO    FCFS        --    unnamed in tanenbaum
RR      RR      RR          RR      
SRR     **      SRR         **    not in tanenbaum
PS      **      PS          PS
SPN     SJF     SJF         SJF   
PSPN    SRT     PSJF/SRTF   --    unnamed in tanenbaum
HPRN    HRN     **          **    not in tanenbaum
**      **      MLQ         **    only in silbershatz
FB      MLFQ    MLFQ        MQ

First Come First Served (FCFS, FIFO, FCFS, --)

If you ``don't'' schedule, you still have to store the PTEs somewhere. If it is a queue you get FCFS. If it is a stack (strange), you get LCFS. Perhaps you could get some sort of random policy as well.

Round Robbin (RR, RR, RR, RR)

Homework: 9, 19, 20, 21

Selfish RR (SRR, **, SRR, **)

Processor Sharing (PS, **, PS, PS)

All n processes are running, each on a processor 1/n as fast as the real processor.

Homework: 18.

Shortest Job First (SPN, SJF, SJF, SJF)

Sort jobs by total execution time needed and run the shortest first.

Preemptive Shortest Job First (PSPN, SRT, PSJF/SRTF, --)

Preemptive version of above

Priority aging

As a job is waiting, raise its priority and when it is time to choose, pick job with highest priority.

Homework: 22, 23

Highest Penalty Ratio Next (HPRN, HRN, **, **)

Run job that has been ``hurt'' the most.

Multilevel Queues (**, **, MLQ, **)

Put different classes of jobs in different queues

Multilevel Feedback Queues (FB, MFQ, MLFBQ, MQ)

Many queues and jobs move from queue to queue in an attempt to dynamically separate ``batch-like'' from interactive jobs.

Theoretical Issues

Much theory has been done (NP completeness results abound)
Queuing theory developed to predict performance

Medium Term scheduling

Decisions made at a coarser time scale.

Long Term Scheduling


==== Start Lecture #4 ====

Notes on lab1

  1. If several processes are waiting on I/O, you may assume noninterference. For example, assume that on cycle 100 process A flips a coin and decides its wait is 6 units and next cycle (101) process B flips a coin and decides its wait is 3 units. You do NOT have to alter process A. That is, Process A will become ready after cycle 106 (100+6) so enters the ready list cycle 107 and process B becomes ready after cycle 104 (101+3) and enters ready list cycle 105.

  2. For processor sharing (PS), which is part of the extra credit:
    PS (processor sharing). Every cycle you see how many jobs are in the ready Q. Say there are 7. Then during this cycle (an exception will be described below) each process gets 1/7 of a cycle.
    EXCEPTION: Assume there are exactly 2 jobs in RQ, one needs 1/3 cycle and one needs 1/2 cycle. The process needing only 1/3 gets only 1/3, i.e. it is finished after 2/3 cycle. So the other process gets 1/3 cycle during the first 2/3 cycle and then starts to get all the cpu. Hence it finishes after 2/3 + 1/6 = 5/6 cycle. The last 1/6 cycle is not used by any process.

Chapter 3: Memory Management

Also called storage management or space management.

Memory management must deal with the storage hierarchy present in modern machines.

We will see in the next few lectures that there are three independent decision:

  1. Segmentation (or no segmentation)
  2. Paging (or no paging)
  3. Fetch on demand (or no fetching on demand)

Memory management implements address translations.

Homework: 7.

When is the address translation performed?

  1. At compilie time
    • Primative
    • Compiler generates physical addresses
    • Requires knowledge of where compilation unit will be loaded
    • Rarely used (MSDOS .COM files)

  2. At link-edit time
    • Compiler
      • generates relocatable addresses for each compilation unit
      • references external addresses
    • Linkage editor
      • Converts the relocatable addr to absolute
      • resolves external references
      • Misnamed ld by unix
      • Also convert virtual to physical by knowing where the linked program will be loaded. Unix ld does not do this.
    • Loader is simple
    • Hardware requirements are small
    • A program can be loaded only where specified and cannot move once loaded.
    • Not used much any more.

  3. At load time
    • Same as linkage editor but do not fix the starting address
    • Program can be loaded anywhere
    • Program can move but cannot be split
    • Need modest hardware: base/limit regs

  4. At execution time
    • Dynamically during execution
    • Hardware to perform the virtual to physical address translation quickly
    • Currently dominates
    • Much more information later

Extensions

Note: I will place ** before each memory management scheme.

3.1: Memory management without swapping or paging

Job remains in memory from start to finish

Sum of memory requirements of jobs in system cannot exceed size of physical memory.

** 3.1.1: Monoprogramming without swapping or paging (Single User)

The ``good old days'' when everything was easy.

3.1.2: Multiprogramming

Goal is to improve CPU utilization, by overlapping CPU and I/O

Homework: 1, 3.

3.1.3: Multiprogramming with fixed partitions

3.2: Swapping

Moving entire jobs between disk and memory is called swapping.

3.2.1: Multiprogramming with variable partitions

Homework: 4


==== Start Lecture #5 ====

See announcements on course home page

Introduces the ``Placement Question'', which hole (partition) to choose

Homework: 2, 5.

Also introduces the ``Replacement Question'', which victim to swap out

We will study this question more when we discuss demand paging

Considerations in choosing a victim
NOTEs:
  1. So far the schemes have had two properties
    1. Each job is stored contiguously in memory. That is, the job is contiguous in physical addresses.
    2. Each job cannot use more memory than exists in the system. That is, the virtual addresses space cannot exceed the physical address space.

  2. Tanenbaum now attacks the second item. I wish to do both and start with the first

  3. Tanenbaum (and most of the world) uses the term ``paging'' to mean what I call demand paging. This is unfortunate as it mixes together two concepts
    1. Paging (dicing the address space) to solve the placement problem and essentially eliminate external fragmentation.
    2. On demand fetching, to permit the total memory requirements of all loaded jobs to exceed the size of physical memory.

  4. Tanenbaum (and most of the world) uses the term virtual memory as a synonym for demand paging. Again I consider this unfortunate.
    1. Demand paging is a fine term and is quite discriptive
    2. Virtual memory ``should'' be used in contrast with physical memory to describe any virtual to physical address translation.

** (non-demand) Paging

Simplest scheme to remove the requirement of contiguous physical memory.

Example: Assume a decimal machine, with pagesize=framesize=1000.
Assume PTE 3 contains 459.
Then virtual address 3372 corresponds to physical address 459372.

Properties of (non-demand) paging.

Homework: 13

Address translation

Choice of page size is discuss below

Homework: 8, 13, 15.

3.2: Virtual Memory (meaning fetch on demand)

Idea is that a program can execute if only the active portion of its address space is memory resident. That is swap in and swap out portions of a program. In a crude sense this can be called ``automatic overlays''.

Advantages

3.2.1: Paging (meaning demand paging)

Fetch pages from disk to memory when they are referenced, with a hope of getting the most actively used pages in memory.

Homework: 11.

3.3.2: Page tables

A discussion of page tables is also appropriate for (non-demand) paging, but the issues are more acute with demand paging since the tables can be much larger. Why?
Ans: The total size of the active processes is no longer limited to the size of physical memory.

Want access to the page table to be very fast since it is needed for every memory access.

Unfortunate laws of hardware

So we can't just say, put the page table in fast processor registers and let it be huge and sell the system for $1500.

Put the (one-level) page table in main memory.

Protection bits

Can place protection bits on pages. For example can mark pages as execute only. This requires that boundaries between regions with different protection must be on page boundaries. Protection is more naturally done with segmentation.

Multilevel page tables

Idea, which is also used in unix inode-based file systems, is to add a level of indirection and have a page table containing pointers to page tables.

Do an example on the board

The VAX used a 2-level page table structure, but with some wrinkles (see tanenbaum for details).

Naturally, there is no need to stop at 2 levels. In fact the sparc has 3 levels and the motorola 68030 has 4 (and the number of bits of Virtual Address used for P#1, P#2, P#3, and P#4 can be varied).

3.3.4: Associative memory (TLBs)

Note: Tanenbaum suggests that ``associative memory'' and ``translation lookaside buffer'' are synonyms. This is wrong. Associative memory is a general structure and translation lookaside buffer is a special case.

An associative memory is a content addressable memory. That is you access the memory by giving the value of some field and the hardware searches all the records and returns the record whose field contains the requested value.

For example

Name  | Animal | Mood     | Color
======+========+==========+======
Moris | Cat    | Finicky  | Grey
Fido  | Dog    | Friendly | Black
Izzy  | Iguana | Quiet    | Brown
Bud   | Frog   | Smashed  | Green
If the index field is Animal and Iguana is given, the associative memory returns
Izzy  | Iguana | Quiet    | Brown

==== Start Lecture #6 ====

A Translation Lookaside Buffer or TLB is an associate memory where the index field is the page number. The other fields include the frame number, dirty bit, valid bit, and others.

Homework: 15.

3.3.5: Inverted page tables

Keep a table indexed by frame number with the entry f containg the number of the page currently loaded in frame f.

3.4: Page Replacement Algorithms

These are solns to the replacement question.

Good solutions take advantage of locality.

Pages belonging to processes that have terminated are of course perfect choices for victims.

Pages belonging to processes that have been blocked for a long time are good choices as well.

Random

A lower bound on performance. Any decent scheme should do better.

3.4.1: The optimal page replacement algorithm (opt PRA)

Replace the page whose next reference will be furthest in the future

3.4.2: The not recently used (NRU) PRA

Divide the frames into four classes and make a random selection from the lowest nonempty class.

  1. Not referenced, not modified
  2. Not referenced, modified
  3. Referenced, not modified
  4. Referenced, modified

Assumes that in each PTE there are two extra flags R (sometimes called U, for used) and M (often called D, for dirty).

Also assumes that a page in a lower number class is cheaper to evict

We again have the prisoner problem, we do a good job of making little ones out of big ones, but not the reverse. Need more resets

Every k clock ticks, reset all R bits

What if hardware doesn't set these bits?

3..4.3: FIFO PRA

Simple but poor since usage of page is given no weight.

Belady's Anomaly: Can have more frames yet more faults. Example given later.

3.4.4: Second chance PRA

Fifo but when time to choose a victim if page at the head of the queue has been referenced (R bit), don't evict it but reset R move it to the rear of the queue (so it looks new). The page is being a second chance.

What if all frames have been referenced?
Becomes the same as fifo (but takes longer)

Might want to turn off the R bit more often (k clock ticks).

3.4.5: Clock PRA

Same algorithm as 2nd chance, but a better (and I would say obvious) implementation: Use a circular list.

Do an example.

LIFO PRA

This is terrible! Why?
You essentially use only one frame.

3.4.6:Least Recently Used (LRU) PRA

When a page fault occurs, choose as victim that page that has been unused for the longest time, i.e. that has been least recently used.

LRU is definitely

Homework: 19, 20

A hardware cutsie in in tanenbaum

3.4.7: Simulating LRU in Software

The Not Frequently Used (NFU) PRA

The Aging PRA

NFU doesn't distinguish between old references and recent one. Modify NFU so that, for all PTEs, at every k clock ticks

  1. Counter is shifted right one bit
  2. R is inserted as the new high order bit (HOB)

R counter
110000000
001000000
110100000
111010000
001101000
000110100
110011010
111001101
001100110

Homework: 21, 25

3.5: Modeling Paging Algorithms

3.5.1: Belady's anomaly

Consider the following ``reference string'' (sequence of pages referenced), which is assumed to occur on a system with no pages loaded initially that uses the FIFO PRU.

 0 1 2 3 0 1 4 0 1 2 3 4

If we have 3 frames this generates 9 page faults.

If we have 4 frames this generates 10 page faults.

Theory has been developed and certain PRA (so called ``stack algorithms'') cannot suffer this anomaly for any reference string. FIFO is clearly not a stack algorithm. LRU is.

Repeat the above for LRU.

3.6: Design issues for (demand) Paging

3.6.1 & 3.6.2: The Working Set Model and Local vs Global Policies

I will do these in the reverse order (which makes more sense). Also tanenbaum doesn't actually define the working set model, but I shall.

A local PRA is one is which a victim page is chosen among the pages of the same process that requires a new page. That is the number of pages for each process is fixed. So LRU means the page least recently used by this process.

Of course we can't have a purely local policy, why?
Ans: A new process has no pages and even if we didn't apply this for the first page loaded, the process would remain with only one page.

Perhaps wait until a process has been running a while.

A global policy is one in which the choice of victim is made among all pages of all processes

If we apply global LRU indiscrimanently with some sort of RR processor scheduling policy, and memory is somewhat over-committed, then by the time we get around to a process, all the others have run and have probably paged out this process.

If this happens each process will need to page fault at a high rate; this is called thrashing. It would therefore be good to get an idea of how many pages a process needs, so that we can balance the local and global desires.


==== Start Lecture #7 ====

Request Please include your student number and email address on homework #6, which you are handing in.

The working set policy (Peter Denning)

The goal is to specify which pages a given process needs to have memory resident.

The idea of the working set policy is to ensure that each process keeps its working set in memory.

Interesting questions incude:

Various approximations to the working set frequency have been devised.

  1. Wsclock
    • Use the aging algorithm above to maintain a counter for each PTE and declare a page whose counter is above a certain threshold to be part of the working set.
    • Apply the clock algorithm globally (i.e. to all pages) but refuse to page out any page in a working set, the resulting algorithm is called wsclock
    • What if we find there are no pages we can page out?
    • Ans: Reduce the multiprogramming level
  2. Page Fault Frequency (PFF)
    • For each process keep track of the page fault frequency, which is the number of faults divided by the number of references.
    • Actually, must use a window or a weighted calculation since you are really interested in the recent page fault frequency
    • If the pff is too low, allocate more frames to this process. Either
      1. Raise its number of frames and use local policy; or
      2. Bar its frames from eviction and use a global policy
  3. What if not enough frames?
  4. Ans: Lower MPL. (multiprogramming level)

3.6.3: Page size

3.6.4: Implementation Issues

Don't worry about instruction backup. Very machine dependent and modern implementations tend to get it right.

Locking (pinning) pages

We discussed pinning jobs already. The same (mostly I/O) considerations apply to pages.

Shared pages

Really should share segments

Backing Store

The issue is where on disk do we put pages

Paging Daemons

Done earlier

Page Fault Handling

  1. Hardware traps to the kernel (switches to supervisor mode; saves state)

  2. Assembly language code save more state, establishes the C-language environment, calls the OS

  3. OS determines that a fault occured and which page

  4. If virt addr is invalid, shoot process. If valid, seek a free frame. If no free frames, select a victim.

  5. If the victim frame is dirty, schedule an I/O write to copy the frame to disk. This process is blocked so the process scheduler is invoked to perform a context switch.

    • Tanenbaum ``forgot'' some here
    • Disk interrupt occurs when I/O complete
    • Hardware trap / assembly code / OS determines I/O done
    • Process moved from blocked to ready
    • Some time later a context switch occurs to this ready process. Since this process is in kernel mode. Perhaps it was scheduled to run as soon as it was ready. I am using a ``self-service'' model where the process moves from user mode to kernel mode.

  6. Now the frame is clean (this may be much later in wall clock time). Schedule an I/O to read to the desired page into this clean frame. This process is again blocked so the process scheduler is invoked to perform a context switch.

  7. Disk interrupt occurs when I/O complete (trap / asm / OS determines) / made ready / starts running). PTE updated

  8. Fix up process (e.g. reset PC)

  9. Process put in ready queue and eventually runs. The OS returns to the first asm routine.

  10. Asm routine restores regs, etc and returns to user mode.

Process is unaware that all this happened.

3.7: Segmentation

Up to now, the virtual address space has been contiguous.

The following table mostly from tanenbaum compares demand paging with demand segmentation.

Consideration Demand
Paging
Demand
Segmentation
Programmer aware NoYes
How many addr spaces 1Many
VA size > PA size YesYes
Protect individual
procedures separately
NoYes
Accomodate elements
with changing sizes
NoYes
Ease user sharing NoYes
Why invented let VA size
exceed
PA size
Sharing
Protection
indep addr spaces

Internal fragmentation YesNo, in principle
Extternal fragmentation NoYes
Placement question NoYes
Replacement question YesYes

Homework: 29.

** Two Segments

Late PDP-10s and TOPS-10

** Three Segments

Traditional unix

  1. Shared text execute only
  2. Data segment (global and static variables)
  3. Stack segment (automatic variables)

** Four Segments

Just kidding.

** General (not necessarily demand) Segmentation


==== Start Lecture #8 ====

Don't forget the mirror site. My main website will be going down for an OS upgrade. Start at http://cs.nyu.edu/

** Demand Segmentation

Same idea as demand paging applied to segments

** 3.7.2: Segmentation with paging

Combines both segmentation and paging to get advantages of both at a cost in complexity.

Homework: 30.

Some last words

Chapter 4: File Systems

Requirements

  1. Size: Store very large amounts of data
  2. Persistence: Data survives the creating process
  3. Access: Multiple processes can access the data concurrently

Solution: Store data in files that together form a file system

4.1: Files

4.1.1: File Naming

Very important. A major function of the filesystem.

4.1.2: File structure

A file is a

  1. Byte stream
    • Unix, dos, windows (I think)
    • Max flexibility
    • Min structure

  2. (fixed size) Record stream: Out of date

  3. Varied and complicated beast
    • Indexed sequential
    • B-trees
    • Supports rapidly finding a record with a specific key
    • Supports retrieving (varying size) records in key order.
    • Treated in depth in database courses

4.1.3: File types

  1. (Regular) files

  2. Directories: studied below

  3. Special files (for devices)
    • Uses the naming power of files to unify many actions
    • dir # prints on screen
    • dir > file # result put in a file
    • dir > /dev/tape # results written to tape

  4. ``Symbolic'' Links (similar to ``shortcuts''): Also studied below.

4.1.4: File access

  1. Sequential access is most common. Why back when (the era (error?) of ``real programmers'' (tm) ), files were declared to be sequential or random.
  2. Random

4.1.5: File attributes

A laundry list of properties that can be specified for a file, e.g.

  1. hidden
  2. do not dump
  3. owner
  4. key length (for keyed files)

4.1.6: File operations

  1. Create: Essential if a system is to add files. Need not be a separate system call (can be merged with open).
  2. Delete: Essential if a system is to delete files.
  3. Open: Not essential. An optimization. Do the translation from file name to disk locations only once per file rather than once per access.
  4. Close: Not essential. Free resources.
  5. Read: Essential. Must specify filename, file location, number of bytes, where to put data read in. Several of these parameters can be set by other system calls and in many OS's they are.
  6. Write: Essential if updates are to be supported. See read for parameters.
  7. Seek: Not essential functionalily (could be in read/write). Specify the file offset of the next (read or write) access
  8. Get attributes: Essential if attributes are to be used.
  9. Set attributes: Essential if attributes are to be user settable.
  10. Rename: Tannenbaum has strange words. Copy and delete is not acceptable for big files. Moreover copy-delete not atomic. Indeed link-delete is not atomic so even with link (discussed below renaming a file adds functionality.

Homework: 2, 3, 4.
Read and understand ``copyfile'' on page 155.

Notes on copyfile

  1. Normally in unix one wouldn't call read and write directly.
  2. Indeed, for copyfile, fgets/fputs would be nice.
  3. fgets/fputs takes care of the buffering.
  4. Tanenbaum is correct that the error reporting is atrocious.
    The worst is exiting the loop on error and thus generating an exit(0) as if nothing happened.

4.1.7: Memory mapped files

Conceptually simple and elegant. Associate a segment with each file and then normal memory operations take the place of I/O.

Thus copyfile has not fgetc/fputc (or read/write). Instead it is just like memcopy

while ( (dest++)* = (src++)* );

The implmentation is via demand paging (on top of segmentation) but the backing store for the pages is the file. This all sounds great but ...

  1. How do you tell the length of a newly created file?
  2. What if same file is accessed by I/O and memory mapping.
  3. What if the file is bigger than the size of virtual memory (will not be a problem in 5 years on modern systems).

==== Start Lecture #9 ====

Bug in lab2 writup. I originally had 6 replacement algorithms, but in a moment of weakness, removed NUR. Sadly, I didn't remove it completely. Change all 900s to 750s and delete the sentence ``For NRU, start the clock pointing to page frame 0 with all use bits off.''

When comparing two algorithms or page sizes or whatever, must use the same set of reference streams.

4.2: Directories

Unit of organization.

4.2.1: Hierarchical directory systems

Possibilities

These are not as wildly different as they sound.

4.2.2: Path Names

Homework: 1, 8.

4.2.3: Directory operations

  1. Create: Normally comes with . and ..

  2. Delete: First empty the directory (except for . and ..)

  3. Opendir: Same as with files (creates a ``handle'')

  4. Closedir: Same as files

  5. Readdir: In the old days (of unix) could read directories as files so there was no special readdir (or opendir/closedir). It was believed that the uniform treatment would make programming (or at least system understanding) as there was less to learn.

    However, experience has taught that this was not a good idea since the structure of directories then becomes exposed. Early unix had a simple structure (and there was only one). Modern systems have more sophisticaed structures and more importantly they are not fixed accross implementations.

  6. Rename: As with files

  7. Link: Add a second name for a file; discussed below.

  8. Unlink: Remove a directory entry. This is how a file is deleted. But if there are many links, the file remains. Discussed in more detail below.

4.3: File System Implementation

4.3.1; Implementing Files

Contiguous allocation

Homework: 7.

Linked allocation

FAT (file allocation table)

Inodes

4.3.2; Implementing Directories

Maps file (or subdirectory) names to the files (or subdirectories) themselvesl.

Trivial filesys (CP/M)

MS-DOS

Unix

4.3.3: Shared files (links)

Since hard links are only permitted to files (not directories) the resulting filesystem is a dag (directed acyclic graph). That is there are no directed cycles. We will now proceed to give away this useful property by studing symlinks, which can point to directories.

Symlinks

4.3.4: Disk space management

All general purpose systems use a sort of (non-demand) paging algorithm for file storage. Files are broken into fixed size pieces, called blocks that can be scattered over the disk.

The file is completely stored on the disk (one can imagine system that only stores parts of file on disk the rest of tertiary storage). Perhaps NASA does this with their huge datasets.

Choice of block size

Storing freeblocks

  1. In memory bit map.
    • One bit per block
    • If blocksize=4K, 1 bit per 32K bits
    • So 32GB disk (potentially all free) needs 1MB ram
  2. Bit map paged in
  3. Linked list with each free block pointing to next: Extra disk access per block
  4. Linked list with links stored contiguously, i.e. an array of pointers to free blocks. Store this in free blocks and keep one in memory.

4,3.5: File System reliability

Bad blocks on disks

Not so much of a problem now. Disks more reliable and more importantly, disks take care of the bad blocks themselves

Backups

Consistency


==== Start Lecture #10 ====

4.3.6 File System Performance

Buffer cache or block cache

An in memory cache of disk blocks

4.4: Security

Very serious subject. Could easily be a course in itself. My treatment is very brief.

4.4.1: Security environment

  1. Accidental data loss
    • Fires, floods, etc
    • System errors
    • Human errors
  2. Intruders
    • Sadly an enormous problem now.
    • NYU ``greeting'' now doesn't include ``welcome'' (that was interpreted as some sort of license to break in).
      Indeed, the greeting is not friendly. It once was.
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
               WARNING:  UNAUTHORIZED PERSONS ........ DO NOT PROCEED
               ~~~~~~~   ~~~~~~~~~~~~~~~~~~~~          ~~~~~~~~~~~~~~
     This computer system is operated by New York University (NYU) and may be
     accessed only by authorized users.  Authorized users are granted specific,
     limited privileges in their use of the system.  The data and programs
     in this system may not be accessed, copied, modified, or disclosed without
     prior approval of NYU.  Access and use, or causing access and use, of this
     computer system by anyone other than as permitted by NYU are strictly pro-
     hibited by NYU and by law and may subject an unauthorized user, including
     unauthorized employees, to criminal and civil penalties as well as NYU-
     initiated disciplinary proceedings.  The use of this system is routinely
     monitored and recorded, and anyone accessing this system consents to such
     monitoring and recording.  Questions regarding this access policy or other
     topics should be directed (by e-mail) to comment@nyu.edu or (by phone) to 
     212-998-3333.
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        
  3. Privacy

    An enormously serious (societal) subject

4.4.2: Famous flaws

4.4.3: The internet worm

4.4.4: Generic Security attacks

More bathroom reading

Viruses

4.4.5: Design principles for security

Bathroom

4.4.6: User authentication

Passwords

Homework: 15, 16, 19, 24.

4.5: Protection mechanisms

4.5.1: Protection domains

4.5.2: Access Control Lists (ACLs)

Keep the columns of the matrix separate and only keep the nonnull entries.

4.5.3: Capabilities

Keep the rows of the matrix separate and only keep the nonnull entries.

4.5.4: Protection models

Give objects and subjects security levels and enforce

  1. A subject may read only those objects whose level is at or below her own.
  2. A subject may write only those objects whose level is at or above her own.

4.5.5: Covert channels

The bad guys are getting smart and use other means of getting out information. For example give good service for a zero and bad for a one. The figure of merit is what rate can bits be sent, i.e. the bandwidth of the covert channel.

Homework: 20.


==== Start Lecture #11 ====

Chapter 5: Input/Output

5.1: Principles of I/O Hardware

5.1.1: I/O Devices

5.1.2: Device Controllers

These are the ``real devices'' as far as the OS is concerned. That is the OS code is written with the controller spec in hand not with the device spec.

The figure in the book is so oversimplfied as to be borderline false. The following picture is closer to the truth (but really there are several I/O buses of different speeds).

Homework: 2

5.1.3: Direct Memory Access (DMA)

Homework: 5

5.2: Principles of I/O Software

As with any large software system, good design and layering is important.

5.2.1: Goals of the I/O Software

Device independence

We want to have most of the OS, unaware of the characteristics of the specific devices attached to the system. Indeed we also want the OS to be largely unaware of the cpu type itself.

It is thanks to this device independence that programs can be written to write and read generic devices and then at run time specific devices are assigned. Writing to a disk has differences from writing to a terminal, but unix cp (dos copy) doesn't see these differences. Indeed, most of the OS, including the filesystem code, Is unaware of whether the device is a floppy or hard disk.

Uniform naming

Recall that we discussed the value of the name space implemented by filesystems. There is no dependence between the name of the file and the device on which it is stored.

Error handling

There are several aspects to error handling including: detection, correction (if possible) and reporting.
  1. Detection should be done as close to where the error occurred as possible before more damage is done (fault containment). This is not trivial.

  2. Correction is sometimes easy, for example ECC memory does this automatically (but the OS wants to know about it and schedule replacement of the faulty chips before unrecoverable double errors occur).

    Other easy cases include successful retries for failed ethernet transmissions. In this example, while logging is appropriate, it is quite reasonable for no action to be taken.

  3. Error reporting tends to be awful. The trouble is that the error occurs occurs at a low level but by the time it is reported the context is lost. Unix/linux in particular is horrible in this area.

Creating the illusion of synchronous I/O

Sharable vs dedicated devices

For devices like printers and tape drives, only one user at a time is permitted. These are called serially resuable devices and are studied next chapter.

Layering

Layers of abstraction as usual prove to be effective. Most systems are believed to use the following layers (but for many systems, the OS code is not available for inspection).

  1. User level I/O routines
  2. Device independent I/O software
  3. Device drivers
  4. Interrupt handlers

We give a bottom up explanation.

5.2.2: Interrupt Handlers

We discussed an interrupt handler before when studying page faults. Then it was called ``assembly language code''.

In the present case, we have a process (actually the device driver OS code running in behalf of a user process) blocked on I/O and the I/O event has just completed. So the goal is to make the process ready. Possible methods are.

5.2.3: Device Drivers

The portion of the OS that ``knows'' the characteristics of the controler.

The driver has two ``parts'' corresponding to its two access points. Recall the following figure from the beginning of the course.

  1. Access by the main line OS with an I/O request.
  2. Accessed by the interrupt handler when the I/O completes (this completion is signaled by an interrupt).

Tanenbaum describes the actions of the driver assuming it is implemented as a process (which he recommends). I give both that view point and the self-service paradigm in which the driver is invoked by the OS acting in behalf of a user process (more precisely the process shifts into kernel mode).

Driver as a process (tanenbaum)

Driver in a self-service paradigm

5.2.4: Device-Independent I/O Software

Most of the functionality. But not necessarily most of the code since there can be many drivers all doing essentially the same thing is slightely different way due to slightly different controllers.

5.2.5: User-Space Software

A good deal of I/O code is actually executed in user space. Some is in library routines linked into user programs and some is in daemon processes.

Homework:

Homework: 6, 7, 8.

5.3: Disks

The ideal storage device is

  1. Fast
  2. Big (in capacity)
  3. Cheap
  4. Impossible

Disks are big and cheap, but slow.

5.3.1: Disk Hardware

Show a real disk opened up and illustrate the components

Overlapping I/O operations is important. Many controllers can do overlapped seeks, i.e. issue a seek to one disk while another is already seeking.

Despite what Tannenbaum says, modern disks cheat and do not have the same number of sectors on outer cylinders as on inner one. Often the controller ``cover for them'' and protect the lie.

Again contrary to Tannenbaum, it is not true that when one head is reading from cylinder C, all the heads can read from cylinder C with no penalty.


==== Start Lecture #12 ====

5.3.2: Disk Arm Scheduling Algorithms

These algorithms are relevant only if there are several I/O requests pending. For many PCs this is not the case. For most commercial applications, I/O is crucial.

  1. FCFS (First Come First Served): Simple but has long delays.
  2. Pick: Same as FCFS but pick up requests for cylinders that are passed on the way to the next FCFS request
  3. SSTF (Shortest Seek Time First): Greedy algorithm. Can starve requests for outer cylinders and almost always favors middle requests.
  4. Scan (Look, Elevator): The method used by an old fashioned jukebox (rember ``Happy Days'') and by elevators. The disk arm proceeds in one direction picking up all requests until there are no more requests in this direction at which point it goes back the other direction. This favors requests in the middle, but can't starve any requests.
  5. C-Scan (C-look, Circular Scan/Look): Similar to Scan but only service requests when moving in one direction. When going in the other direction, go directly to the furthest away request. This doesn't favor any spot on the disk. Indeed, it treats the cylinders as though they were a clock, i.e. after the highest numbered cylinder comes cylinder 0.
  6. N-step Scan: This is what the natural implementation of Scan gives.
    • While the disk is servicing a Scan direction, the controller gathers up new requests and sorts them.
    • At the end of the current sweep, the new list becomes the next sweep.

Minimizing Rotational Latency

Use Scan, which is the same as C-Scan. Why?
Because the disk only rotates in one direction.

Homework: 9, 10.

RAID (Redundant Array of Inexpensive Disks)

Tannenbaum's treatment is not very good.

5.3.3: Error Handling

Disks error rates have dropped in recent years. Moreover, bad block forwarding is done by the controller (or disk electronic).

5.3.4: Track Caching

Often the disk/controller caches a track, since the seek penalty has already been paid. In fact modern disks have megabyte caches that hold recently read blocks. Since modern disks cheat and don't have the same number of blocks on each track, it is better for the disk electronics to do the caching since it is the only part of the system to know the true geometry.

5.3.5: Ram Disks

5.4: Clocks

Also called timers.

5.4.1: Clock Hardware


5.4.2: Clock Software

  1. TOD: Bump a counter each tick (clock interupt). If counter is only 32 bits must worry about overflow so keep two counters: low order and high order.

  2. Time quantum for RR: Decrement a counter at each tick quantum expires when counter is zero. Load this counter when the scheduler runs a process.

  3. Accounting: At each tick, bump a counter in the process table entry for the currently running process.

  4. Alarm system call and system alarms:
    • Users can request an alarm at some future time and the system also needs to do things specific future times (e.g. turn off floppy motor).
    • The conceptually simplist solution is to have one timer for each event. Instead, we simulate many timers with just one.
    • The data structure on the right works well.
    • The time in each list entry is the time after the preceeding entry that this entry's alarm is to ring. The other entry is a pointer to the action to perform.
    • At each tick, decrement next-signal.
    • When next-signal goes to zero. process the first entry on the list and any others following immediately after with a time of zero (which means they are to be simultaneous with this alarm. Then set next-signal to the value in the next alarm

  5. Profiling
    • Want a histogram giving how much time was spent in each 1KB (say) block of code.
    • At each tick check the PC and bump the appropriate counter.
    • At the end of the run can assign the 1K blocks to software modules.
    • If use fine grainularity (say 10B instead of 1KB) get higher accuracy but more memory overhead.

Homework: 12

5.5: Terminals

5.5.1: Terminal Hardware

Quite dated. It is true that modern systems can communicate to a hardwired ascii terminal, but most don't. Serial ports are used, but they are normally connected to modems and then some protocol (SLIP, PPP) is used not just a stream of ascii characters.

5.5.2: Memory-Mapped Terminals


==== Start Lecture #13 ====

5.5.3: Input Software

5.5.4: Output Software

Again too dated and the truth is too complicated to deal with in a few minutes.

Homework: 16.

Chapter 6: Deadlocks

A deadlock occurs when a every member of a set of processes is waiting for an event that can only be caused by a member of the set. Often the event waited for is the release of a resource.

In the automotive world deadlocks are called gridlocks.

Reward: One point extra credit on the final exam for anyone who brings a real (e.g., newspaper) picture of an automotive deadlock. You must bring the clipping to the final and it must be in good condition. Hand it in with your exam paper.

For a computer science example consider two processes A and B that each want to print a file currently on tape.

  1. A has obtained ownership of the printer (but will release it when it finished printing).
  2. B has obtained ownership of the tape drive (but will release when it has finished reading the tape).
  3. A tries to get ownership of the tape drive, but is told to wait for B to release it.
  4. B reads a block from the tape and then tries to get ownership of the printer to print the block; naturally B is told to wait for A to release the printer.

Bingo: deadlock!

6.1: Resources:

The resource is the object granted to a process.

6.2: Deadlocks

To repeat: A deadlock occurs when a every member of a set of processes is waiting for an event that can only be caused by a member of the set. Often the event waited for is the release of a resource.

6.3: Necessary conditions for deadlock

The following four conditions (Coffman; Havender) are necessary but not sufficient for deadlock. Repeat: They are not sufficient.

  1. Mutual exclusion: A resource can be assigned to at most one process at a time (no sharing).
  2. Hold and wait: A processing holding a resource is permitted to request another.
  3. No preemption: A process must release its resources; they cannot be taken away.
  4. Circular wait: There must be a chain of processes such that each member of the chain is waiting for a resource held by the next member of the chain.

6.2.2: Deadlock Modeling

On the right is the Resource Allocation Graph, also called the Resourse Graph.

Homework: 1.

Consider two concurrent processes P1 and P2 whose programs are.

P1: request R1       P2: request R2
    request R2           request R1
    release R2           release R1
    release R1           release R2

On the board draw the resource allocation graph for various possible executions of the processes, indicating when deadlock occurs and when deadlock is no longer avoidable.

There are four strategies used for dealing with deadlocks.

  1. Ignore the problem
  2. Detect deadlocks and recover from them
  3. Avoid deadlocks by carefully deciding when to allocate resources.
  4. Prevent deadlocks by violating one of the 4 necessary conditions.

6.3: Ignoring the problem--The Ostrich Algorithm

The ``put your head in the sand approach''.

6.4: Detecting Deadlocks and Recovering from them

6.4.1: Detecting Deadlocks with single unit resources

Consider the case in which there is only one instance of each resource.

To find a directed in a directed graph is not hard. The algorithm is in the book. The idea is simple.

  1. For each node in the graph do a depth first traversal (hoping the graph is a DAG (directed acyclic graph), building a list as you go down the DAG.
  2. If you ever find the same node twice on your list, you have found a directed cycle and the graph is not a DAG and deadlock exists among the processes in your current list.
  3. If you never find the same node twice, the graph is a DAG and no deadlock occurs.
  4. The searches are finite since the list size is bounded by the number of nodes.

6.4.2: Detecting Deadlocks with multiple unit resources

This is more difficult.

6.4.3: Recovery from deadlock

Preemption

Perhaps you can temporarily preempt a process. Not likely.

Rollback

Database (and other) systems take periodic checkpoints. If the system does take checkpoints, one could roll back to one.

Kill processes

Can always be done but might be painful. For example some processes have had effects that can't be simply undone. Print, launch a missle, etc.

6.5: Deadlock Avoidance

Let's see if we can tiptoe through the tulips and avoid deadlock states even though our system does permit all four of the necessary conditions for deadlock.

An optimistic resource manager is one that grants every request as soon as it can. To avoid deadlocks with all four conditions present, the manager must be smart not optimistic.

6.5.1 Resource Trajectories

I believe this is a tannenbaumism. I have never tried to teach it before but the possibility of color might make this understandable.


==== Start Lecture #14 ====

Remark: An optimistic resource manager is one that grants every request as soon as it can. To avoid deadlocks with all four conditions present, the manager must be smart not optimistic.

6.5.2: Safe States

Avoiding deadlocks given some extra knowledge.

Definition: A state is safe if there one can find an ordering of the processes such that if the processes are run in this order, they will all terminate (assuming none exceeds its claim).

A manager can determine if a state is safe.

Example 1

Example 2

Assume that Z now requests 2 units and we grant them.

Remark: An unsafe state is not necessarily a deadlocked state. Indeed, if one gets lucky all processes may terminate successfully. A safe state means that the manager can guarantee that no deadlock will occur.

6.5.3: The Banker's Algorithm (Dijkstra) for a Single Resource

The algorithm is simple: Stay in safe states.

6.5.4: The Banker's Algorithm for Multiple Resources

At a high level the algorithm is identical: Stay in safe states.

Limitations of the banker's algorithm

Homework: 11, 14 (not to be handed in).

6.6: Deadlock Prevention

Attack one of the coffman/havender conditions

6.6.1: Attacking Mutual Exclusion

Idea is to try to use spooling instead of mutual exclusion. Not possible for many kinds of resources

6.6.2: Attacking Hold and Wait

Require processes to ask for all resources in the beginning (or first release what they have and ask for it back plus new resources all at once). This is often called One Shot.

6.6.3: Attacking No Preempt

Normally not possible.

6.6.4: Attacking Circular Wait

Establish a fixed ordering of the resources and require that they be requested in this order. So if a process holds resources #34 and #54, it can request only resources #55 and higher.

It is easy to see that a cycle is now not possible.

6.7: Other Issues

6.7.1: Two-phase locking

This is covered (MUCH better) in a database text. We will skip it.

6.7.2: Non-resource deadlocks

You can get deadlock from semaphores as well as resources. This is trivial. Semaphores can be considered resources. P(S) is request S and V(S) is release S. The manager is the module implementing P and V, when the manager returns from P(S), it has granted the resource S.

6.7.3: Starvation

As usual FIFS is a good cure. Often this is done by priority aging and picking the highest priority process to get the resource. Also can periodically stop accepting new processes until all old ones get the resources.