Explanation

About the Theme

The OER is a simulator of the producer/consumer problem with sleep/wakeup as presented in the book Modern Operating Systems (TANENBAUM, 2014, p. 129).

This simulator's main goal is to illustrate the use and semantics of the OS primitives sleep (which can appear in the form of system calls - syscalls) and wakeup, which are used to do interprocess communication (IPC).

To be more specific, we illustrate the usage of those primitives for synchronization between processes (and not to obtain mutual exclusion or exchange data, which constitute other objectives of IPC). In fact, the lack of mutual exclusion in the simulated codes is the source of an important race condition that can happen in this scenario. A race condition is a problem difficult to predict, detect, reproduce, and fix, originated by concurrent access to shared memory between two or more processes. Its presence in the simulated scenario encourages the introduction and study of semaphores, which can be used to avoid it.


About the Simulated Scenario and the Sleep and Wakeup Syscalls

The producer/consumer scenario herein presented consists of two processes and a fixed size buffer shared between both of them. The producer's job is to produce items and add them to the buffer, while the consumer's is to remove them from the buffer (and process them somehow - this is not relevant for the simulation's purpose). It's clear that the consumer must not try to remove items from an empty buffer and the producer must not add items to an already full buffer. We use the sleep and wakeup calls to enforce this semantic. Sleep blocks the calling process, which then waits to be awakened by a wakeup call made by another process passing the blocked process' identification (PID) as a parameter.

The solution for the problem, therefore, is such that, when the producer or consumer process is incapable of working (due to a full or empty buffer, respectively), it blocks itself by calling sleep. The process which remains awake thus bears the responsibility of awakening the blocked process, by calling wakeup, when the latter can continue working - that is, when the buffer is not full or not empty anymore, respectively.


About Race Conditions

An insightful user with some knowledge in Operating Systems and processes could notice that the simulation's code seems to present some problems: the buffer and the count variable are shared between two processes, representing, consequently, a critical region which demands mutual exclusive access. That user would be absolutely correct. As said above, the sleep/wakeup pair is not being used to obtain mutual exclusion. Race conditions may occur, for there is nothing protecting the concurrent access to the shared resources. The simulation does respect this fact realiably, and can therefore be used to illustrate such concept.

The most important and simulable race condition (though not the only one) involves the fact that wakeup calls to a non-blocked process are lost permanently. Ultimately, this can result in both consumer and producer being blocked forever, as Tanenbaum explains in his aforementioned book. We suggest that users try, as exercise, to achieve this situation by themselves.