A race condition occurs when two or more asynchronously running pieces of code (eg, an interrupt and a background loop shown in the video) can access and change a shared resource.
For this episode, I will skip lesson #19 about Eclipse-based IDE and the GNU-ARM development toolset. Instead, today I’d like to go straight to lesson #20 about race conditions.
Lesson 20 – Race Conditions: What are they, and how to avoid them?
What are Race Conditions?
A race condition occurs when two or more asynchronously running pieces of code (eg, an interrupt and a background loop shown in the video) can access and change a shared resources. Problems often occur when at least one such piece of code performs a read-modify-write sequence on the shared resource. If an asynchronous preemption occurs after the read but before the write, the resource’s state might change, but the preempted piece of code could miss it. The change might get lost, depending only on a narrow time window of the preemption.
The Nastiness of the Concurrency Problems
Race conditions are just one of many types of concurrency problems that transpire only due to asynchronous execution. The common characteristic of all such problems is that they seem to “defy logic.” By this, I mean that each piece of code behaves correctly, when executed individually. Issues show up only intermittently when the pieces of code are executed concurrently. Bugs of this type are generally hard to reproduce, isolate, and fix. You might be testing your system for hours or weeks, and some concurrency bugs can still slip into the final product. This is the worst kind of problem you ever want to deal with.
Mutual Exclusion
The most common way of preventing concurrency problems is to disallow asynchronous preemption while accessing the shared resource. This makes the access mutually exclusive, meaning that only one piece of code can access the resource at a time. For single-CPU systems, the simplest method (demonstrated in the video) is to disable interrupts right before accessing a shared resource and re-enabling them right after. The section of code where interrupts remain disabled is called a critical section.
Mutual exclusion prevents concurrency issues, but serializing access to the resource reduces system responsiveness (eg, disabling interrupts for too long can extend the interrupt latency.) Also, developers must remember to apply mutual exclusion around all applicable parts of their code, and it is easy to miss some of them in practice.
Avoiding Resource Sharing
Another way to prevent concurrency problems is to avoid sharing resources in the first place. this approach is the best because it side-steps all concurrency issues, so you can program “as usual” without even knowing what concurrency problems are.
You can avoid sharing resources in many ways, including smarter use of the hardware. For example, many peripherals inside the MCU offer interfaces precisely designed to avoid unnecessary sharing of resources. The video shows how to take advantage of the TivaC GPIO design (discussed in the previous lesson 7) to decouple individual pins.
End Notes
Race conditions are only the tip of the iceberg of concurrency problems, which can cause some of the nastiest bugs. The accompanying video shows only the simplest case of a single interrupt and a background loop, but the issues are endemic to all forms of concurrency, including concurrent threads in a Real-Time Operating System (RTOS). Concurrency hazards and the ways to avoid them will be the recurring theme in the upcoming lessons of this course.
Dr. Miro M. Samek is the creator of the open source QP real-time embedded framework and the freeware QM graphical model-based design tool. He is also the founder and CEO of Quantum Leaps — the provider of modern embedded software based on active objects and hierarchical state machines as well as tools for visual modeling, automatic code generation, and unit testing of deeply embedded software. Miro teaches the popular YouTube “Modern Embedded Systems Programming” video course on which this article series is based. |
Related Contents:
For more Embedded, subscribe to Embedded’s weekly email newsletter.