Version française
Home     About     Download     Resources     Contact us    
Browse thread
Disabling the OCaml garbage collector
[ Home ] [ Index: by date | by threads ]
[ Search: ]

[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
Date: -- (:)
From: Raj Bandyopadhyay <rajb@r...>
Subject: Re: [Caml-list] Disabling the OCaml garbage collector
Dear all,

As a followup to this discussion, I have been trying to understand  
the OCaml/C interface better. Here's a very small program that I've  
been trying to get to work. It's a mutually recursive function, one  
part in C and the other in OCaml.

(* (* Implement this in C *)
let factC g n = if n=0 then [] else ("C",n)::(g (n-1));;
*)

external factC: (int ->(string * int) list) -> int -> ((string * int)  
list)= "caml_factC"
let factO g n = if n=0 then [] else ("OCaml",n)::(g (n-1));;
let rec fact n = factO (factC fact) n;;

fact 12000;;


The C function corresponding to factC is quite short, however the  
program crashes for values of n > about 11,000. I have tried  
inserting the code to register global roots (currently commented  
out), however, that makes no difference to the point of crash. I was  
just wondering if there is some really obvious step that I am  
missing, or using the wrong allocation function in Caml or something  
like that. Any suggestions would be welcome. I apologize in advice  
for inflicting code on you all, but I am out of ideas right now :(

/*
let factC g n =
         if n=0 then
                 []
         else
                 ("C",n)::(g (n-1))
*/
value caml_factC(value g,value n){
         CAMLparam2(g,n);
         CAMLlocal3(e,l,new_l);

         //C value for n
         int locn = Int_val(n);

         //2 cases
         if (locn <= 0){
                 CAMLreturn(Val_int(0)); //empty list
         }
         else {
                 e = alloc_tuple(2);  //allocate a new list element  
("C",n)
                 Store_field(e,0,copy_string("C"));
                 Store_field(e,1,n);

                 //callback the closure g
                 if(Tag_val(g) == Closure_tag) {
			//PROGRAM CRASHES HERE for large n and never returns from callback
                         l = callback(g,Val_int(locn-1));
                 } else {
                         exit(1);
                 }
                 //cons this tuple to the list obtained by callback
                 new_l = alloc(2,0); //structured list value, tag is 0
                 Store_field(new_l,0,e);
                 Store_field(new_l,1,l);

                 //now we should register e,l and new_l with the GC
		//The program crashes at the same point (n>11000) regdless of  
whether the following
		//code is commented out or not.
                 /*
                 Vstore *roots = (Vstore *)caml_stat_alloc(sizeof 
(Vstore));
                 roots->v1 = e;
                 roots->v2 = l;
                 roots->v3 = new_l;
                 caml_register_global_root(&roots->v1);
                 caml_register_global_root(&roots->v2);
                 caml_register_global_root(&roots->v3);
                 CAMLreturn(roots->v3); //newly constructed list
                 */


                 CAMLreturn(new_l); //newly constructed list
         }
}


Thanks!
Raj