Version française
Home     About     Download     Resources     Contact us    
Browse thread
Custom blocks and finalization
[ Home ] [ Index: by date | by threads ]
[ Search: ]

[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
Date: -- (:)
From: Dr. Thomas Fischbacher <t.fischbacher@s...>
Subject: Re: [Caml-list] Custom blocks and finalization

Markus Mottl wrote:

> Yes, if your C-finalizer e.g. needs to remove global roots, this may
> not be sound.  I am not totally sure this is actually true in the
> current implementation, but at least the documentation clearly
> indicates that any interaction with the OCaml-runtime from within
> C-finalizers is prohibited.  You may essentially just extract C-values
> / pointers from the OCaml-value to be reclaimed and manipulate those.
>   

I take it you are referring to this part of the documentation (18.9.1 
bottom):

===>
Note: the finalize, compare, hash, serialize and deserialize functions
attached to custom block descriptors must never trigger a garbage 
collection.
Within these functions, do not call any of the Caml allocation 
functions, and
do not perform a callback into Caml code. Do not use CAMLparam to 
register the
parameters to these functions, and do not use CAMLreturn to return the 
result.
<===

Let's have a look at byterun/globroots.c:

/* Un-register a global C root */

CAMLexport void caml_remove_global_root(value *r)
{
  struct global_root * update[NUM_LEVELS];
  struct global_root * e, * f;
  int i;

  /* Init "cursor" to list head */
  e = (struct global_root *) &caml_global_roots;
  /* Find element in list */
  for (i = caml_global_roots.level; i >= 0; i--) {
    while (1) {
      f = e->forward[i];
      if (f == NULL || f->root >= r) break;
      e = f;
    }
    update[i] = e;
  }
  e = e->forward[0];
  /* If not found, nothing to do */
  if (e == NULL || e->root != r) return;
  /* Rebuild list without node */
  for (i = 0; i <= caml_global_roots.level; i++) {
    if (update[i]->forward[i] == e)
      update[i]->forward[i] = e->forward[i];
  }
  /* Reclaim list element */
  caml_stat_free(e);
  /* Down-correct list level */
  while (caml_global_roots.level > 0 &&
         caml_global_roots.forward[caml_global_roots.level] == NULL)
    caml_global_roots.level--;
}

...and memory.c says:

CAMLexport void caml_stat_free (void * blk)
{
  free (blk);
}



So... how could caml_remove_global_root() actually trigger a heap GC?

-- 
best regards,
Thomas Fischbacher
t.fischbacher@soton.ac.uk