0

Let's say that the function isr_callback() is called on hardware interrupts. If my_function() sets the variable data to 0, and waits for tx_complete_semaphore, will the variable data be updated to 1 in my_function() when tx_complete_semaphore is released by isr_callback()? Or does the variable data have to be qualified as volatile to be updated properly in my_function()?

static int data;
static rtems_id tx_complete_semaphore;
void isr_callback(void)
{
  data = 1;
  /* interrupts as disabled here */
  rtems_semaphore_release(tx_complete_semaphore);
}
  
void my_function(void)
{
  data = 0;
  /* data will be 0 here */
  printf("data is %i", data)
  /* Interrupts are enabled here */
  rtems_semaphore_obtain(tx_complete_semaphore,
                         RTEMS_WAIT,
                         RTEMS_NO_TIMEOUT);
  /* what is the value of data here? */
  printf("data is %i", data);
}
LukesDiner
  • 145
  • 8

2 Answers2

0

You should qualify data as volatile, because for the compiler it will not be deducable that data is changed during the course of my_function.

With volatile you ensure that the compiler doesn't rely on a previously known value 0 because it can change anytime outside the function.

Devolus
  • 21,661
  • 13
  • 66
  • 113
  • Actually, after testing it seems like 'volatile' can be omitted here because the RTEMS semaphore synchronization makes sure that the variable data is correctly updated in my_function(). – LukesDiner Apr 22 '21 at 09:17
  • But that doesn't mean that the compiler knows about it when it reaches the `printf` line. To avoid redundant loads it can optimize it away thinking that the variable has not been changed in the meantime. That's the whole point of using `volatile`. To tell the compiler that a certain value can change anytime without it being aware of it and thus it shouldn't apply such optimizations. – Devolus Apr 22 '21 at 09:19
  • For all we know, `data` could already have been changed, even at the first `printf` line, right after `data = 0`, so the comment might be wrong about the assumption that data is 0 after you assigned it. – Devolus Apr 22 '21 at 09:21
  • Sorry, I should have added info that interrupts are enabled after setting data to 0 in my_function(). – LukesDiner Apr 22 '21 at 09:28
  • Sure, there is a risk that the semaphore is not obtained when the interrupt comes, but I don't see how this could create a race condition assuming that it is always legal to release a semaphore, obtained or not. If I would obtain the semaphore before enabling interrupts, the call to obtain the semaphore would block forever and interrupts would never be enabled. – LukesDiner Apr 22 '21 at 09:46
  • 1
    Yeah, I realized this, that's why I deleted that comment. :) I don't know what the meaning of `data` is, but your second `printf` may print a wrong value if you don't declare it volatile. You can always check the generated asm source, to see if the compiler reloads the value even when optimizations are active. – Devolus Apr 22 '21 at 09:48
  • I checked the generated asm code for two cases, one where `data` was `volatile`, and one where `data` was not volatile. In both cases, `data` was loaded after obtaining the semaphore, but only in the first case `data` was loaded before obtaining the semaphore. – LukesDiner Apr 26 '21 at 09:17
0

No, the qualifier 'volatile' is not needed here since RTEMS semaphore synchronization makes sure that the variable data is correctly updated in my_function().

I checked the generated asssembler code for two cases, one where data was volatile, and one where data was not volatile. In both cases, data was loaded after obtaining the semaphore, but only in the first case data was loaded before obtaining the semaphore.

LukesDiner
  • 145
  • 8