When is it necessary to declare volatile VALUEs in Ruby C extensions?
Asked Answered
D

2

6

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?

When volatile does not need to be used:

  • in C++ object members (because they're never on the stack?)
  • in C/C++ methods that do not call Ruby API (because the GC isn't turned on until Ruby API is called)

When volatile does need to be used

  • in C/C++ methods that call any of the Ruby ALLOC or malloc macros/functions (because these can trigger GC when memory is highly fragmented)
  • in C/C++ methods that call any Ruby functions (e.g., rb_funcall, rb_ary_new, etc.)

Other methods for avoiding GC

  • mark VALUEs that are in use
  • disable the GC during object creation and then re-enable it
  • don't use Ruby's allocation methods (risky)

Is everything correct? What details am I missing? Other than marking, is volatile the only way?

Diversiform answered 3/10, 2013 at 21:38 Comment(0)
F
1

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.

Foregut answered 11/7, 2019 at 9:59 Comment(0)
M
0

Marking a variable as volatile prevents the C/C++ compiler from applying certain optimizations, based on the assumption that variables cannot change values "on their own". Wikipedia: Volatile variable

I think it should be used when a VALUE is shared with or can be changed by Ruby code outside the C extension, to make the compiler aware of this fact. Have a look at this example.

Micronutrient answered 12/10, 2013 at 11:33 Comment(1)
This is misleading. volatile does different things in C and C++.Diversiform

© 2022 - 2024 — McMap. All rights reserved.