English version
Accueil     À propos     Téléchargement     Ressources     Contactez-nous    

Ce site est rarement mis à jour. Pour les informations les plus récentes, rendez-vous sur le nouveau site OCaml à l'adresse ocaml.org.

Browse thread
When can we ignore CAMLparam and CAMLreturn?
[ Home ] [ Index: by date | by threads ]
[ Search: ]

[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
Date: 2010-10-27 (15:19)
From: Goswin von Brederlow <goswin-v-b@w...>
Subject: Re: [Caml-list] When can we ignore CAMLparam and CAMLreturn?
Jianzhou Zhao <jianzhou@seas.upenn.edu> writes:

> On Wed, Oct 27, 2010 at 5:36 AM, Goswin von Brederlow <goswin-v-b@web.de> wrote:
>> Jacques Garrigue <garrigue@math.nagoya-u.ac.jp> writes:
>>> On 2010/10/26, at 1:19, Jianzhou Zhao wrote:
>>>> Hi All,
>>>> Here is the code from LLVM-OCaml bindings.
>>>> /////////////////
>>>> /* llvalue -> GenericValue.t array -> ExecutionEngine.t -> GenericValue.t */
>>>> CAMLprim value llvm_ee_run_function(LLVMValueRef F, value Args,
>>>>                                   LLVMExecutionEngineRef EE) {
>>>> unsigned NumArgs;
>>>> LLVMGenericValueRef Result, *GVArgs;
>>>> unsigned I;
>>>> NumArgs = Wosize_val(Args);
>>>> GVArgs = (LLVMGenericValueRef*) malloc(NumArgs * sizeof(LLVMGenericValueRef));
>>>> for (I = 0; I != NumArgs; ++I)
>>>>   GVArgs[I] = Genericvalue_val(Field(Args, I));
>>>> Result = LLVMRunFunction(EE, F, NumArgs, GVArgs);
>>>> free(GVArgs);
>>>> return alloc_generic_value(Result);
>>>> }
>>>> ////////////////////////
>>>> The 'llvm_ee_run_function' does not protect the Args parameter by
>>>> CAMLparam with CAMLreturn. Is this safe in this case, because we
>>>> allocated a GVArgs? The Ocaml manual suggests to use CAMLparam for any
>>>> value parameters (http://caml.inria.fr/pub/docs/manual-ocaml/manual032.html#toc140).
>>> The basic rule is that those macros are only needed if some allocation in the caml heap
>>> occurs before accessing a caml value. Expressed another way, whenever allocation is
>>> used all unprotected pointers to the caml heap should be considered as invalid.
>>> Since in the above code there is no allocation in the caml heap before the Genericvalue_val's,
>>> Args need not be protected. Similarly for the result, we are just returning the result of another
>>> function, with no risk of corruption.
>>> When in doubt, it is always safer to use CAMLparam/CAMLreturn, eventhough they will
>>> generate a bit more code.
>> As a special case: If you enter/leave_blocking_section() then some other
>> thread might (almost certainly will) do an allocation. So any ocaml
>> values you need in enter/leave_blocking_section() need to be copied to C
>> values beforehand and values you need after need to be protected.
>> MfG
>>        Goswin
> Does it imply that, if any Ocaml binding uses
> enter/leave_blocking_section, the Ocaml runtime only switch contexts
> at enter/leave_blocking_section(). If it allows other threads run at
> any point, we might have to protect values in any function.
> -- 
> Jianzhou

It never switches threads preemptively. But I think the alloc function
potentially does switch threads. So any time you allocate some memory a
switch occurs if your thread has run enough. Something like that. This
happens all the time in the code, not just on
enter/leave_blocking_section() afaik.