From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Original-To: caml-list@yquem.inria.fr Delivered-To: caml-list@yquem.inria.fr Received: from mail4-relais-sop.national.inria.fr (mail4-relais-sop.national.inria.fr [192.134.164.105]) by yquem.inria.fr (Postfix) with ESMTP id 161D9BBAF for ; Wed, 27 Oct 2010 17:19:54 +0200 (CEST) X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AkoEAP7fx0zZSMDqgGdsb2JhbAChWRUBAQsLChgDH744hUgEjVuIKw X-IronPort-AV: E=Sophos;i="4.58,246,1286143200"; d="scan'208";a="76640746" Received: from fmmailgate03.web.de ([217.72.192.234]) by mail4-smtp-sop.national.inria.fr with ESMTP; 27 Oct 2010 17:19:53 +0200 Received: from smtp08.web.de ( [172.20.5.216]) by fmmailgate03.web.de (Postfix) with ESMTP id 6F7BB16A3C87E; Wed, 27 Oct 2010 17:19:53 +0200 (CEST) Received: from [78.43.204.177] (helo=frosties.localdomain) by smtp08.web.de with asmtp (TLSv1:AES256-SHA:256) (WEB.DE 4.110 #24) id 1PB7n7-0003ku-00; Wed, 27 Oct 2010 17:19:53 +0200 Received: from mrvn by frosties.localdomain with local (Exim 4.72) (envelope-from ) id 1PB7n6-00016R-No; Wed, 27 Oct 2010 17:19:52 +0200 From: Goswin von Brederlow To: Jianzhou Zhao Cc: Goswin von Brederlow , Jacques Garrigue , caml-list@yquem.inria.fr Subject: Re: [Caml-list] When can we ignore CAMLparam and CAMLreturn? References: <8739rsdljr.fsf@frosties.localdomain> Date: Wed, 27 Oct 2010 17:19:52 +0200 In-Reply-To: (Jianzhou Zhao's message of "Wed, 27 Oct 2010 09:32:17 -0400") Message-ID: <87ocaf64tj.fsf@frosties.localdomain> User-Agent: Gnus/5.110009 (No Gnus v0.9) XEmacs/21.4.22 (linux, no MULE) MIME-Version: 1.0 Content-Type: text/plain; charset=iso-8859-1 Content-Transfer-Encoding: 8bit Sender: goswin-v-b@web.de X-Sender: goswin-v-b@web.de X-Provags-ID: V01U2FsdGVkX18qUPQLgnJDmwLxwsJvFwxEokZRjvRB5EAs0Rs5 g9C/OrjD/KQWux71fgPEPjan+D4+O4FtL4IFWkS2lkUjMZEPC5 FaB5A/xJU= X-Spam: no; 0.00; camlparam:01 camlreturn:01 bindings:01 camlprim:01 wosize:01 val:01 malloc:01 sizeof:01 val:01 alloc:01 function':01 camlparam:01 camlreturn:01 ocaml:01 pointers:01 Jianzhou Zhao writes: > On Wed, Oct 27, 2010 at 5:36 AM, Goswin von Brederlow wrote: >> Jacques Garrigue 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. MfG Goswin