Information Technology Reference
In-Depth Information
data must be reentrant, which means that a task may be interrupted and the data will
not be compromised. Critical sections in the code must be protected, and there are
different methods for protecting data, such as semaphores and disabling interrupts.
Depending on the requirements of the system, one method may be more suitable than
others. These methods will be discussed in greater detail in the following sections.
Shared variables commonly are referred to as global data because it can be viewed
by all tasks. Variables that are specific to a task instance or local are referred to as
local or static variables. An example of when data integrity becomes an issue is when
global data are being modified by a task and another task preempts the first task and
reads that data before the modification is complete.
In addition to data integrity, resources often are limited and must be shared among
the tasks in the system. Control of these resources usually is the job of the operating
system. The design of a real-time operating system may include several methods
for protecting data and sharing of resources. Some methods include semaphores,
read/write locks, mailboxes, and event flags/signals.
3.5.1
Semaphores
Operating systems commonly use semaphores as a method to signal when a resource
is being used by a task. Use of semaphores in computer science is not a new concept,
and papers have been published on the topic since the early 1970s. Today, it maintains
a popular way for operating systems to allow tasks to request resources and signal to
other tasks that the resource is being used. Two main functions make up a semaphore,
wait and signal . The usual implementation of a semaphore is to protect a critical
section, of code; before the task enters the critical section, it checks to see whether
the resource is available by calling the wait function. If the resource is not available,
the task will stay inside the wait function until it is available. Once it becomes
available, the task requests the resource and therefore makes it unavailable to other
tasks. Once the task is finished with the resource, it must release it by using the signal
function so other tasks may use it. There are two main types of semaphores, binary
and counting. Binary usually is sufficient, but counting semaphores are nice when
there are more than one resource.
Although semaphores are a relatively easy concept, issues can develop if they
are not implemented and used properly. With binary and counting semaphores, a
race condition can occur if code that is responsible for reserving the resource is
not protected until the request is complete. There are, however, a couple different
approaches on how to eliminate race conditions from the wait function. One method,
presented by Hemendinger in comments on “A correct implementation of general
semaphores” discusses a common race condition and provides a simple solution.
This solution was further improved on by Kearns in “A correct and unrestrictive
implementation of general semaphores” (1988) as Kearns had found another possible
race condition within the solution.
Another issue that can occur with semaphores, or any method where a task must
wait until a resource is freed, is called deadlock. Deadlock usually is avoidable
in real-time applications. Four conditions must be present for deadlock to occur.
Search WWH ::




Custom Search