Midterm Exam

CS354 Fall 2002

Name:



Part 1. True False Questions

Answer True/False (T/F) (1 point each)

____ A call to getenv() will show in the truss output.
____ A program that uses user-level threads will consume less system time than the same program using kernel threads.
____ execvp() will return a value of 0 if successful..
____ If  "a" is a local variable, then &a is a memory address in the stack section
____ The function strcpy(a, b) allocates strlen(a) + 1 bytes of memory using malloc.
____ By default pthread_create() creates user-level threads.
____ The user time in the time command is always smaller than the system time.
____ The close() system call always releases the resources of an open file object.
____ When a process calls fork(), the number of file descriptors in the parent process remain the same.
____ Programs that run non-preemptive scheduling finish sooner than programs that run with preemptive scheduling.
____ The OS checks the arguments of a system call in user space to save execution time.
____ The size in bytes of a variable of type (char *) is 4 bytes.
____ When a process exits, all the file descriptors of that process are closed.
____ The sum of the user and system time in a process could be larger than the real time.
____ After forking a process, a write call in the parent could modify the offset of an open file in the child.
____ The counter of a semaphore cannot have a value larger than the initial count.
____ Potentially a program could run faster in a cluster than in a multiprocessor computer assuming they have the same number and type of CPUs.
____ In a soft real time system high priority jobs will always finish on time.
____ The cost of  a multiprocessor computer grows linearly with the number of CPUs.
____ spin-locks are better than mutex_locks for small critical sections.

Part 2. Short questions.

1. (3 pts.) Assume that the thread_yield() is substituted by sleep(1) in the spin-lock call. sleep(1) makes the current thread sleep for 1 second. Answer: a) Is the new spin_lock() call going to work? b) If it does not work explain why. If it does work, explain what would be the behavior of the new lock.
 
 
 
 
 
 

2. (3 pts.) What is the impact of choosing a quantum time smaller than the average process burst?

 
 
 
 
 
 

3. (3 pts.) What are the advantages and disadvantages of using user threads vs. using kernel thrreads.

 
 
  

 
 

4. (3 pts.) Write the implementation of sema_wait and sema_post but instead of waiting use thread_yield and spinning. The implementation does not need to preserve the FIFO behavior of semaphores.

 





5. (3 pts.) Write the substitutions necessary to transform a wildcard into a regular expression.






Part 3. Programming questions.

 
6. (10 pts.) Write the code for the function 

       char *strncat(char *dst, const char *src, size_t n);

The srncat() function appends the string src at the end of the string dst. strncat() appends at most n characters from src. strncat returns a pointer to the resulting null-terminated string.

char *strncat(char *dst, const char *src, size_t n)
{





















}
8. (10 pts.) Write the implementation of the procedure putenv() that adds an environment variable to the process environment.  Assume that var_val is a string of the form VAR=VAL. If the variable already exists the old variable will be substituted with the new variable.
extern char ** environ;

void putenv( char * var_val ) {
























}

9. (15 pts.) Implement a synchronized int array class. The class will have four methods: SyncIntArray(int n) is the constructor of the class that creates an array of size n and initializes the other variables. void add(int val) will add one value to the array. The value will be stored in any unused place in the array. add() will wait until there is space available in the array. int removeAny() will return the minimum value in the array. removeAny() will wait if the array is empty. Also you will implement the procedure int getMin() that will return the minimum element in the array but it will not remove it. getMin() will wait if the array is empty.


class SyncIntArray {
// Extra variables here





public:
SyncIntArray(int n) {








}

void add(int val) {











}

int removeAny() {









}

int getMin() {









}
};

 
10. (15 pts.) Write a function runPipe(command1, command2, infile, outfile) 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. The input of command 1 will be taken from infile and the output of command2 will go to outfile. outfile will be created if it does not exist, or it will be truncated it it does exist. Both command1 and command2 will run in different child processes. The process calling runPipe will wait until the child process that runs command2 terminates. See how runPipe is used in main() below.
int runPipe( char ** command1, char ** command2, char * infil, char * outfile )
{























}

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

//Store in file "outfile" the lines in "infile" that contain the substring "aaa" sorted.
runPipe( command1, command2, "infile", "outfile" );

}


 
11. (15 pts.) Implement the procedure char * scommand( char ** command, char * infile) that runs the command passed as argument and returns the output of the command as a string. The command executed takes as input the file in infile. scommand allocates enough memory to store the output of command. See how the procedure is used in main().

char * scommand( char ** command, char * infile)
{

































}

int main()
{
char * args[] = {"ls", ".", NULL };

char * s = scommand(args, "/dev/null");

printf( "The content of the current directory is:\n %s\n", s );
}