Race Conditions (Glossary Entry)

This topic is covered in more detail at level 5.

In software, where the outcome of software depends on the timing of 1 or more asynchronous events, such as interrupts or software threads.

There are scenarios where data that is being referenced in two sections of code can become corrupted or data integrity is lost. For example, consider the following example:

Now imagine it is the stroke of midnight, as the time changes from 23:59:59 on the 31st December 1999 to 00:00:00 on 1st January 2000. The code below has reached the line where the month is to be updated to the new value.

hour = getHour();
min = getMin();
sec = getSec();
day = getDay();
month = getMonth();
year = getYear();

At this precise point, an interrupt occurs, and the following code is executed in the interrupt service routine:

//Save date and time to flash storage device
saveDateAndTime(hour, min, sec, day, month, year);

The problem is that the month and year were not updated at the point the interrupt occurred, and that the interrupt service routine made reference to the partially updated data. The time and date to be saved will be 00:00:00 1st December 1999, which is a whole year out. We say that data integrity has been compromised. Had the interrupt occurred slightly earlier or later in the code, or had the day in the month not been the end of the month, then the result would have been entirely different.

To prevent this problem, one would need to recognise that the date and time elements are part of a single data structure that should only be modified atomically (ensure the complete read-modify-write is allowed to occur without interruption).

This is actually a trivial example. Most real-world examples are much more subtle and difficult to spot. Such errors are stochastic, and may only occur very infrequently (making them hard to detect).

If you are using either interrupts or threads, and modifying shared data, you need to be aware of how to protect against race conditions (covered at level 5 and above).

If you do not know how to anticipate and mitigate against race conditions, you should not use interrupt or threads (except for the purpose of personal study)

If you are sure you are not using any form of concurrency (interrupts or threads), you do not need to consider race conditions.