1. (4 pts.) What is a real-time system, a hard real-time system, and
a soft real-time system?
2. (4 pts.) What are the differences between kernel and user mode?
3. (4 pts.) Why modern CPU's have kernel and user mode?
4. (4 pts.) Why system calls use software interrupts?
5. (4 pts.) What are the steps for servicing an interrupt?
6. (4 pts.) How many program counters and sets of registers are
stored in a single process table entry?
7. (4 pts.) In which state processes are most of the time and in what
kind of programs this is not true?
8. (4 pts.) What are the advantages and disadvantages of using threads
vs. using processes?
9. (4 pts.) What factors have to be considered when choosing the
length of a quantum time?
10. (4 pts.) What are the advantages and disadvantages of using spinlocks
vs. disable/enable interrupts?
11. (6 pts.) Write down the code for spinlock() and spinunlock() and
explain briefly how it works.
12. (6 pts.) Assume that a computer executes the following jobs:
Process | Time needed for completion (ms) |
P1 | 40 |
P2 | 5 |
P3 | 30 |
Compute the average waiting time if the following scheduling algorithms are used:
FCFS:
SJF:
Round Robin (Quantum=10ms):
13. (6 pts.) Mark the "C" expressions that are quivalent to a[i]. The type of a[i] is not necessarily char. | ||||||||||||||||||
|
14. (6 pts.) Write a procedure arrayMapper() , that calls the function func in all the n elements of the array a. The size of each element in the array a is elementSize. The address of the array element is passed to func every time func is called. |
typedef void (*FuncPtr)(void * arg);
void arrayMapper( void * a, FuncPtr func, int n, int elementSize)
} |
15. (6 pts.) The following code implements a concurrent stack. The push() and pop() calls can be called simultaneously by different threads. The push() call blocks until space is available in the stack. The pop() call blocks until data is available in the stack. Insert the necessary semaphore calls to implement this behavior. Remember to initialize the semaphores in main(). |
int stackPointer; int stack[ MaxStack ]; void push( int a )
stack[ stackPointer ] = a;
} int pop()
stackPointer--;
return tmp;
main()
} |
16. (6 pts.) The following program consists of two threads: a client thread and a server thread. First the client thread reads the numbers a and b, wakes up the server thread, and then blocks until c is ready. When the server thread wakes up, it adds a and b, assigns the result to c, wakes up the client thread, and then goes to sleep. When the client wakes up, prints the value of c and starts all over again. Complete the following code and insert semaphore calls where necessary. Remember to initialize the semaphores in main(). |
client_thread()
a = input();
print c;
}
server_thread()
c = a + b;
}
main()
}
|
17. (6 pts.) Complete the procedure redirectStdin( fileName ) to redirect the standard input from file fileName. The procedure will return -1 if any error occurrs or 0 if it succeeds. Look at main() to see how redirectStdin( ) is used. NOTE: ERROR CHECKING IS IMPORTANT. Also notice that the procedure is called redirectStdin and not redirectStdout. |
int redirectStdin( char * fileName )
{ } main()
int n = scanf( "%d", &i );
|
18. (6 pts.) Complete the procedure redirectStdinFromPipe( command, arg1) that creates a pipe, redirects stdin from the pipe, forks a child process that redirects its output to the pipe, and then executes a command with argument arg1. redirectStdinFromPipe() will return -1 if an error occurrs or 0 if it succeeds. Look at main() to see how redirectStdinFromPipe( ) is used. NOTE: ERROR CHECKING IS IMPORTANT. Also see that the procedure is called redirectStdinFromPipe and not redirectStdoutToPipe. |
int
redirectStdinFromPipe( char * command, char * arg1) { } int
/* Put the output of ls in a buffer */
|
19. (6 pts.) Write the instructions necessary to eliminate zombie processes. Your code should print "Child exited" when a child exits. |
int
}
|
20. (6 pts.) Write the code for the function strcpy(). |
char * strcpy( char * dest, char * src )
{ }
|