Midterm Exam

CS354 Spring 2002

Name:




1. Answer True/False (T/F) (1 point each)
____ The call dup2() will show in the truss output.
____ There is a set of registers for every kernel level thread in the process table.
____ The cost of  a multiprocessor computer grows linearly with the number of CPUs.
____ A parent and a child process may communicate by a pipe created by the child.
____ If  "a" is a local variable, then &a is a memory address in the data section
____ The function strcat(a,b) allocates strlen(a) + strlen(b)  + 1 bytes of memory using malloc.
____ Disabling interrupts could be used to enforce mutual exclusion.
____ A program that runs with non- preemptive scheduling may deadlock.
____ The user time in the time command may be smaller than the system time.
____ An exit code of 1 in UNIX means success.
____ When a process calls fork, the number of open file objects in the kernel remain the same.
____ Programs that run preemptive scheduling finish sooner than programs that run with non-preemptive scheduling.
____ A program needs to run in kernel mode to install an interrupt handler in the interrupt vector.
____ The size in bytes of a variable of type (char *) is 1 byte.
____ Kernel threads in the same process share the same file descriptors.
____ The time command in mentor could show that the user time is larger than the real time in a multi-threaded program.
____ After forking a process, if an environment variable is modified in the parent it will be modified in the child.
____ The counter of a semaphore could have a negative value.
____ A moving average with an alpha=.5 gives the same weight to the previous two samples.
____ In a soft real time system jobs will always finish on time.

2. (3 pts.) What is the consequence of substituting the thread_yield() call by an empty statement in the spinlock locking code?
 
 
 
 
 
 

3. (3 pts.) What factors have to be considered when choosing the length of a quantum time?

 
 
 
 
 
 

4. (3 pts.) What are the advantages and disadvantages of using threads vs. using processes?

 
 
  

 
 

5. (3 pts.) Write the pseudocode of sema_wait and sema_post

 





6. (3 pts.) Write the regular expresion used in shell.l to represent quoted arguments, that is, arguments delimitted by "". A quoted argument  may contain spaces but no new line characters. Also, a quoted argument may have quotes if they are escaped with the character "\". Example: "This is a space between quotes: \" \" "







 
7. (10 pts.) Write the code for the function 
       char *strstr(const char *s1, const char *s2)

The strstr() function locates the first occurrence of the string s2 (excluding the terminating null character) in string s1. The strstr() function returns a pointer to the located string, or a null pointer if the string is not found. If s2 points to a string with zero length (that is, the string ""), the function returns s1.

char *strstr(const char *s1, const char *s2)
{
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
}
      

8. (10 pts.) Write the implementation of the procedure unsetenv() that removes an environment variable from the process environment. unsetenv() will return if the environment variable does not exist. Implement unsetenv as it should be implemented in the shell project.
extern char ** environ;
     
void unsetenv( char * variable ) {

       
       
       
       
       
       
       
       













}
      

9. (15 pts.) The following class implements a multi-threaded single-linked list queue of names. The enqueue() function waits if there are already maxQueueItems in the list and then adds a name to the queue. dequeue() will wait if the list is empty and then it will remove the oldest name in the queue. The enqueue() and dequeue() calls can be called simultaneously by different threads. Add the body of these functions and member variables so multiple threads can run the operations simultaneously without corrupting the name queue. The NameQueue constructor receives as parameter maxQueueItemsImportant: The queue has to be implemented as a single-linked list.
struct NameNode {
      
      
      
      
};
      
class NameQueue {
  // Extra variables here
 
 
 
 
public:
  NameQueue( int maxQueueItems ) {
    //Initialization code here
    
    
    
    
    


  }
  
  void enqueue( char * name ) {
    // Enqueues a name in the queue. Waits if queue is full










  }
  
  char * dequeue() { 
    // Dequeues a name from the queue. Waits if queue is empty.









  }
  
};
      

 
10. (15 pts.) Write a function runPipe(command1, command2) that executes command1 and command2 connected through a pipe . Command1 and command2 are  arrays of arguments that are NULL terminated. The output of command1 will be connected to the input of command2 using a pipe. Both command1 and command2 will run in different child processes. The process calling runPipe will wait until the child process that runs command2 terminates. command1 will have the same standard input of the parent process and command2 will have the same standard output of the caller process. See how runPipe is used in main() below.
int runPipe( char ** command1, char ** command2 )
{
  

















}

main()
{
  char * command1[] = {"ls", NULL};
  char * command2[] = {"grep", "aaa", NULL};

  //Prints the files in the current directory that contain the substring "aaa"
  runPipe( command1, command2 );

}


 
11. (15 pts.) Implement a message system with the following characteristics. void msgSendPrio( int msg, int priority) will send a message with the given priority and it will block until the receiver gets the message. The method int msgRecvPrio( int minPriority ) will remove and return the oldest message with a priority larger or equal to minPriority. msgRecvPrio() will wait until there is such message. Hint. You may need a linked list of waiting sender/receivers with semaphores in each list node.
// Data structures needed
      
      
      
      
      
      
      
      
      
      
      


      
      
void msgSendPrio( int msg, int priority)
{
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
}

int msgRecvPrio( int minPriority ){























}