Q: What is Interprocess Co-Operation?
A: The cooperation of processes to ensure the integrity of shared data.

Q: Give an example of shared data.
A: Print queue.

Q: What is the notion of mutual exclusion? Can assumptions be made to simplify this process?
A: Only one process may be executing code in a given critical section at any one time.
A: No assumptions should be made about the relative speed or number of processes.

Q: What does sequential consistency mean?
A: It means that the memory reads and writes issued by two programs are executed in some interleaved order, i.e. two memory operations never appear to be done at the same time.

Q: How does Dekker's algorithm work?
A: Introduces a 'turn' variable into the while comparator.

Q: What property of the hardware does Dekker's algorithm depend on?
A: Sequential Consistency.

Q: What is theory of test-and-set for mutual exclusion?
A: Modifies a word in memory, and returns an indication of its former contents, all in one atomic operation.

Q: What is a spinlock?
A: Generic name for busy_waiting synchronization methods.

Q: How do spinlocks reduce efficiency? How can this be more efficient?
A: Wastes CPU time.
A: Ensure that the time in spinlock is bounded and short.

Q: How can spinlocks cause deadlock?
A: Due to priority inversion.

Q: What is priority inversion?
A: A high priority process may busy_wait forever for a lock held by a low priority process. The high-priority process has the CPU, the low-priority process has the lock, and neither will let go until the other does.

Q: For test-and-set or swap instructions, what must the memory system allow?
A: Atomic read-modify-write cycles.

Q: Why is Dekker's algorithm not applicable in practice?
A: It is hard to generalize to N processes for N > 2.

Q: Does test-and-set method work for any N?
A: Yes

Q: Which of Dekker's algorithm or T&S method would you use for multiprocessors? Why?
A: T&S, because this method works for N processes, where as Dekker's algorithm is reduced to only N=2 processes.

Q: How can mutual exclusion be achieved via interrupts?
A: The CPU's IPL can be raised to a value that blocks all interrupts, running the critical section, then restoring the old IPL will ensure mutual exclusion in a uniprocessor.

Q: Under what conditions can mutual exclusion be achieved via interrupts?
A: Only in Kernel mode.

Q: The OS cannot execute user's code in kernel mode, so how can mutual exclusion via interrupts be used in practice?
A: The OS provides services that the user programs can use to get mutual exclusion.
A: This service CANNOT be "turn off interrupts"

Q: What is a semaphore?
A: An integer variable which can be accessed by the primitives wait and signal.

Q: What does signal(s) do?
A: Increments 's' in an atomic (indivisible) operation.

Q: What is meant by an atomic operation?
A: An operation which is indivisible.

Q: What does wait(s) do?
A: Decrements 's' when s>0 in an atomic operation.
A: When s=0 at start, the process must be delayed until some other process executes a signal on 's'.

Q: What happens if wait(s) is executed and s = 0?
A: The process must be delayed until some other process executes a 'signal' on s.

Q: In this structure of the semaphore explain what 'c' and 'q' are?
Q: typedef struct {
Q:   int c;
Q:   Queue q;
Q: } Sem
A: c is the value of the semaphore
A: q is a queue of processes suspended on the semaphore when c = 0.
A: Wait and Signal system calls manipulate this structure.

