From mboxrd@z Thu Jan 1 00:00:00 1970 Path: main.gmane.org!not-for-mail From: Kevin Ryde Newsgroups: gmane.lisp.guile.devel Subject: Re: doco scm_remember_upto_1 Date: Fri, 30 May 2003 10:04:58 +1000 Sender: guile-devel-bounces+guile-devel=m.gmane.org@gnu.org Message-ID: <87add5mh91.fsf@zip.com.au> References: <87wugjhowm.fsf@zip.com.au> <87wugjqx1g.fsf@raven.i.defaultvalue.org> <87r86rqa6m.fsf@raven.i.defaultvalue.org> <87vfw1i1jq.fsf@zip.com.au> NNTP-Posting-Host: main.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-Trace: main.gmane.org 1054253232 6135 80.91.224.249 (30 May 2003 00:07:12 GMT) X-Complaints-To: usenet@main.gmane.org NNTP-Posting-Date: Fri, 30 May 2003 00:07:12 +0000 (UTC) Original-X-From: guile-devel-bounces+guile-devel=m.gmane.org@gnu.org Fri May 30 02:07:11 2003 Return-path: Original-Received: from monty-python.gnu.org ([199.232.76.173]) by main.gmane.org with esmtp (Exim 3.35 #1 (Debian)) id 19LXQM-0001an-00 for ; Fri, 30 May 2003 02:07:11 +0200 Original-Received: from localhost ([127.0.0.1] helo=monty-python.gnu.org) by monty-python.gnu.org with esmtp (Exim 4.20) id 19LXQh-0001M4-Jo for guile-devel@m.gmane.org; Thu, 29 May 2003 20:07:31 -0400 Original-Received: from list by monty-python.gnu.org with tmda-scanned (Exim 4.20) id 19LXQ1-0000nP-71 for guile-devel@gnu.org; Thu, 29 May 2003 20:06:49 -0400 Original-Received: from mail by monty-python.gnu.org with spam-scanned (Exim 4.20) id 19LXPm-00006I-65 for guile-devel@gnu.org; Thu, 29 May 2003 20:06:36 -0400 Original-Received: from snoopy.pacific.net.au ([61.8.0.36]) by monty-python.gnu.org with esmtp (Exim 4.20) id 19LXOQ-0007KO-9F for guile-devel@gnu.org; Thu, 29 May 2003 20:05:10 -0400 Original-Received: from sunny.pacific.net.au (sunny.pacific.net.au [203.2.228.40]) h4U058PB008711 for ; Fri, 30 May 2003 10:05:08 +1000 Original-Received: from wisma.pacific.net.au (wisma.pacific.net.au [210.23.129.72]) by sunny.pacific.net.au with ESMTP id h4U058Qg009071 for ; Fri, 30 May 2003 10:05:08 +1000 (EST) Original-Received: from localhost (ppp16.dyn228.pacific.net.au [203.143.228.16]) by wisma.pacific.net.au (8.12.9/8.12.9) with ESMTP id h4U055YZ015436 for ; Fri, 30 May 2003 10:05:07 +1000 (EST) Original-Received: from gg by localhost with local (Exim 3.35 #1 (Debian)) id 19LXOF-0000sp-00; Fri, 30 May 2003 10:04:59 +1000 Original-To: guile-devel@gnu.org Mail-Copies-To: never User-Agent: Gnus/5.090019 (Oort Gnus v0.19) Emacs/21.2 (gnu/linux) X-BeenThere: guile-devel@gnu.org X-Mailman-Version: 2.1b5 Precedence: list List-Id: Developers list for Guile, the GNU extensibility library List-Help: List-Post: List-Subscribe: , List-Archive: List-Unsubscribe: , Errors-To: guile-devel-bounces+guile-devel=m.gmane.org@gnu.org Xref: main.gmane.org gmane.lisp.guile.devel:2450 X-Report-Spam: http://spam.gmane.org/gmane.lisp.guile.devel:2450 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. _______________________________________________ Guile-devel mailing list Guile-devel@gnu.org http://mail.gnu.org/mailman/listinfo/guile-devel