guile-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: doco scm_remember_upto_1


From: Kevin Ryde
Subject: Re: doco scm_remember_upto_1
Date: Fri, 30 May 2003 10:04:58 +1000
User-agent: Gnus/5.090019 (Oort Gnus v0.19) Emacs/21.2 (gnu/linux)

I'd like to propose the words below, assuming they're true.  Perhaps
experts can review the last para in particular, and decide how much
can or should be said about gc and pre-emption.

I don't think the varargs scm_remember_upto_here should be documented,
because I don't think it can be implemented as an inline.  I guess it
appeared in the NEWS file though, so probably has to go in the
deprecated functions chapter.  (Likewise the old scm_remember I
suppose.)


Remembering During Operations
-----------------------------

It's important that a smob is visible to the garbage collector whenever
its contents are being accessed.  Otherwise it could be freed while
code is still using it.

 - C Macro: void scm_remember_upto_here_1 (SCM obj)
 - C Macro: void scm_remember_upto_here_2 (SCM obj1, SCM obj2)
     Create a reference to the given object or objects, so they're
     certain to be present on the stack or in a register up to the
     point of these macro calls, and hence won't be freed by the
     garbage collector before then.

For example consider a procedure to convert image data to a list of
pixel values.

     SCM
     image_to_list (SCM image_smob)
     {
       struct image *image;
       SCM lst;
       int i;
       SCM_ASSERT (SCM_SMOB_PREDICATE (image_tag, image_smob),
                   image_smob, SCM_ARG1, "image->list");
     
       image = (struct image *) SCM_SMOB_DATA (image_smob);
       lst = SCM_EOL;
       for (i = image->width * image->height - 1; i >= 0; i--)
         lst = scm_cons (SCM_MAKINUM (image->pixels[i]), lst);
     
       scm_remember_upto_here_1 (image_smob);
       return lst;
     }

   In the loop, only the `image' pointer is used and the C compiler has
no reason to keep the `image_smob' `SCM' anywhere.  The use of
`scm_remember_upto_here_1' however forces it to be kept until that
point, thereby ensuring there's no danger of the smob being freed and
the loop accessing freed data.

   It's not necessary to do the same for the `lst' `SCM', since that's
the return value and the compiler will therefore certainly keep it in a
register or somewhere throughout the routine.

   The previous `clear_image' example (*note Type checking::) did not
use `scm_remember_upto_here_1'.  This is because it didn't do anything
that allocated memory and hence won't trigger the garbage collector.
`image_to_list' on the other hand uses `scm_cons', which will garbage
collect when out of memory, hence requiring protection for `image_smob'.

   It's only in quite rare circumstances that a missing
`scm_remember_upto_here_1' will bite, but when it happens the
consequences are serious.  Fortunately the rule is simple: ensure the
`SCM' of a smob is referenced somewhere past all accesses to its
insides.  Do this by adding an `scm_remember_upto_here_1' if there's no
other references.

   In a multi-threaded program, it might be thought that a garbage
collect could occur in another thread at any time, and hence mean a
routine like `clear_image' would require protection too.  But currently
this is not the case, pre-emption is restricted.  Perhaps, however,
this will change in the future.




reply via email to

[Prev in Thread] Current Thread [Next in Thread]