[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

rb_gc_mark question

Ara.T.Howard

5/16/2005 10:26:00 PM

8 Answers

Charles Mills

5/16/2005 11:14:00 PM

0


Ara.T.Howard wrote:
> i reading some code attm that goes:
>
> static VALUE convertgslmatrixToRubyMatrix(gsl_matrix *dm)
> {
> int i, j;
> volatile VALUE result;
> assert(dm);
> // printf("Trying to convert dm %p\n", dm);
> // printf("With size %d, %d\n", dm->size1, dm->size2);
> volatile VALUE rows = rb_ary_new();
> rb_gc_mark(rows);
> for (i = 0; i < dm->size1; i += 1) {
> volatile VALUE currow = rb_ary_new();
> rb_gc_mark(currow);
> rb_ary_push(rows, currow);
> for (j = 0; j < dm->size2; j += 1) {
> double val = gsl_matrix_get(dm, i, j);
> VALUE rval = rb_float_new(val);
> rb_gc_mark(rval);
> rb_ary_push(currow, rval);
> }
> }
> result = rb_funcall(cMatrix, rb_intern("rows"), 2, rows, Qnil);
> rb_gc_mark(result);
> return result;
> }
>
>
> now, everything i know says this should be something along the lines
of:
>
> static VALUE
> convertgslmatrixToRubyMatrix (gsl_matrix * dm)
> {
> int i, j;
> VALUE result;
> VALUE rows = rb_ary_new ();
> for (i = 0; i < dm->size1; i += 1)
> {
> VALUE currow = rb_ary_new ();
> rb_gc_mark (currow);
> rb_ary_push (rows, currow);
> for (j = 0; j < dm->size2; j += 1)
> {
> double val = gsl_matrix_get (dm, i, j);
> VALUE rval = rb_float_new (val);
> rb_ary_push (currow, rval);
> }
> }
> result = rb_funcall (cMatrix, rb_intern ("rows"), 2, rows,
Qnil);
> return result;
> }
>
> (please correct me if i'm wrong)
>
> or nasty things will happen in memory right? what would it do to
call
> rb_gc_mark on ruby objects like this?
>

You shoud just not call rb_gc_mark at all. Not sure if it even
matters, but it is possible that objects you mark using rb_gc_mark
outside of a mark and sweep cycle will hang around AFTER some of there
fields have been GCed - like an array whose elements have been GCed,
but is still -alive-. This will only happen if the stack does not
overflow when marking and the only way this could be a problem is by
using the object space API.

Anyway, hopefully whoever wrote this code hopefully wasn't modivated by
my overly paranoid/incorrect past posts about the Ruby GC.

Also you could use rb_ary_new2 to save ruby from having to resize the
array since you know the size ahead of time.

-Charlie

Nikolai Weibull

5/16/2005 11:23:00 PM

0

Ara.T.Howard wrote:

> static VALUE
> convertgslmatrixToRubyMatrix (gsl_matrix * dm)
> {
> int i, j;
> VALUE result;
> VALUE rows = rb_ary_new ();
> for (i = 0; i < dm->size1; i += 1)
> {
> VALUE currow = rb_ary_new ();
> rb_gc_mark (currow);
> rb_ary_push (rows, currow);
> for (j = 0; j < dm->size2; j += 1)
> {
> double val = gsl_matrix_get (dm, i, j);
> VALUE rval = rb_float_new (val);
> rb_ary_push (currow, rval);
> }
> }
> result = rb_funcall (cMatrix, rb_intern ("rows"), 2, rows, Qnil);
> return result;
> }

I donâ??t understand why you need to rb_gc_mark those values. Theyâ??re
pointed to by objects on the stack, so a GC sweep wonâ??t remove them.
Neither of the volatile specifiers in the original are needed either, as
you write (or I am definitely missing something). I donâ??t see how they
would be optimized away anyway. Well, actually, the 'result' variable
should be optimized away :-), just return the result of the rb_funcall
immediately.

Perhaps I donâ??t understand what you want to do here,
nikolai

--
Nikolai Weibull: now available free of charge at http:/...!
Born in Chicago, IL USA; currently residing in Gothenburg, Sweden.
main(){printf(&linux["\021%six\012\0"],(linux)["have"]+"fun"-97);}


nobu.nokada

5/16/2005 11:31:00 PM

0

Hi,

At Tue, 17 May 2005 07:40:31 +0900,
Ara.T.Howard wrote in [ruby-talk:142850]:
> i reading some code attm that goes:
>
> static VALUE convertgslmatrixToRubyMatrix(gsl_matrix *dm)
> {
> int i, j;
> volatile VALUE result;
> assert(dm);
> // printf("Trying to convert dm %p\n", dm);
> // printf("With size %d, %d\n", dm->size1, dm->size2);
> volatile VALUE rows = rb_ary_new();
> rb_gc_mark(rows);
> for (i = 0; i < dm->size1; i += 1) {
> volatile VALUE currow = rb_ary_new();
> rb_gc_mark(currow);
> rb_ary_push(rows, currow);

GC may run while resizing rows, however many platforms don't
have the problem. And rb_gc_mark() isn't sufficient in theory
but volatile with currow avoids it, so rb_gc_mark() isn't
needed here at all.

> for (j = 0; j < dm->size2; j += 1) {
> double val = gsl_matrix_get(dm, i, j);
> VALUE rval = rb_float_new(val);
> rb_gc_mark(rval);

Therefore volatile before rval is better than rb_gc_mark() also
here.

> rb_ary_push(currow, rval);
> }
> }
> result = rb_funcall(cMatrix, rb_intern("rows"), 2, rows, Qnil);
> rb_gc_mark(result);

No meanings at all.

> return result;
> }
>

--
Nobu Nakada


Ara.T.Howard

5/16/2005 11:34:00 PM

0

Ara.T.Howard

5/16/2005 11:37:00 PM

0

Ara.T.Howard

5/17/2005 12:19:00 AM

0

Nakada, Nobuyoshi

5/17/2005 2:02:00 AM

0

Hi,

At Tue, 17 May 2005 09:30:31 +0900,
Ara.T.Howard@noaa.gov wrote in [ruby-talk:142861]:
> > GC may run while resizing rows, however many platforms don't
> > have the problem. And rb_gc_mark() isn't sufficient in theory
> > but volatile with currow avoids it, so rb_gc_mark() isn't
> > needed here at all.
>
> why does it matter if the GC runs while re-sizing rows? it seems like rows
> would still have references to all the old rows and the new one would be
> added? or are you saying that, without volatile currow could get gc'd when
> rows got resized? i guess i can see that. still how would volatile help
> that?

I forgot that it was an already fixed bug on platforms passing
arguments by regsiters.

> > Therefore volatile before rval is better than rb_gc_mark() also
> > here.
>
> you are saying ONLY volatile and no rb_gc_mark then?

So you don't need volatile neither rb_gc_mak() with recent versions
of ruby even on such platforms.

--
Nobu Nakada


Ara.T.Howard

5/17/2005 3:17:00 AM

0