Tutorial Week 3

Questions

System Calls

Q1: Why must kernel programmers be especially careful when implementing system calls?

Q2: Why is recursion or large arrays of local variables avoided by kernel programmers?

Q3: How does the 'C' function calling convention relate to the system call interface between the application and the kernel? At minimum, what additional information is required beyond that passed to the system-call wrapper function?

Q4: In the example given in lectures, the library procedure read invoked the read system call. Is it essential that both have the same name? If not, which name is important?

Q5: To a programmer, a system call looks like any other call to a library procedure. Is it important that a programmer know which library procedures result in system calls? Under what circumstances and why?

Processes and Threads

Q6: In the three-state process model, what do each of the three states signify? What transitions are possible between each of the states, and what causes a process (or thread) to undertake such a transition?

Q7: The following segment of code is similar (but much simpler) to the main task that the daemon inetd performs. It accepts connections on a socket and forks a process to handle the connection.

This is not guaranteed to be compilable. Use the man command if you want to investigate what all the system calls are doing.

0001 xxx(int socket){
0002 
0003        while ((fd = accept(socket, NULL, NULL)) >= 0) {
0004                switch((pid = fork())) {
0005                case -1:
0006                        syslog(LOG_WARN, "%s cannot create process: %s",
0007				progname, sys_error(errno));
0008                        continue;
0009                case 0:         
0010                        close(0);
0011                        close(1);
0012                        dup(fd);
0013                        dup(fd);
0014                        execl("/usr/sbin/handle_connection", 
0015				"handle_connection", NULL);
0016                        syslog(LOG_WARN, "%s cannot exec handle_connection\ 
0017				helper : %s", progname, sys_error(errno));
0018                        _exit(0);
0019                default: 
0020                        waitpid(pid, &status, 0); 
0021                        if (WIFEXITED(status) && WIFEXITSTATUS(status) == 0)
0022                                continue;
0023                        syslog(LOG_WARN, "handle_connection failed:\
0024				exit status +%d\n", status);
0025                }
0026        }
0027 }

Q8: A web server is constructed such that it is multithreaded. If the only way to read from a file is a normal blocking read system call, do you think user-level threads or kernel-level threads are being used for the web server? Why?

Q9: Compare reading a file using a single-threaded file server and a multithreaded file server. Within the file server, it takes 15 msec to get a request for work and do all the necessary processing, assuming the required block is in the main memory disk block cache. A disk operation is required for one third of the requests, which takes an additional 75 msec during which the thread sleeps. How many requests/sec can a server handled if it is single threaded? If it is multithreaded?