tderensis
tderensis

Reputation: 90

How to protect a non-atomic variable from modification by both interrupt and application code without blocking

I want to be able to modify a non-atomic variable in interrupt context or application context without ever blocking. To prevent the ISR from blocking, I use an atomic flag to guard the non-atomic data.

#include <atomic>
#include <cstdint>

using CountLock = std::atomic<bool>;
static_assert(CountLock::is_always_lock_free, "count lock must be lock free");

#define TARGET_COUNT (1000)
CountLock count_locked{false};
uint64_t  count{0}; // non-atomic on 32-bit system

// In interrupt
void MyISR()
{
    // Don't modify count if locked
    if (count_locked)
        return;

    ++count; // non-atomic

    if (count == TARGET_COUNT)
        // Do something
}

// Application code (not in interrupt)
void setCount(uint64_t newCount)
{
    // lock count while we are setting it
    count_locked = true;
    count = newCount;
    count_locked = false;
}
  1. Does this correctly guard the data?
  2. Is the compiler allowed to compile out the count_locked variable or reorder instructions such that the data is outside the lock?
  3. Am I correct in thinking nothing needs to be marked volatile?
  4. Is this equivalent to a mutex?

Upvotes: 0

Views: 332

Answers (1)

463035818_is_not_an_ai
463035818_is_not_an_ai

Reputation: 122830

Consider two threads concurrently calling MyISR and setCount respectively:

T1                             T2

if (count_locked)
        return;

                               count_locked = true;

 ++count; /*non-atomic*/       count = newCount;        // << data race

 if (count == TARGET_COUNT)
    // Do something

                               count_locked = false;

The atomic does not protect writes to count.

  1. No

  2. The data is modifed without being properly locked anyhow

  3. Yes. Quoting from When to use volatile with multi threading?: "volatile is (nearly) useless for platform-agnostic, multithreaded application programming."

  4. No

Upvotes: 2

Related Questions