caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
* Interfacing with C question...
@ 2007-01-24 17:23 David Allsopp
  2007-01-25  6:27 ` [Caml-list] " Remi Vanicat
  2007-01-25 16:26 ` Hendrik Tews
  0 siblings, 2 replies; 5+ messages in thread
From: David Allsopp @ 2007-01-24 17:23 UTC (permalink / raw)
  To: OCaml List

Sorry if this an RADBOTFM case. Rule 2 in Chapter 18 of the manual states
that all local variables of type value must be declared using CAMLlocal
macros. However, later on when demonstrating caml_callback we get the
statements:

value* format_result_closure = caml_named_value("format_result");
return strdup(String_val(caml_callback(*format_result_closure, Val_int(n))))

(I've "simplified" the opening lines for clarity here - naturally it should
be static and once only!).

Two questions arise:

1. Presumably it's OK to cache values returned by caml_named_value without
declaring them in a CAMLlocal "call" or by using register_global_root?
2. The result of caml_callback is passed straight to String_val. Therefore,
if I expand the line to:

value result = caml_callback(*format_result_closure, Val_int(n)));
return strdup(String_val(result));

then does that work ok without using CAMLlocal1(result);

Ta!


David


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

* Re: [Caml-list] Interfacing with C question...
  2007-01-24 17:23 Interfacing with C question David Allsopp
@ 2007-01-25  6:27 ` Remi Vanicat
  2007-01-25 16:26 ` Hendrik Tews
  1 sibling, 0 replies; 5+ messages in thread
From: Remi Vanicat @ 2007-01-25  6:27 UTC (permalink / raw)
  To: OCaml List

2007/1/24, David Allsopp <dra-news@metastack.com>:
> Sorry if this an RADBOTFM case. Rule 2 in Chapter 18 of the manual states
> that all local variables of type value must be declared using CAMLlocal
> macros. However, later on when demonstrating caml_callback we get the
> statements:
>
> value* format_result_closure = caml_named_value("format_result");
> return strdup(String_val(caml_callback(*format_result_closure, Val_int(n))))
>
> (I've "simplified" the opening lines for clarity here - naturally it should
> be static and once only!).
>
> Two questions arise:
>
> 1. Presumably it's OK to cache values returned by caml_named_value without
> declaring them in a CAMLlocal "call" or by using register_global_root?

No, any C pointer to a caml value must be known to the caml GC,
because the caml GC might move the caml value. But you might no
declare such a pointer if you are sur that the GC won't be triger
between your affectation of the value to the C variable, and the use
of the C variable.*

In the given exemple, this is the case: nothing is done between the
affectation and the use.

By the way, when in doubt, or when you are a begginer not nowing well
how the GC work, you should always use the CAMLlocal call.

> 2. The result of caml_callback is passed straight to String_val. Therefore,
> if I expand the line to:
>
> value result = caml_callback(*format_result_closure, Val_int(n)));
> return strdup(String_val(result));
>
> then does that work ok without using CAMLlocal1(result);

Yes, for the same reason: you do nothing between the affectation of
the result function, and the use of the variable.


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

* Re: [Caml-list] Interfacing with C question...
  2007-01-24 17:23 Interfacing with C question David Allsopp
  2007-01-25  6:27 ` [Caml-list] " Remi Vanicat
@ 2007-01-25 16:26 ` Hendrik Tews
  2007-01-25 18:29   ` skaller
  1 sibling, 1 reply; 5+ messages in thread
From: Hendrik Tews @ 2007-01-25 16:26 UTC (permalink / raw)
  To: caml-list

"David Allsopp" <dra-news@metastack.com> writes:

   Sorry if this an RADBOTFM case. Rule 2 in Chapter 18 of the manual states
   that all local variables of type value must be declared using CAMLlocal
   macros. However, later on when demonstrating caml_callback we get the
   statements:

   value* format_result_closure = caml_named_value("format_result");

Note the type! format_result_closure is not of type value, Rule 2
does not apply!

   1. Presumably it's OK to cache values returned by caml_named_value without
   declaring them in a CAMLlocal "call" or by using register_global_root?

Yes it is OK. And you cannot use CAMLlocal or
register_global_root, because they only deal with values and not
pointers to values. The manual guarantees that the value pointed
to by the result of caml_named_value doesn't move. Probably
caml_named_value allocates a value outside the heap, registers it
as a global root and gives you back its address.

   value result = caml_callback(*format_result_closure, Val_int(n)));
   return strdup(String_val(result));

   then does that work ok without using CAMLlocal1(result);

Yes. You should think of values as pointers that point to data
that is moved around by the garbage collector. If there is any
chance that the garbage collector is called, then you must make
sure that it updates your pointer when it moves the data. Hence
you have to register the value.

If the garbage collector is not called under any circumstances
then the data will not move, the pointer doesn't need to get
updated and you don't have to register the value.

Furthermore, if your are sure Is_long(your_variable) is true
under any circumstances, you don't have to register
your_variable, because it is not a pointer. 

Of course all that is strongly discouraged.

Bye,

Hendrik


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

* Re: [Caml-list] Interfacing with C question...
  2007-01-25 16:26 ` Hendrik Tews
