I can't find much documentation on when it's appropriate to declare a VALUE
as volatile
in Ruby extensions to avoid premature garbage collection of in-use objects.
Here's what I've learned so far. Can anyone fill in the blanks?
volatile
does not need to be used:volatile
does need to be usedALLOC
or malloc
macros/functions (because these can trigger GC when memory is highly fragmented)rb_funcall
, rb_ary_new
, etc.)VALUE
s that are in useIs everything correct? What details am I missing? Other than marking, is volatile
the only way?
Volatile is used in C programming when we need to go and read the value stored by the pointer at the address pointed by the pointer. If you need to change anything in your code that is out of compiler reach you can use this volatile keyword before the variable for which you want to change the value.
volatile is a keyword that must be used when declaring any variable that will reference a device register. If this is not done, the compile-time optimizer might optimize important accesses away. This is important; neglecting to use volatile can result in bugs that are difficult to track down.
The volatile qualifier is applied to a variable when we declare it. It is used to tell the compiler, that the value may change at any time. These are some properties of volatile. The volatile keyword cannot remove the memory assignment. It cannot cache the variables in register.
The volatile qualifier declares a data object that can have its value changed in ways outside the control or detection of the compiler (such as a variable updated by the system clock or by another program).
I would say the rule of thumb is if your variable value can be changed at any time during run-time and you don't know when, use volatile
keyword. That includes interrupts. For example you have interrupt callback function that counts how many times the user pressed something on a keyboard. Your program does not know WHEN will the user press the button on the keyboard so your counter variable must be declared with volatile
keyword.
As mentioned before, it disables some compiler optimizations for a variable. For example:
int a = 5;
while(a == 5){
//do something
}
Compiler optimizes the while(a == 5)
statement to while(true)
because it sees that variable a cannot change during run-time and it is no use to check the value of a
every loop. So you end up in an infinite loop. But if you add keyword volatile
:
volatile int a = 5;
while(a == 5){
//do something
}
You just tell the compiler to leave the variable as it is. Don't make any optimizations on it, some interrupt might change it's value. And at this it works just fine.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With