CS 481: Solutions for Test #1 |
Problem 1. You have a preemptive scheduling system that works on the following principle: every fixed time period (quantum), a clock interrupts the current process and the OS evaluates the priority of each process in the ready queue (including the process interrupted), choosing that process to dispatch next which has the highest priority. The priority of a process changes with time: for each unit of time spent running, its priority increases by alpha and for each unit spent waiting in the ready queue its priority increases by beta. (Time spent blocked does not affect the priority.) alpha and beta are real-valued constants that can be negative, zero, or positive, depending on the goals of the scheduler.
The priority goes up faster when running than when waiting in the ready queue. Lowest-priority processes are those entering the system. So we have an aging policy (priority goes up when in the ready queue) and a policy that favors long jobs that use full quanta (your priority goes up at each turn around the queue, but goes up fastest if you use the full quantum). The result is a very heavy bias in favor of long, CPU-bound jobs and against I/O bound-jobs. We might want to call this policy longest-job-first.
The priority goes down whenever the process is not blocked and goes down faster when waiting in the ready queue than when running. Highest priority is always to new processes. Thus there is a negative aging policy. Processes that are mostly I/O-bound will do well, since their priorities are unaffected when blocked. But the most favored processes will be those that can complete in a single quantum. This is essentially a shortest-job-first policy.
It is very flexible, but very expensive: at each quantum (or at least every few quanta) the priority of every job in the ready queue must be recomputed; moreover, the ready queue must be a priority queue and thus the dispatcher must spend O(log n) time to get the highest-priority process. Too expensive to be worth the trouble.
Problem 2. In steady state, a system composed of two identical CPUs and three identical I/O devices has an average of 5 jobs. Assume that the rate of job completion of a single CPU is alpha and the rate of job completion of a single I/O device is beta.
There are 6 states, corresponding to the 6 possible partitions of the 5 jobs into CPU vs. I/O: (5,0), (4,1), (3,2), (2,3), (1,4), (0,5). We get the following states and transitions, where R denotes running on a CPU, W waiting for a CPU, I doing I/O, B blocked waiting for I/O:
1 2 3 4 5 6 -RR -RR -RR -RR -R- --- WWW -WW -W- --- --- --- --- -I- -II III III III --- --- --- --- -B- -BB
The transition rates are 2*alpha from 1 to 2, 2 to 3, 3 to 4, and 4 to 5, and alpha from 5 to 6; and are 3*beta from 6 to 5, 5 to 4, and 4 to 3, 2*beta from 3 to 2, and beta from 2 to 1.
Denote the probabilities by p1, p2, p3, p4, p5, and p6. We have 6 equations: one is the binding equation p1+p2+p3+p4+p5+p6=1. The other are the equilibrium equations at each partition:
p1*2*alpha = p2*1*beta p2*2*alpha = p3*2*beta p3*2*alpha = p4*3*beta p4*2*alpha = p5*3*beta p5*1*alpha = p6*3*beta
All CPUs are busy in the first 4 states, so the desired probability is simply p1+p2+p3+p4. We never have over half the jobs waiting for I/O, so that probability is 0.
Problem 3. Suppose you need a type of semaphore that allows you to wait on several resources at once (e.g., to avoid partial allocation and thus potential deadlocks). That is, you need a semaphore with operation P(r1,r2,...,rn), where the process is allowed to move one only if each of the n resources r1, r2, ..., rn is available.
The basic idea is to use a single binary semaphore mutex to protect all of the resource counters/flags for r1 through rn. The P operation does a P(mutex); if any of the resource counters/flags is non-positive, it leaves them unchanged, releases the exclusion with a V(mutex), and goes to sleep on another binary semaphore, P(sleep). On waking up, we start over again at P(mutex). If all counters/flags are strictly positive, we update each counter/flag, release the exclusion with a V(mutex), and proceed. This is essentially the same solution given during the test for homework #3.
We do not need a matching V; however, the V(ri) will actually be implemented
as a subroutine of its own, which uses the mutex semaphore to access the
counter ri and always wakes up a process sleeping on semaphore sleep, just
to give it a chance to check things out. Hence
P(mutex)
update ri
V(mutex)
V(sleep)
Problem 4. Starvation in resource allocation occurs when a process cannot obtain a resource no matter how long it tries. We have seen an example of starvation through conspiracy in the dining philosophers problem: neighbors i-1 and i+1 can conspire to starve (literally) philosopher i.
If we have an even number of philospohers, do the following. Have odd and even turns; at each turn, only philosophers whose number has the proper parity can eat. There cannot be deadlock, since there is no shared resource between philosophers of the same parity; there cannot be conspiracy, for the same reason. Starvation cannot occur at all, since no philosopher eats forever. If we have an odd number of philosophers, we can have odd, even, and leftover turns, where the last philosopher, although odd, is not allowed to participate in odd turn, but is by him/herself in the "leftover" turn.
In any system where partial resource allocation is not allowed and where processes need varying amounts of resources, any process that needs an abnormally high amount of resources is likely to starve, unless the scheduler has an aging policy.
No; the best the OS can do is verify that a process has been blocked for a very long time -- which need not denote starvation. However, it is also the one thing that the OS can do to prevent starvation: have an aging policy that eventually gives very high priority to jobs that have been blocked a long time, so that jobs that need fewer resources and might otherwise pass head will be denied the resources they need until the OS has accumulated enough free resources to fulfill the request of the high-priority job.
| Back to CS 481 home page |