简体   繁体   中英

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?

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM