Linux Kernel Architecture

(Jacob Rumans) #1

Chapter 13: System Calls


Similarly, some system calls were developed specifically for Linux and either don’t exist at all in other
look-alikes or have a different name. One example is thevm86system call, which is of fundamental impor-
tance in implementing the DOS emulator on IA-32 processors. More general calls, such asnanosleepto
suspend process execution for very short periods of time, are also part of the Linux-specific repertoire.

In some cases, two system calls are implemented to resolve the same problem in different ways. Prime
examples are thepollandselectsystem calls; the first was introduced in System V, the latter in 4.3BSD.
Ultimately, both perform the same function.

In conclusion, it’s worth noting that — in spite of the name — simply implementing the POSIX standard
does not produce a fullUnixsystem. POSIX is nothing more than a collection ofinterfaceswhose concrete
implementations are not mandated and need not necessarily be included in the kernel. Some operating
systems therefore fully implement the POSIX standard in a normal library to facilitateUnixapplication
porting despite their non-Unixdesign.^4

13.1.3 Restarting System Calls


An interesting problem arises when system calls clash with signals. How are priorities assigned when
it is imperative to send a signal to a process while a system call is being executed? Should the signal
wait until the system call terminates, or should the call be interrupted so that the signal can be delivered
as quickly as possible? The first option obviously causes fewer problems and is the simpler solution.
Unfortunately, it only functions properly ifallsystem calls terminate quickly and don’t make the process
wait for too long (as mentioned in Chapter 5, signals are always delivered when the process returns to
user mode after a system call). This is not always the case. System calls not only need a certain period of
time to execute, but, in the worst case, they also go to sleep (when, e.g., no data are available toread).
This seriously delays delivery of any signals that may have occurred in the meantime. Consequently,
such situations must be prevented at all costs.

If an executing system call is interrupted, which value does the kernel return to the application? In nor-
mal circumstances, there are only two situations: Either the call is successful or it fails — in which case
an error code is returned so that the user process candetermine the cause of the error and react appropri-
ately. In the event of an interruption, a third situation arises: The application must be informed that the
system callwouldhave terminated successfully,hadit not been interrupted by a signal during execution.
In such situations, the-EINTRconstant is used under Linux (and under other System V derivatives).

The downside of this procedure is immediately apparent. Although it is simple to implement, it forces
programmers of userspace applications to explicitly check the return value of all interruptible system
calls for-EINTRand, where this value is true, to restart the call repeatedly until it is no longer interrupted
by a signal. System calls restarted in this way are calledrestartable system calls, and the technique itself is
known asrestarting.

This behavior was introduced for the first time in System VUnix. However, it is not the only way of com-
bining the rapid delivery of new signals and the interruption of system calls, as the approach adopted
in the BSD world confirms. Let us examine what happens in the BSD kernel when a system call is inter-
rupted by a signal.

The BSD kernel interrupts execution of the system call and switches to signal execution in user
mode. When this happens, the call doesnotissue a return value but is restarted automatically by

(^4) More recent Windows versions include a library of this kind.

Free download pdf