[SOLVED] Is an assignment to 8 bit-long variable on 8 bit processor always atomic?

well, volatile in itself does not imply atomic R/W access as per the C++ standard. The compiler generated code does not guarantee that the access will be atomic, just that the lifetime of a register copy has to be limited and that limited optimisation can be done around it.

it can (and often is) by the C++ standard. If you want atomic access to your volatile variable (very very often required), you need to code for it. critical sections like blocking interrupts, using semaphores, ...

➜ so it's two separate concepts. I think that's what @bperrybap was trying to say


Have a look at the HardwareSerial.cpp code for example and you'll see that they support multibyte for the Tx or Rx buffer index

#if (SERIAL_TX_BUFFER_SIZE>256)
typedef uint16_t tx_buffer_index_t;
#else
typedef uint8_t tx_buffer_index_t;
#endif

#if  (SERIAL_RX_BUFFER_SIZE>256)
typedef uint16_t rx_buffer_index_t;
#else
typedef uint8_t rx_buffer_index_t;
#endif

this type is used for the instance variables, that are defined as volatile:

    volatile rx_buffer_index_t _rx_buffer_head;
    volatile rx_buffer_index_t _rx_buffer_tail;
    volatile tx_buffer_index_t _tx_buffer_head;
    volatile tx_buffer_index_t _tx_buffer_tai

and thus in the code they allow for atomicity

you'll see things like this

int HardwareSerial::availableForWrite(void)
{
  tx_buffer_index_t head;
  tx_buffer_index_t tail;

  TX_BUFFER_ATOMIC {
    head = _tx_buffer_head;
    tail = _tx_buffer_tail;
  }
  if (head >= tail) return SERIAL_TX_BUFFER_SIZE - 1 - head + tail;
  return tail - head - 1;
}

where the local copies are made in a protected block