8.16 Critical Sections

If two or more processes operate on the same set of data, then the combined output of the set of processes may depend on the relative synchronisation of the various processes.

This is usually considered to be highly undesirable and to be avoided at all costs. The solution is usually to define “critical sections” (it is the programmer’s responsibility to recognise these) in the code which is executed by each process. The programmer must then ensure that at any time no more than process is executing a section of code which is critical with respect to a part1cular set of data.

In UNIX user processes do not share data and so do not conflict in this way. Kernel processes however have shared access to various system data and can conflict.

In UNIX an interrupt does not cause a change in process as a direct side effect. Only where kernel processes may suspend themselves in the middle of a critical section by an explicit call on “sleep”, does an explicit lock variable which may be observed by a group of processes) need to be introduced. Even then the actions of testing and setting the locks do not usually have to be made inseparable.

Some critical sections of code are executed by interrupt handlers. To protect other sections of code whose outcome may be affected by the handling of certain interrupts, the processor priority is raised temporarily high enough before the critical section is entered to delay such interrupts until it is safe, when the processor priority is reduced again. There are of course a number of conventions which interrupt handling code should observe, as will be discussed later in Chapter Nine.

In passing it may be noted that the strategy adopted by UNIX works only for a single processor system and would be totally inappropriate in a multiprocessor system.