CS444 Previous Midterm Exam,  for practice, F13

Open books, notes, handouts.

Write on these pages, using the backs if need be (I hope not.)

Each problem is worth 20 points.

 

1.      Consider the system implemented in hw1.

 

a.       Although testio.c has calls such as write(dev, buff, nbytes), that look like system calls (the arguments to write are good, and write is a UNIX system call), we don’t consider this to be a “system call”.  Explain why, and explain how execution reaches ttywrite from this call.

 

b.      Suppose the UART transmitter becomes ready to accept another byte while the code in testio.c is running. Is IF=0 or IF=1 at this moment?

 

c.       Is IF=1 at any point during the execution of ttywrite?  At all points?

 

d.      After an interrupt cycle happens in the CPU, what software function (assembler or C) first executes?  Which one last executes at the end of the interrupt handling, just before the interrupted program resumes execution?

 

e.       What CPU instruction restores the CPU state off the stack to undo the interrupt cycle’s CPU state-saving?

 

 

 

 

 

  1. A major goal of modern operating systems is user-kernel separation.
  1. Why is this important?

 

 

 

 

  1. The OS makes sure that the user programs need to use system calls to ask for services (other than a few infrastructure services like time-sharing and automatic stacks).  The system call then becomes the focus of user-kernel communication. How many instruction cycles are involved in changing from user-level to kernel-level execution in a system call? 

 

c.       How does the kernel know which system call the user wants (assume Linux here, as in hw2 setup).

 

d.      Does the kernel need to turn off interrupts for all of system call code execution?  Why or why not?

 

 

 

 

 

 

 

 


 

  1. We have seen the need for mutual exclusion (mutex) even in hw1, a single-program system. 
  1. Explain this need—what could happen, in hw1, and by what execution scenarios?

 

 

 

 

  1. Explain how we provided mutex.

 

 

 

 

 

4.      Consider this Java code:

First a Semaphore is created this way:  Semaphore sem1 = new Semaphore(2);

            Second, four threads A, B, and C, and D each call sem1.acquire(); in A, B, C, D order.  At the end of this sequence, which threads are blocked by the semaphore and which ones are continuing to execute other code?

 

 

            Note that A was not blocked. If A now calls sem1.release(), what will happen?

 

 

 

 

 

 

5.      Consider the multi-threaded Web server described in Tanenbaum on pg. 99, and assume kernel-supported threads are in use.  Suppose there are 5 worker threads and one dispatcher thread, which is the process’s original thread.

 

  1. How many stacks are there in the user process image?
  2. Find the points at which a worker could block, and similarly, where the dispatcher could block (which lines of code?  mark them below)
  3. Find the points that generate an event that unblocks (there’s only one spot in this code that has to have an unblock action.)  Again, mark that line in the code.
  4. Why is a pointer (&buf) sufficient as communication between the dispatcher and the worker—why can they use the same pointer value to access the buffer?

 

 

 

/* dispatcher */

while (TRUE) {

   get_next_request(&buf);

   handoff_work(&buf);

}

 

/* worker */

while (TRUE) {

   wait_for_work(&buf);

   look_for_page_in_cache(&buf, &page);

   if (page_not_in_cache(&page))

      read_page_from_disk(&buf, &page);

   return_page(&page);

}