[Q] Caveats of rb_global_variable()?

Fellow Rubygoers,

For a program I’m working on, I wrote a nifty little class in C (said
class being a sort of specialized pseudo-Array for a very
performance-sensitive loop), and all is well and wonderful, and the
class does everything I’d hoped (and IMO ruby is wonderful to work with
even on the C side of things…), but there are two places where I need
to protect certain values from the Garbage Collector.

In the first case, I just made the value in question into an instance
variable, since there’s just one such value.

In the second case (method StatArray#[]= ), I use rb_global_variable(
data_pointer + index ) to protect the stored VALUE from being culled by
the GC.

It works, but is this a healthy practice? I.e., am I keeping these
values from being deallocated until the program terminates, and if so,
is there a better way to ensure that the GC does not cull these
referenced objects while the StatArray instance exists, but to allow
normal garbage collection afterwards?

TIA,
Julian

It works, but is this a healthy practice? I.e., am I keeping these
values from being deallocated until the program terminates, and if so,
is there a better way to ensure that the GC does not cull these
referenced objects while the StatArray instance exists, but to allow
normal garbage collection afterwards?

Well, it's really difficult to answer without seeing your C source but
rb_global_variable() use rb_gc_register_variable() and the opposite is
rb_gc_unregister_variable()

Guy Decoux

[…]

It works, but is this a healthy practice? I.e., am I keeping these
values from being deallocated until the program terminates, and if so,
is there a better way to ensure that the GC does not cull these
referenced objects while the StatArray instance exists, but to allow
normal garbage collection afterwards?

In addition to what has already been suggested, simply assigning Qnil to
the variable(s) allows the GC to purge anything that is solely
referenced from there without having to worry about ruby internals.

		Reimer Behrends
···

Julian Snitow (vangczung@yahoo.com) wrote:

Bad, bad

Well, it's really difficult to answer without seeing your C source but
rb_global_variable() use rb_gc_register_variable() and the opposite is

                             ^^^^^^^^^^^^^^^^^^^^^^^
                             rb_gc_register_address()

rb_gc_unregister_variable()

    ^^^^^^^^^^^^^^^^^^^^^^^^^
    rb_gc_unregister_address()

Guy Decoux

ts wrote:

“t” == ts decoux@moulon.inra.fr writes:

Bad, bad

Well, it’s really difficult to answer without seeing your C source but
rb_global_variable() use rb_gc_register_variable() and the opposite is
^^^^^^^^^^^^^^^^^^^^^^^
rb_gc_register_address()
rb_gc_unregister_variable()
^^^^^^^^^^^^^^^^^^^^^^^^^
rb_gc_unregister_address()

Guy Decoux

Thanks. Can rb_gc_unregister_adddress() be safely called on an address
that wasn’t necessarily registered in the first place? If so, I can
solve my problem neatly.

(If not, I get to go source diving again… :wink:

You were lucky, problem solved :slight_smile:

void
rb_gc_unregister_address(addr)
VALUE *addr;
{
struct gc_list *tmp = global_List;

if (tmp->varptr == addr) {
    global_List = tmp->next;
    RUBY_CRITICAL(free(tmp));
    return;
}
while (tmp->next) {
    if (tmp->next->varptr == addr) {
        struct gc_list *t = tmp->next;

        tmp->next = tmp->next->next;
        RUBY_CRITICAL(free(t));
        break;
    }
    tmp = tmp->next;
}

}

Nothing happens if it wasn’t registered before.

···

On Fri, Mar 28, 2003 at 03:16:18PM +0900, Julian Snitow wrote:

Thanks. Can rb_gc_unregister_adddress() be safely called on an address
that wasn’t necessarily registered in the first place? If so, I can
solve my problem neatly.


_ _

__ __ | | ___ _ __ ___ __ _ _ __
'_ \ / | __/ __| '_ _ \ / ` | ’ \
) | (| | |
__ \ | | | | | (| | | | |
.__/ _,
|_|/| || ||_,|| |_|
Running Debian GNU/Linux Sid (unstable)
batsman dot geo at yahoo dot com

  • SynrG notes that the number of configuration questions to answer in sendmail
    is NON-TRIVIAL
    – Seen on #Debian