Shared variables and audio callback (and uint64_t)

A few (somewhat related) questions:

Suppose I have a variable that is updated in the main control thread, but also used in the AudioCallback; for example

float myvar1, myvar2, myvar3, myvar4 ;

int main() {
    myvar1 = myvar2 + myvar3 + myvar4;
    if ( myvar1 > 1) myvar1 = 1;
}
void AudioCallback(...) {
   ... here I use myvar1 ...
}

What is the atomicity of the operations with respect to the AudioCallback?

  • Should I expect that myvar1 has always a consistent value resulting from myvar2+myvar3+myvar4 (and not only a partial value from myvar2 + myvar3)?
  • Should I expect that it could happen that the AudioCallback is called before the if (myvar1 > 1) ... so a value greater than 1 could happen?
  • Is there a standard way to handle the shared variables between audio callback and main thread?

and another question:

  • are uint64_t operations supported on the daisy? (sum, mul, shifts)

Thank you in advance.

  1. If you write to a global variable from ISR (that calls AudioCallback function in this case), you should probably define it as volatile to make sure that correct value is used outside of ISR. This has some performance overhead as values will be loaded from memory on each read operation. In some cases you can avoid it when not needed by assigning it to a local variable and reading from it as soon as possible (i.e. inside AudioCallback since it won’t be preempted).

  2. Generally you can expect to be able to use 64 bit (or more!) integer operation on any hardware, it ends up processing multiple halves (quarters, etc for longer numbers) sequentially. It’s a matter of processing carry/overflow bits between those operations and compiler generates all the necessary code for that. Of course it’s not a free operation and using more precision would take more time.

In case of floating point operations, the underlying logic is more complex and hardware support is important to get any sort of reasonable performance - that’s why double precision FPU on STM32H7 is a big improvement over lower level MCUs. It was still possible to use doubles on older hardware, but that ended up being processed in software and performed much worse compared to what you can expect from a hardware double precision FPU.

Ok, thank you I’ll dig more on the volatile variables.
Though my concern is mainly the opposite: the consistency of a global variable (or struct) changed at the main level and read at the ISR level.

For example, if I write something on a uint64_t variable x_64 = y_64 + z_64; at main level (that I also read from ISR), is it an atomic operation, or it can happens that ISR stops the main thread while the variable value is neither the original value of x_64 nor the new value y_64 + z_64 ?

You should probably look for answers in ARM documentation rather than here as the question has nothing to do with Daisy itself and is not trivial. I’m pretty sure that you can’t have atomic operations in 64 bit integers out of the box as the underlying architecture is 32 bit. But at least 32 bit store/load that was mentioned in your top post would be atomic.

You can also disable interrupts for a small critical section that needs to update global state.