@ 2007-01-25 18:29   ` skaller
  2007-01-26  0:16     ` Robert Roessler
  0 siblings, 1 reply; 5+ messages in thread
From: skaller @ 2007-01-25 18:29 UTC (permalink / raw)
  To: Hendrik Tews; +Cc: caml-list

On Thu, 2007-01-25 at 17:26 +0100, Hendrik Tews wrote:
> "David Allsopp" <dra-news@metastack.com> writes:
> 
>    Sorry if this an RADBOTFM case. 

> And you cannot use CAMLlocal or
> register_global_root, 

FWIW: I encourage people not to just use the high level macros
like CAMLlocal: they hide what really happens.

Instead, read the section describing the lower level macros
and figure out how the gc *actually* works.

Roughly speaking the rules are:

(a) certain operations, including allocation, trigger the gc.

(b) you must ensure allocated store is initialised when
the gc is triggered (so it doesn't chase off into the wild
blue yonder)

(c) you may not retain copies of values in stores across
calls that trigger the gc because it may move blocks and
adjust pointers

(d) there are some exceptions: if the value is an integer
or unboxed float it won't change (obviously).

(e) Every allocated block you want to use must be reachable
from a root when the gc is triggered

The high level macros reduce thinking by making variables
a root and ensuring they're initialised, however they're
conservative and may incur a performance overhead by doing
this when it isn't necessary. For any kind of serious glue
logic you really need to understand the low level requirements,
in particular the fact stuff moves means you have to know
precisely when the gc is triggered anyhow -- since you can't
write C without temporary creation and sequence points
being considered.

It takes a bit of reading, thinking, and question asking
to figure the gc out, but it is worth it: it really isn't that
hard and IMHO the higher level macros just confuse things
by obscuring the real constraints.

[Once you know how it works .. *then* you can use the
higher level macros because you then know what they're
sugar for .. :]

-- 
John Skaller <skaller at users dot sf dot net>
Felix, successor to C++: http://felix.sf.net


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

* Re: [Caml-list] Interfacing with C question...
  2007-01-25 18:29   ` skaller
@ 2007-01-26  0:16     ` Robert Roessler
  0 siblings, 0 replies; 5+ messages in thread
From: Robert Roessler @ 2007-01-26  0:16 UTC (permalink / raw)
  To: caml-list

skaller wrote:
> ...
> It takes a bit of reading, thinking, and question asking
> to figure the gc out, but it is worth it: it really isn't that
> hard and IMHO the higher level macros just confuse things
> by obscuring the real constraints.
> 
> [Once you know how it works .. *then* you can use the
> higher level macros because you then know what they're
> sugar for .. :]

While understanding what is going on under the covers *is* important, 
there is a key reason for using the macros: as the documented and 
recommended interface to the OCaml GC machinery, their use gives you a 
much better chance that your code will easily / automagically survive 
changes to the GC mechanism in the future... like if direct support of 
multi- cores and processors ever becomes a reality. ;)

Robert Roessler
roessler@rftp.com
http://www.rftp.com


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

end of thread, other threads:[~2007-01-26  0:16 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2007-01-24 17:23 Interfacing with C question David Allsopp
2007-01-25  6:27 ` [Caml-list] " Remi Vanicat
2007-01-25 16:26 ` Hendrik Tews
2007-01-25 18:29   ` skaller
2007-01-26  0:16     ` Robert Roessler

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).