From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: ludo@gnu.org (Ludovic =?iso-8859-1?Q?Court=E8s?=) Newsgroups: gmane.lisp.guile.devel Subject: Re: Fluids Date: Wed, 03 Mar 2010 00:52:05 +0100 Message-ID: <87iq9ez3h6.fsf@gnu.org> References: <87eiknx4zl.fsf@gnu.org> NNTP-Posting-Host: lo.gmane.org Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" X-Trace: dough.gmane.org 1267573950 14798 80.91.229.12 (2 Mar 2010 23:52:30 GMT) X-Complaints-To: usenet@dough.gmane.org NNTP-Posting-Date: Tue, 2 Mar 2010 23:52:30 +0000 (UTC) To: guile-devel@gnu.org Original-X-From: guile-devel-bounces+guile-devel=m.gmane.org@gnu.org Wed Mar 03 00:52:26 2010 Return-path: Envelope-to: guile-devel@m.gmane.org Original-Received: from lists.gnu.org ([199.232.76.165]) by lo.gmane.org with esmtp (Exim 4.69) (envelope-from ) id 1Nmbt4-0000fa-5H for guile-devel@m.gmane.org; Wed, 03 Mar 2010 00:52:26 +0100 Original-Received: from localhost ([127.0.0.1]:40653 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1Nmbt3-0000BQ-G1 for guile-devel@m.gmane.org; Tue, 02 Mar 2010 18:52:25 -0500 Original-Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1Nmbsz-0000Ag-HN for guile-devel@gnu.org; Tue, 02 Mar 2010 18:52:21 -0500 Original-Received: from [140.186.70.92] (port=47219 helo=eggs.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1Nmbsy-0000AO-Az for guile-devel@gnu.org; Tue, 02 Mar 2010 18:52:20 -0500 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.69) (envelope-from ) id 1Nmbsw-0001v2-Ko for guile-devel@gnu.org; Tue, 02 Mar 2010 18:52:20 -0500 Original-Received: from lo.gmane.org ([80.91.229.12]:57608) by eggs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1Nmbsw-0001uw-9v for guile-devel@gnu.org; Tue, 02 Mar 2010 18:52:18 -0500 Original-Received: from list by lo.gmane.org with local (Exim 4.69) (envelope-from ) id 1Nmbsv-0000a8-Hy for guile-devel@gnu.org; Wed, 03 Mar 2010 00:52:17 +0100 Original-Received: from acces.bordeaux.inria.fr ([193.50.110.5]) by main.gmane.org with esmtp (Gmexim 0.1 (Debian)) id 1AlnuQ-0007hv-00 for ; Wed, 03 Mar 2010 00:52:17 +0100 Original-Received: from ludo by acces.bordeaux.inria.fr with local (Gmexim 0.1 (Debian)) id 1AlnuQ-0007hv-00 for ; Wed, 03 Mar 2010 00:52:17 +0100 X-Injected-Via-Gmane: http://gmane.org/ Original-Lines: 164 Original-X-Complaints-To: usenet@dough.gmane.org X-Gmane-NNTP-Posting-Host: acces.bordeaux.inria.fr X-URL: http://www.fdn.fr/~lcourtes/ X-Revolutionary-Date: 13 =?iso-8859-1?Q?Vent=F4se?= an 218 de la =?iso-8859-1?Q?R=E9volution?= X-PGP-Key-ID: 0xEA52ECF4 X-PGP-Key: http://www.fdn.fr/~lcourtes/ludovic.asc X-PGP-Fingerprint: 83C4 F8E5 10A3 3B4C 5BEA D15D 77DD 95E2 EA52 ECF4 X-OS: x86_64-unknown-linux-gnu User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/23.1 (gnu/linux) Cancel-Lock: sha1:pocWC4IZijShluXRRVez159DGSs= X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6 (newer, 3) X-BeenThere: guile-devel@gnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "Developers list for Guile, the GNU extensibility library" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Original-Sender: guile-devel-bounces+guile-devel=m.gmane.org@gnu.org Errors-To: guile-devel-bounces+guile-devel=m.gmane.org@gnu.org Xref: news.gmane.org gmane.lisp.guile.devel:10011 Archived-At: --=-=-= Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit Hello, ludo@gnu.org (Ludovic Courtès) writes: > Andy Wingo writes: > >> But you can't / shouldn't make a new fluid every time you enter a >> `catch', because currently fluids are never garbage collected! We really >> need to fix this. I think it's a 1.9 regression. > > Indeed. We should use a weak vector or some such instead of the current > scm_gc_malloc’d array. Just to clarify: fluids themselves *are* GC’d, but fluid numbers aren’t recycled so ALLOCATED_FLUIDS grows endlessly (1 byte per fluid). The working patch below allows fluid numbers to be recycled but it’s inefficient. Needs more thought. Thanks, Ludo’. --=-=-= Content-Type: text/x-patch Content-Disposition: inline; filename*=us-ascii''%2c%2crecycle-fluid-numbers.patch Content-Description: the patch diff --git a/libguile/fluids.c b/libguile/fluids.c index d493053..157737a 100644 --- a/libguile/fluids.c +++ b/libguile/fluids.c @@ -34,6 +34,7 @@ #include "libguile/deprecation.h" #include "libguile/lang.h" #include "libguile/validate.h" +#include "libguile/bdw-gc.h" #define FLUID_GROW 20 @@ -63,7 +64,7 @@ static scm_i_pthread_mutex_t fluid_admin_mutex = SCM_I_PTHREAD_MUTEX_INITIALIZER */ static size_t allocated_fluids_len = 0; static size_t allocated_fluids_num = 0; -static char *allocated_fluids = NULL; +static void **allocated_fluids = NULL; #define IS_FLUID(x) SCM_I_FLUID_P (x) #define FLUID_NUM(x) SCM_I_FLUID_NUM (x) @@ -120,45 +121,53 @@ scm_i_dynamic_state_print (SCM exp, SCM port, scm_print_state *pstate SCM_UNUSED scm_putc ('>', port); } -static size_t -next_fluid_num () +static SCM +new_fluid () { size_t n; + SCM fluid; + + /* Fluids are cells: the first word is the type tag; the second word is the + fluid number. */ + fluid = PTR2SCM (scm_gc_malloc_pointerless (sizeof (scm_t_cell), "fluid")); + SCM_SET_CELL_TYPE (fluid, scm_tc7_fluid); + + /* Look for a fluid number. */ scm_dynwind_begin (0); scm_i_dynwind_pthread_mutex_lock (&fluid_admin_mutex); - if ((allocated_fluids_len > 0) && - (allocated_fluids_num == allocated_fluids_len)) - { - /* All fluid numbers are in use. Run a GC to try to free some - up. - */ - scm_gc (); - } - if (allocated_fluids_num < allocated_fluids_len) + n = allocated_fluids_num; + else { + /* All fluid numbers are in use. Run a GC and look for a number recently + freed. */ + scm_i_gc ("fluids"); + for (n = 0; n < allocated_fluids_len; n++) - if (allocated_fluids[n] == 0) - break; + if (allocated_fluids[n] == NULL) + { + allocated_fluids_num--; + break; + } } - else + + if (n >= allocated_fluids_len) { /* Grow the vector of allocated fluids. */ - /* FIXME: Since we use `scm_malloc ()', ALLOCATED_FLUIDS is scanned by - the GC; therefore, all fluids remain reachable for the entire - program lifetime. Hopefully this is not a problem in practice. */ - char *new_allocated_fluids = - scm_gc_malloc (allocated_fluids_len + FLUID_GROW, - "allocated fluids"); + void **new_allocated_fluids = + scm_gc_malloc_pointerless ((allocated_fluids_len + FLUID_GROW) + * sizeof (*allocated_fluids), + "allocated fluids"); /* Copy over old values and initialize rest. GC can not run during these two operations since there is no safe point in - them. - */ - memcpy (new_allocated_fluids, allocated_fluids, allocated_fluids_len); - memset (new_allocated_fluids + allocated_fluids_len, 0, FLUID_GROW); + them. */ + memcpy (new_allocated_fluids, allocated_fluids, + allocated_fluids_len * sizeof (*allocated_fluids)); + memset (new_allocated_fluids + allocated_fluids_len, 0, + FLUID_GROW * sizeof (*allocated_fluids)); n = allocated_fluids_len; /* Update the vector of allocated fluids. Dynamic states will @@ -167,12 +176,16 @@ next_fluid_num () allocated_fluids = new_allocated_fluids; allocated_fluids_len += FLUID_GROW; } - + allocated_fluids_num += 1; - allocated_fluids[n] = 1; - + allocated_fluids[n] = SCM2PTR (fluid); + SCM_SET_CELL_WORD_1 (fluid, (scm_t_bits) n); + + GC_GENERAL_REGISTER_DISAPPEARING_LINK (&allocated_fluids[n], + SCM2PTR (fluid)); + scm_dynwind_end (); - return n; + return fluid; } SCM_DEFINE (scm_make_fluid, "make-fluid", 0, 0, 0, @@ -186,7 +199,7 @@ SCM_DEFINE (scm_make_fluid, "make-fluid", 0, 0, 0, "with its own dynamic state, you can use fluids for thread local storage.") #define FUNC_NAME s_scm_make_fluid { - return scm_cell (scm_tc7_fluid, (scm_t_bits) next_fluid_num ()); + return new_fluid (); } #undef FUNC_NAME --=-=-=--