CS3013 Practice Midterm Exam

  1. We discussed four ways in which operating systems are structured. Which of these structures is easiest to extend to a distributed system? Briefly explain why.

  2. What is context switching? How is the process table used in context switching?

  3. What does the operating system do at process scheduling time when no processes are ready to run?

  4. What are the possible outputs when the following code is run on a Unix system?
    int n;
    
    main(int argc, char **argv)
    {
        n = 0;
    
        if (fork() == 0)
            n = n + 5;
        else
            n = n + 7;
        printf("n = %d\n", n);
    }
    

  5. Why do the following routines not work for solving the problem of mutual exclusion?
    #define TRUE 1
    #define FALSE 0
    int mutex;         /* also called lock variable */
    
    BeginRegion()      /* Loop until safe to enter */
    {
        while (mutex) 
            ; /* do nothing until FALSE */
        mutex = TRUE;
    }
    
    EndRegion()       /* Exit critical section */
    {
        mutex = FALSE;
    }
    

  6. Consider a single processor timesharing system that supports a large number of interactive users with a round robin scheduling policy. Each process gets up to a quantum of time to execute each timeslice.

    1. What would be the effect of setting the quantum to a large value, say 10 minutes?

    2. What if the quantum were set to a small value, say a few processor cycles?

    3. Suppose you could turn a dial and vary the quantum between these two extremes. How do you know when you have chosen the "right" value. What factors make it right from the user's standpoint? What factors make it right from the system's standpoint?

  7. Explain the difference between a preemptive and a non-preemptive process scheduling policy. Why do all interactive systems use premptive polcies even though these policies have a higher overhead?

  8. Consider the following portion of a major city map indicating two-way streets and intersections. Using processes to model the cars on the streets, discuss how these processes can be coordinated using primitives we have talked about so that no accidents occur in the intersections. There is not a single correct answer to this question, and you may give multiple answers. However, each answer should indicate you understand the implications of the approach.

  9. Consider the two processes A and B in the following example with the global variable x, which is shared between the two processes. Assume that the routine atomicprintf() works just like printf() except it cannot be interrupted. 1. What is printed by the two processes in the example (give all possibilities)? 2. What is the final value of x after both processes complete (give all possibilities)? 3. What synchronization problem does this example illustrate?
    int x = 0;  /* global shared variable (not Unix!) */
    
    ProcessA()
    {
        int i;
    
        i = x;
        i = i + 2;
        x = i;
        atomicprintf("x = %d\n", x);
    }    
    
    ProcessB()
    {
        int i;
    
        i = x;
        i = i + 1;
        x = i;
        atomicprintf("x = %d\n", x);
    }
    

  10. Is the pipe abstraction in the Unix operating system an example of a mutual exclusion or producer/consumer problem?

  11. Processes can be in one of three states: running, ready and blocked. Show the possible transitions between these states and the reason for each transition.

  12. Most machines provide an atomic "test and set" instruction for the purpose of implementing mutual exclusion for protection of critical regions. Using this instruction BeginRegion() and EndRegion() can be written as:
    int mutex;
    
    BeginRegion()      /* Loop until safe to enter */
    {
        while (test_and_set(&mutex, TRUE)) ;
            /* Loop until return value is FALSE  */;
    }
    
    EndRegion()
    {
        mutex = FALSE;
    }
    Suppose that instead of a ``test and set'' instruction, our machine provides an exchange instruction of the form EXCH(A, &x), which exchanges the contents of a register (A) and a memory word ( x) in a single atomic instruction. The following shows how this instruction works assuming we can directly access a register (again remember the instruction is done in an atomic manner). Show how the instruction can be used to implement BeginRegion() and EndRegion().
    void EXCH(REGISTER A, int *pVar)
    {
        REGISTER tmp;
    
        tmp = A;
        A = *pVar;
        *pVar = tmp;
    }

  13. What are the differences between user-level threads and kernel-supported threads? Under what circumstances is one type "better" than another?

  14. Consider the following monitor for the Readers-Writers problem:
    monitor reader-writer {
      condition mutex, wrt;
    
      void write() {
    	  wrt.wait;
    	  /* writing is performed */
    	  wrt.signal;
    	}
    
      void read() {
    	  mutex.wait;
    	    readcount = readcount + 1;
    	    if (readcount == 1) 
              wrt.wait;
    	  mutex.signal;
    	  /* reading is performed */
    	  mutex.wait;
    	    readcount = readcount - 1;
    	    if (readcount == 0)
              wrt.signal;
    	  mutex.signal;
      }
      
      main() {
         readcount = 0;
      }
    
    Does the solution satisfy all conditions for correct critical region operation? If not, name one condition that may be violated and give a reason why:

  15. Five processes are waiting to run. Their expected run times are 9, 6, 3, 5 and X. In what order should they be run to minimize average waiting time? (Your answer will depend upon X).

  16. Suppose we have a message-passing system using mailboxes. When sending to a full mailbox or trying to receive from an empty one, a process does not block. Instead, it gets an error code back. The process responds to the error code by just trying again, over and over, until it succeeds. Does this scheme lead to race conditions?

  17. In his exposition against Linux, Dr. Andrew Tannenbaum contrasts Monolithic operating systems (those having a simple structure) such as Linux to Micro-Kernel operating systems such as MINIX or Mach. Take one position either pro-Monolithic (Simple) operating systems or pro-Micro-Kernel operating systems and give a brief argument supporting your position.

Return to the CS3013 Home Page