caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
* [Caml-list] Garbage collection and a reference counting library
@ 2003-12-11 14:36 Richard Jones
  2003-12-11 15:14 ` Jean-Christophe Filliatre
  2003-12-16 22:55 ` Damien Doligez
  0 siblings, 2 replies; 4+ messages in thread
From: Richard Jones @ 2003-12-11 14:36 UTC (permalink / raw)
  To: caml-list

Dear OCamlers,

I wrote an interface to allow OCaml to call Perl code and libraries.
This interface doesn't pay much attention to collecting memory
correctly.  In particular when a Perl SV (scalar value) is allocated
and passed to us, it will have a Perl internal link count of, say, 1,
and we never decrement that link count, so Perl will never free it.

This wasn't originally an issue because all the programs I was writing
were shortlived (and Perl has enough memory leaks of its own anyway).
But inevitably perhaps, I'm now dealing with a long-running OCaml /
Perl hybrid program, and the lack of proper memory handling has bitten
me on the backside.  So now it looks like I'll need to spend some time
fixing this.

But I'm not really sure how to do this.  At present the code uses the
following subroutine to wrap up Perl SVs (the void *ptr in this case)
in OCaml objects with an ABSTRACT_TAG.  (Note also the XXX comment,
since I'm not actually sure if this code itself is correct).

static value
Val_voidptr (void *ptr)
{
  value rv = alloc (1, Abstract_tag); /* XXX Is this correct? */
  Field(rv, 0) = (value) ptr;
  return rv;
}

#define Voidptr_val(type,rv) ((type *) Field ((rv), 0))

#define Val_sv(sv) (Val_voidptr ((sv)))
#define Sv_val(svv) (Voidptr_val (SV, (svv)))

I imagine that what I should do is to add a finalization function, so
that when 'rv' is garbage collected, I should decrement the Perl link
count, thus forcing Perl to free the associated SV.

Is this safe though?  Can OCaml copy this object, and collect one of
them, thus causing the SV to be deallocated early?  Do I need another
layer of indirection between 'rv' and the SV?

Rich.

-- 
Richard Jones. http://www.annexia.org/ http://freshmeat.net/users/rwmj
Merjis Ltd. http://www.merjis.com/ - improving website return on investment
C2LIB is a library of basic Perl/STL-like types for C. Vectors, hashes,
trees, string funcs, pool allocator: http://www.annexia.org/freeware/c2lib/

-------------------
To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr
Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners


^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [Caml-list] Garbage collection and a reference counting library
  2003-12-11 14:36 [Caml-list] Garbage collection and a reference counting library Richard Jones
@ 2003-12-11 15:14 ` Jean-Christophe Filliatre
  2003-12-11 16:57   ` David Brown
  2003-12-16 22:55 ` Damien Doligez
  1 sibling, 1 reply; 4+ messages in thread
From: Jean-Christophe Filliatre @ 2003-12-11 15:14 UTC (permalink / raw)
  To: Richard Jones; +Cc: caml-list


Richard Jones writes:
 > 
 > I wrote an interface to allow OCaml to call Perl code and libraries.
 > (...)
 > But I'm not really sure how to do this.  At present the code uses the
 > following subroutine to wrap up Perl SVs (the void *ptr in this case)
 > in OCaml objects with an ABSTRACT_TAG.  (Note also the XXX comment,
 > since I'm not actually sure if this code itself is correct).
 > 
 > static value
 > Val_voidptr (void *ptr)
 > {
 >   value rv = alloc (1, Abstract_tag); /* XXX Is this correct? */
 >   Field(rv, 0) = (value) ptr;
 >   return rv;
 > }

A first remark: to be GC-friendly you have to use CAMLlocal1 to
declare rv and CAMLreturn instead of return.

Then, to be able to add a finalization function, you should use custom
blocks and not the Abstract_tag. The code then looks like

======================================================================
#define Perl_val(x) (*((void**)(Data_custom_val(x))))

void ml_perl_finalize(value v) {
  perlFree(Perl_val(v));
}

static struct custom_operations perl_custom_operations = {
  "...",
  ml_perl_finalize,
  custom_compare_default,
  custom_hash_default,
  custom_serialize_default,
  custom_deserialize_default
};

#define ALLOC_PERL(v) \
  v = alloc_custom(&perl_custom_operations,sizeof(void*),0,1)

static value
Val_voidptr (void *ptr)
{
  CAMLlocal1(rv);
  ALLOC_PERL(rv);
  Perl_val(rv) = ptr;
  CAMLreturn (rv);
}

======================================================================

Hope this helps,
-- 
Jean-Christophe 

-------------------
To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr
Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners


^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [Caml-list] Garbage collection and a reference counting library
  2003-12-11 15:14 ` Jean-Christophe Filliatre
@ 2003-12-11 16:57   ` David Brown
  0 siblings, 0 replies; 4+ messages in thread
From: David Brown @ 2003-12-11 16:57 UTC (permalink / raw)
  To: Jean-Christophe Filliatre; +Cc: Richard Jones, caml-list

On Thu, Dec 11, 2003 at 04:14:45PM +0100, Jean-Christophe Filliatre wrote:

>  > static value
>  > Val_voidptr (void *ptr)
>  > {
>  >   value rv = alloc (1, Abstract_tag); /* XXX Is this correct? */
>  >   Field(rv, 0) = (value) ptr;
>  >   return rv;
>  > }
> 
> A first remark: to be GC-friendly you have to use CAMLlocal1 to
> declare rv and CAMLreturn instead of return.

Although, it isn't necessary in this situation.  GC only happens on
allocation, so the value 'rv' never has an opportunity to change, so
there is nothing wrong with this function.

But, if you're not sure, it is better to err being too safe rather than
not being safe enough.  Performance is the only issue.

Dave

-------------------
To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr
Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners


^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [Caml-list] Garbage collection and a reference counting library
  2003-12-11 14:36 [Caml-list] Garbage collection and a reference counting library Richard Jones
  2003-12-11 15:14 ` Jean-Christophe Filliatre
@ 2003-12-16 22:55 ` Damien Doligez
  1 sibling, 0 replies; 4+ messages in thread
From: Damien Doligez @ 2003-12-16 22:55 UTC (permalink / raw)
  To: caml-list

On Thursday, December 11, 2003, at 03:36 PM, Richard Jones wrote:

> I wrote an interface to allow OCaml to call Perl code and libraries.
> This interface doesn't pay much attention to collecting memory
> correctly.  In particular when a Perl SV (scalar value) is allocated
> and passed to us, it will have a Perl internal link count of, say, 1,
> and we never decrement that link count, so Perl will never free it.
[...]
> I imagine that what I should do is to add a finalization function, so
> that when 'rv' is garbage collected, I should decrement the Perl link
> count, thus forcing Perl to free the associated SV.

Yes, this is the canonical example of using finalized blocks.

> Is this safe though?  Can OCaml copy this object, and collect one of
> them, thus causing the SV to be deallocated early?  Do I need another
> layer of indirection between 'rv' and the SV?

Of course it is safe.  It is guaranteed that each allocation of a
finalized block corresponds to at most one call of its finalization
function.  Otherwise, finalization would be much less useful.

-- Damien

-------------------
To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr
Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners


^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2003-12-16 22:54 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2003-12-11 14:36 [Caml-list] Garbage collection and a reference counting library Richard Jones
2003-12-11 15:14 ` Jean-Christophe Filliatre
2003-12-11 16:57   ` David Brown
2003-12-16 22:55 ` Damien Doligez

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).