CS 3204 Operating Systems Midterm (Abrams) Spring 2004 VIRG INIA POLYTECHNIC INSTITUTE AND STATE U T PRO SI M UNI VERSI TY Instructions: Do not start the test until instructed to do so! Print your name in the space provided below. This examination is closed book and closed notes. No calculators or other computing devices may be used. Answer each question in the space provided. If you need to continue an answer onto the back of a page, clearly indicate that and label the continuation with the question number. If you want partial credit, justify your answers, even when justification is not explicitly required. When you have completed the test, sign the pledge below and turn in the test. Note that either failing to return this test, or discussing its content with a student who has not taken it is a violation of the Honor Code. Print Your Name: Pledge: On my honor, I have neither given nor received unauthorized aid on this examination. Sign your name: Problem Long1 Long2 Long3 Long4 Short1 Short2 Short3 Short4 Short5 Short6 Total Grade /10 /20 /25 /24 /3 /5 /2 /1 /5 /5 /100 1 of 1
CS 3204 Operating Systems Midterm (Abrams) Spring 2004 Long Answer L1. [10 points] Consider the simple run/ready/block state transition scheme for process scheduling. Draw the state diagram, showing all the possible transitions. Label each transition with a brief, precise description of an event that might cause a process to make that transition. 2 of 2
CS 3204 Operating Systems Midterm (Abrams) Spring 2004 L2. [20 points] Consider executing the two threads below, with the shared global variables that are shown. //Shared variables 1 boolean t1 = ; 2 boolean t2 = ; //Thread T1 T1.4 void main() { T1.5 while ( true ) { T1.6 t1 = ; T1.7 while ( t2 ); T1.8 //critical section code T1.9 t1 = ; T1.10 //code outside critical section T1.11 } //end while loop T1.12 } //end thread T1 // Thread T2 T2.4 void main() { T2.5 while ( true ) { T2.6 t2 = ; T2.7 while ( t1 ); T2.8 //critical section code T2.9 t2 = ; T2.10 //code outside critical section T2.11 } //end while loop T2.12 } //end thread T2 (a) [10 points] Fill in the blanks in the code above (with TRUE or FALSE) to guarantee that mutual exclusion will be achieved. (b) [10 points] Does program with your modifications in (a) guarantee that the program is free from deadlock? YES NO If you answer YES, justify your answer. If you answer NO, clearly describe an execution sequence (using line numbers) that would lead to a deadlock of the two threads. 3 of 3
CS 3204 Operating Systems Midterm (Abrams) Spring 2004 L3. [25 points] Consider executing the two threads below, with the shared global variables that are shown. //Shared variables 1 Semaphore valueproduced = new Semaphore(1); 2 Semaphore valueconsumed = new Semaphore(1); 3 int sharedvalue=2; // variable shared by Producer and Consumer //Producer thread 4 void main() { 5 int v=0; 6 while ( true ) { 7 v++; 8 P(valueConsumed); 9 sharedvalue=v; 10 V(valueProduced); 11 } // end while 12 } // end producer thread //Consumer thread 13 void main() { 14 int v; 15 while ( true ) { 16 P(valueProduced); 17 v = sharedvalue; 18 V(valueConsumed); 19 printf( %d, v); 21 } // end consumer thread (a) [5 points] List all line numbers at which a thread can potentially block. (b) [10 points] If the code as shown above is executed, would either thread block forever? YES NO If your answer is YES clearly describe an execution sequence (using line numb ers) that would lead to a thread blocking forever. If your answer is NO, justify your answer by giving a logical argument why neither thread could block forever. 4 of 4
(c) [10 points] The specification for the program above says that all executions of this program must write to standard output the sequence of integers 1,2,3,4,5,. Does the program meet the specification? YES NO If your answer is YES, justify your answer by giving a logical argument as to why this is the only possible output for any execution order. If your answer is NO, clearly describe an execution sequence (using line numbers) that generates a different output, and state what the program would write to standard output. 5
L4. [24 points, 4 points per box] After graduation from Virginia Tech, you work at a software company that is writing a new operating system. The designers are trying to decide whether to use user-level threads, kernel-level threads, or a hybrid threading model. Because you are fresh out of CS3204, you are in a great position to advise them. In the boxes below, make a list of the pros and cons of each option. User level pros: User level cons: Kernel level pros: Kernel level cons: Hybrid pros: Hybrid cons: Short Answer S1. [3 points] If three threads want to achieve mutual exclusion, which of the following algorithms could be used? a. Peterson s YES NO b. Lamport s bakery YES NO c. Dekker s YES NO S2. [5 points] Why would an operating system that uses a microkernel run faster on a multiprocessor computer than on using a monolithic design? 6
S3. [2 points] What is the difference between a system call and a normal call of a function or method in an API? S4. [1 point] Give one reason why a DVD allows storage of more data than a CD. S5. [5 points] Which of the following is a true statement: a. RISC and CISC typically use the same number of registers b. CISC microprocessors generally contain more registers c. RISC microprocessors generally uses more registers Justify your answer: S6. [5 points] Why is a kernel call often implemented by a software interrupt? Have a good break! 7
8
Solution: L1: See Figure 3.1 L2: This is the algorithm in Figure 5.8 in the book. (a) Blanks are filled in as follows: boolean t1=false; boolean t2=false; t1=true t1=false t2=true t2=false (b) NO (In the following, a correct answer can omit the items in [] or <>.) There are several correct sequences. But ANY correct answer must have T1.6 AND T2.6 executed BEFORE either of T1.7 and T2.7, and NO statements executed after T1.7 and T2.7. Here are two correct answers: [T1.4,] T1.5, T1.6, [<context switch>,] [T2.4,] T2.5, T2.6, T2.7, <T2 stays in T2.7 forever>, T1.7 <T1 stays in T2.7 forever DEADLOCK> or [T2.4,] T2.5, T2.6, T2.7, [<context switch>,] [T1.4,] T1.5, T1.6, T1.7, <DEADLOCK> L3: Comment: A key difference of the code in problem L3 from Figure 5.16 in the book is listed in item 2 in Self Review on page 231 valueproduced is initialized to 1 and not zero. (a) 8 and 16. That is because only the P() operation blocks. The V() operation and all other statements used in the program never block.. NOTE: It is optional to list statement 19. The process blocks to execute 19, unless the compiler/os do programmed I/O (which an old computer and OS or an embedded OS would do). (b) NO This is the hardest problem in the exam. To be rigorous, the answer requires a proof (or a proof outline, similar to the arguments given in Chapter 5 for why the shared memory mutual exclusion algorithms do not block a thread forever). However, full credit will be given to an answer that has the seed of the ideas needed in a proof at least the fact that the value of the semaphore named in each P operation is always larger than 1 when the P is executed (either because the thread is in its first loop iteration, or, by inductive reasoning, the thread did not block at P in the last loop iteration, and the thread only got past the P in the last iteration if the semaphore value was incremented to a value larger than 0 (by the other thread)). For the record, here is a proof outline Proof by contradiction. Assume that one thread does block forever. Let s look at the 3 possible blocking statements from part (a). [It is OPTIONAL to discuss statement 19] Statement 19 cannot block forever, because I/O to standard out will eventually complete. Stdout is either the console so nothing would block display of letters on the console or a file 9
(if stdio is redirected to a file), but even if the file system becomes full an error message would be generated and printf() would return in error. Hence statement 19 cannot block forever. Exactly one of statement 8 or 16 (or both) are blocked forever. It is impossible for exactly one of the two statements to block forever, because the other thread would eventually execute a V() operation on the semaphore whose P operation is causing blocking forever. That V operation would unblock the blocked thread. Both statement 8 AND 16 are forever blocked. This can only happen if both semaphores are 0. However, it is impossible for this case to arise. The proof is by induction. o On first iteration or each thread s loop, the semaphore is 1, so the P decrements the semaphore to 0 and does not block. Furthermore, the thread does a V on the other semaphore, so that other semaphore now has value 1 or 2. o Now assume that a thread has not blocked on its first i-1 iterations (for i>0). On the ith iteration of a thread s loop, the semaphore has value of greater than 0 (or else the iteration i-1 would have blocked; since i-1 did not block we know that the thread completed execution of the P operation, which would only have happened if the semaphore value was incremented by a V operation. Therefore, there is no statement at which either thread could block forever. (c) NO. 1,2,13,14,15,16,17,18,19 would generate 2 as the first output number. 10
L4: User level pros: Doesn t require kernel changes Facilitates portability User level cons: All threads in a process are context switched as one unit by OS. Thus if one thread did I/O, all threads would block. A process containing many threads cannot use more than one processor of a a multiprocessor. Threads get shorter timeslices because all threads share timeslice of one process. Kernel level pros: Allows every thread to be scheduled separately by OS, yielding maximum potential for parallelism, and allowing one thread to block while others continue. Can utilize multiple processors. Harder to handle signals and terminating threads. Kernel level cons: Harder to implement than user-level threading. Also, hard to make programs portable. Can create more overhead in OS needs to be one scheduler activation for every thread, which means schedule is controlling more activations (and hence larger kernel data structures), which could reduce OS performance. Hybrid pros: Allows pros of kernel-level. Allows multiple user threads to be mapped to one kernel scheduler activation ( m-to-n thread mapping ) negating last con listed for kernel level. Hybrid cons: Can be harder to create a portable program that works on any thread model. Programmer must be careful about choosing which threads to map to a single kernel activation record. If the programmer makes a bad choice, they get the disadvantages of user or kernel level threads. (For example, if the programmer maps two threads that both do I/O to the same kernel scheduler activation, the if one thread blocks for I/O the other thread must wait also.) 11
S1: a. NO (only does 2-way) b. YES (does N-way) c. NO (only does 2-way) S2: All calls to the OS kernel are serialized. Hence the kernel can run on only one processor in a multiprocessor. Therefore, to allow maximum concurrency, the kernel should do as little work as possible to minimize its execution time. A microkernel moves as much OS functionality as possible outside the kernel, thereby minimizing the kernel s execution time. All the functionality that a microkernel OS puts outside the kernel can potentially be run concurrently on multiple processors, thereby improving OS performance. S3: System call invokes operation inside the OS and ultimately the kernel, whereas normal API call invokes user space code. S4: A correct answer is either of the following: DVDs use 2 layer. DVDs use thinner tracks. S5: Correct answer is c, for either of these reasons: With a simpler instruction set, RISC does not typically have ALU instructions that access memory [just load and store instructions to access memory]. Hence RISC requires more quantities to be in registers than CISC. RISC processors have multiple copies of processor registers to permit fast context switching among a limited number of processes without requiring registers to be copied to a process control block in main memory. S6: Either of these answers is correct: An interrupt is a safe way to enter the kernel when a software interrupt occurs, the PC is changed by the processor to an address in the interrupt vector table (set by the kernel during boot time), so that the next instruction executed is inside the kernel. The processor must switch from user to privileged mode when the program counter changes to an instruction inside the kernel code. For security, a means is needed for this to happen only when a kernel call occurs a user must not be able to switch to privileged mode without entering the kernel. A software interrupt permits the mode change in a safe way. (In the above answers, safe means that a nasty user cannot enter the kernel or change to privileged mode without raising a software interrupt.) 12