Q: Write down 'C' code for the implementation of Wait.
A: wait (Sem *s)
A: {
A:  intr_off();
A:  if (s->c > 0)
A:    s->c--;
A:  else
A:    suspend(s->q);

Q: What does 'suspend' in the implementation of wait do?
A: It enters the process ID in the queue, then blocks the process.

Q: What happens when wait exits?
A: The scheduler will select the next process to run.

Q: Write down code for the implementation of Signal.
A: signal (Sem *s)
A: {
A:  intr_off();
A:  if (nonempty(s->q))
A:      activate(s->q);
A:  else
A:      s->c++;

Q: What does 'activate' in the implementation of Signal do?
A: Removes a process id from the queue, it then changes this process to 'READY'.

Q: What happens after a signal (in terms of the scheduler)?
A: The scheduler may or may not schedule the newly ready process.

Q: On multiprocessors, blocking interrupts is not enough for mutual exclusion. What is needed to get exclusive access to a semaphore on a MP system?
A: A MP kernel should reserve a lock for each semaphore, and wait and signal should call 'enter_cs' on this lock just after 'intr_off' and 'leave_cs' just before 'intr_on'.
A: i.e.
A: intr_off
A: enter_cs
A: .......

Q: Write the code for test-and-set (680x0) implementation.
Q: enter_cs
Q: loop
Q: leave_cs
Q: lock
A: enter_cs:  move.l  #lock,a0
A: loop:     tas      a0@
A:          bne     loop
A:          rts
A: leave_cs:  move.b  #0, lock
A:          rts
A: lock:      dc.b     0

Q: Why would you want small grains on frequently used objects? Why not on infrequently used objects?
A: To reduce the probability that two or more processors want the same lock at the same time. If this happens, all processors except the first, must be idle.
A: This probability is low for infrequently used objects, so large grain locks are sufficient.

Q: Just as semaphores need locks, other data structures should also be guarded by their own locks. Give an example.
A: The process table manipulated by suspend and activate.

Q: What is the role of the producer in the producer-consumer problem? When can it do this?
A: Producers put information into the buffer, it can only deposit items into the pool when space is available for them.

Q: What is the role of the consumer in the producer-consumer problem? When can it do this?
A: Consumers remove information from the buffer, it can only extract items from the pool when they are available.

Q: What is the producer-consumer problem?
A: When two sets of processes share a single buffer of fixed size.

Q: Write the solution of the producer/consumer problem [not with Monitors].
A: mutex = 1;
A: space = N;
A: item = 0;
A: Producer      Consumer
A: wait(space);   wait(item);
A: wait(mutex);   wait(mutex);
A: deposit        extract

Q: Write a DEADLOCK-Prone solution to the producer-consumer problem?
A: mutex=1;
A: space=N;
A: item=0;
A: Producer    Consumer
A: wait(mutex); wait(mutex);
A: wait(space);  wait(item);
A: deposit      extract

Q: Why does the DEADLOCK-prone solution of the producer-consumer problem cause difficulties?
A: Because a producer who wants to deposit an item when the buffer is full will prevent consumers from creating the space it needs to proceed and vice-versa.

Q: What is the readers and writers dilemma?
A: Two sets of processes share a single piece of data.

Q: In the readers and writers problem, explain how readers and writers treated? Where is the priority held here?
A: Multiple readers can access the data concurrently, the writers need exclusive access.
A: Reads have priority over writes.

Q: What are the two kinds of synchronization required for Readers and Writers problem?
A: 1. Between readers and writers
A: 2. Among readers

Q: Write code for Readers and Writers solution.
A: mutex=1; w=1;
A: Reader             Writer
A: wait(mutex);
A: readers++;
A: if (readers==1)
A:  wait(w);

Q: In the readers and writers solution, what problem can occur?
A: A steady stream of readers may block all writers forever.  Causing starvation.

Q: What is a monitor?
A: A collection of procedures, variables and data structures grouped together in a special kind of module that is tailored for concurrent environments.

Q: How is mutual exclusion guaranteed by monitors?
A: Because at any instant, at most one process may be active inside a monitor.

Q: Co-operation is the responsibility of the programmer. To help the programmer, what do monitors provide? What are these essentially?
A: Monitors provide CONDITION VARIABLES.
A: These are essentially queues of processes.

Q: What happens when a process calls a wait on a condition variable?
A: It releases mutual exclusion, and is blocked until another process signals on that variable.

Q: What happens when a process calls a signal operation on a condition variable?
A: Releases mutual exclusion to the newly unblocked process. It schedules one of the waiting processes to run immediately. If no processes are waiting, the signal operation has no effect.

Q: Are wait/signal on conditional variables related to wait/signal on semaphores?
A: NOT AT ALL.

Q: What happens to invariants established by the signaling process when using monitors?
A: They will still be intact when the waiting process resumes execution.

Q: Give Pascal implementation of Monitors to Producer/Consumer problem.
A: monitor bounded_buffer
A: var
A:   data, space: condition
A:   items: integer
A:   ...other declarations....
A: procedure producer(i: item)

Q: What fields does the standard implementation of monitors associate with each monitor?
A: 1. Mutual Exclusion semaphore
A: 2. Count of processes sleeping after invoking signal.
A: 3. Semaphore for these processes to block on.

Q: What fields does the standard implementation of monitors associate with each condition variable?
A: 1. Count of processes waiting for a given condition.
A: 2. Semaphore for these processes to block on.

Q: What does the semantics of monitors require (in terms of order of events)?
Q: What are possible solutions to this?
A: Newly activated processes run first
A: Signaling processes run next
A: Processes trying to enter the monitor run last.
A: Solution: Doing its own scheduling [portable], or rely on known properties of the scheduler [simpler to write]

Q: When you have several objects of a given type that you want to protect with mutual exclusion, what are two approaches?
A: 1. Make one monitor/semaphore/lock to protect them ALL
A: 2. One for each object.

Q: What are the advantages of making one monitor/semaphore/lock to protect all objects?
A: Requires less memory and has less overhead if you access two objects of the same type.

Q: What are the advantages of making one monitor/semaphore/lock to protect only one object?
A: Permits more parallelism, as several processes can operate on several objects at the same time.

Q: How do Kernels for multiprocessors decide on lock granularity for objects?
A: Infrequently Used Objects = Large Grain Locks
A: Frequently Used Objects = Small Grain Locks

Q: What is meant by a deadlock?
A: When every process in the deadlock set is waiting for an event that only another process in the set can cause. The event is usually a resource, I/O device, block of memory, a lock etc.

Q: What four conditions must be satisfied before a deadlock can occur?
A: 1. [Mutual Exclusion] Processes must have exclusive access to resources.
A: 2. [No Preemption] A resource cannot be forcibly taken away from a process until that process explicitly releases that resource.
A: 3. [Hold And Wait] A process currently holding resources can request new resources.

Q: When is the Ostrich algorithm used?
A: e.g. if deadlock occurs once every 50 years, while crashes due to hardware failures, compiler errors and OS bugs occurs once a month.

Q: What is the Ostrich Algorithm?
A: Simplest approach, pretend there is no problem at all.

Q: In Unix, deadlocks can occur by competition for process table entries and swap space. These resources can be freed by killing a process, but what problem occurs?
A: The creation of the kill process itself requires both resources.

Q: What is involved in deadlock detection and recovery?
A: 1. Keep track of resource graph and check for existence of cycles.
A: 2. If cycle exists, pick one process in each cycle and kill it, releasing its
A:   resources.
A: 3. Restart processes.

Q: What can be done to prevent deadlocks?
A: 1. Allow only one process to access a resource.
A: 2. Allow OS to take resources away from processes (preemption).
A: 3. Require processes to allocate all their resources in one step.
A: 4. Rule out cycles by classifying resources into N classes.

Q: In deadlock prevention, the OS can allow only one process to access a resource. What is needed? Why is its applicability limited?
A: Needed: Mutual exclusion is required.
A: Limited: Many devices (disks/tapes) cannot be spooled.

Q: What is the strategy used by spoolers in deadlock prevention?
A: Allowing only one process to access a resource.

Q: In deadlock prevention, we can allow the OS to preempt resources from processes. When is this not acceptable?
A: For large classes of resources (e.g. printers, tape drives).

Q: In deadlock prevention, the OS can require processes to allocate all their resources in one step. What does this require?
A: Requires:
A: 1. Processes to know their resource requirements in advance [not usually available]
A: 2. Processes must release all their resources before requesting another set. [voluntary preemption]

Q: In deadlock prevention, we can rule out cycles by classifying resources into N classes. Explain what this means.
A: If a process holds a resource of class 'j', it can only request resources of class i , where i > j.
A: Within each class, all resources must be claimed in a single request.

Q: How is deadlock avoided? What does this require of the process?
A: OS analyses each request and grants it only if it can prove that it will not lead to deadlock.
A: Requires: Advance knowledge of the maximum requirement of each process for each resource type. [Available in a few environments].

Q: What are the strategies for dealing with deadlocks?
A: 1. Ignore the problem
A: 2. Detect deadlock and recover.
A: 3. Prevent deadlocks statically by permanently negating one of the four necessary conditions.
A: 4. Avoid deadlocks dynamically, by not allocating a resource to a process if that allocation can be part of a deadlock chain.

Q: In the Banker's algorithm, what is meant by an unsafe state?
A: May/will lead to deadlock.

Q: What is meant by a safe state?
A: A state in which there exists a sequence of other states that leads to all processes getting resources up to their maximum requirements.

Q: What must be maintained for multiple resource types?
A: 1. Current Allocation
A: 2. Maximum Requirements
A: 3. Available Resources

Q: Describe a safety check algorithm [Banker's] in pseudo code.
A: While (some processes remain)
A:  1. Look for a process whose unmet resources are smaller or equal to the available resources. If this row doesn't exist, system will eventually lead to deadlock.
A:  2. Mark chosen row as terminated and add its resources to the Available resources vector.
A: Loop (until all processes are marked terminated)

Q: What is the difference between implicit and explicit scheduling? Where is implicit scheduling used?
A: Explicit scheduling, done on a higher level using the OS process scheduler.
A: Implicit scheduling, scheduling done within the process itself.
A: Implicit scheduling is used for the semantics of monitors, that require certain events occur at certain times.

Q: Give a summary form of Deadlock Prevention when compared to Deadlock Cause.
A: Problem ---> Solution
A: -----------------------------
A: Mutual Exclusion ----> Spool everything
A: Hold and Wait ----> Request all resources initially
A: No Preemption ----> Take resources away
A: Circular Wait ----> Order resources numerically

Q: Why is Banker's algorithm not applicable in practice? Can you recommend another approach?
A: Processes rarely know what their maximum resource needs will be in advance.
A: Number of processes is not fixed.
A: Resources thought to be available can vanish.
A: Another approach: Two-Phase locking.
