guile-commits
[Top][All Lists]
Advanced

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

[Guile-commits] GNU Guile branch, master, updated. v2.1.0-101-gd7cb7f7


From: Andy Wingo
Subject: [Guile-commits] GNU Guile branch, master, updated. v2.1.0-101-gd7cb7f7
Date: Sun, 20 Jan 2013 11:42:36 +0000

This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "GNU Guile".

http://git.savannah.gnu.org/cgit/guile.git/commit/?id=d7cb7f7925ff4a4059eb7a81a1ba5ee53e259810

The branch, master has been updated
       via  d7cb7f7925ff4a4059eb7a81a1ba5ee53e259810 (commit)
       via  a0551390d5a3dd4e9ca0920be9cf0883f36a941e (commit)
       via  d93770763b66990bd989749013b961a1c54c66fd (commit)
       via  c12fa334155da64e4e00a2a0e07a3151555d2e9c (commit)
      from  22cdf986db43ea1b81816a1cc0151994d484fdee (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit d7cb7f7925ff4a4059eb7a81a1ba5ee53e259810
Author: Andy Wingo <address@hidden>
Date:   Sun Jan 20 12:41:15 2013 +0100

    weak-table consolidation around scm_i_register_weak_gc_callback
    
    * libguile/weak-table.c (GC_move_disappearing_link)
      (move_disappearing_links): Factor out stub, as in previous weak-set
      commit.
      (resize_table): As in weak-set commit, finalizers do not run within
      allocators.
      (do_vacuum_weak_table): Add comment about need for trylock.
      (scm_c_make_weak_table): Use the new scm_i_register_weak_gc_callback.
      Previously this was the case because of a mistyped check for a
      "HAVE_GC_TABLE_START_CALLBACK" symbol, whereas the symbol was actually
      HAVE_GC_SET_START_CALLBACK.  Anyway, it's better to call this after GC
      anyway, as vacuuming might need to allocate weak links (on pre-7.3
      libgc without GC_move_disappearing_link) or reallocate the backing
      vector.

commit a0551390d5a3dd4e9ca0920be9cf0883f36a941e
Author: Andy Wingo <address@hidden>
Date:   Sun Jan 20 11:55:50 2013 +0100

    consolidate scm_i_register_weak_gc_callback, update weak-set to fit
    
    * libguile/finalizers.h:
    * libguile/finalizers.c (scm_i_register_weak_gc_callback): New internal
      helper, from weak-set.c.
    
      Relative to the previous weak-set.c version, prefer the
      finalizer-based implementation.  Fix bug regarding confusion between
      scm_before_gc_c_hook and scm_after_gc_hook.  Fix bug regarding
      referencing weak values outside of the alloc lock.
    
    * libguile/weak-set.c (GC_move_disappearing_link): New stub.
      GC_move_disappearing_link is only available in libgc 7.3.
      (move_weak_entry): Use the new stub instead of ifdeffery.
      (resize_set): Now that we run finalizers from a separate thread or
      async, we can keep the lock while reallocating the set vector.
      (do_vacuum_weak_set): For the same reason, always lock the set.
      Remove implementation of scm_c_register_weak_gc_callback in preference
      of the new copy in finalizers.c.
      (scm_c_make_weak_set): Use the new scm_i_register_weak_gc_callback.

commit d93770763b66990bd989749013b961a1c54c66fd
Author: Andy Wingo <address@hidden>
Date:   Sun Jan 20 10:48:19 2013 +0100

    gc.c: assume gc 7.2 features are present
    
    * libguile/gc.c: Remove shims for GC_get_heap_usage_safe,
      GC_get_free_space_divisor, and GC_set_finalize_on_demand.  Remove code
      in the case in which we did not have GC_set_start_callback.

commit c12fa334155da64e4e00a2a0e07a3151555d2e9c
Author: Andy Wingo <address@hidden>
Date:   Thu Jan 17 16:52:58 2013 +0100

    guile 2.2 will require libgc 7.2 or greater
    
    * configure.ac: Bump required libgc version to 7.2, released March
      2012.

-----------------------------------------------------------------------

Summary of changes:
 configure.ac          |    2 +-
 libguile/finalizers.c |   60 ++++++++++++++++++++++++++++++-
 libguile/finalizers.h |    7 +++-
 libguile/gc.c         |   50 +-------------------------
 libguile/weak-set.c   |   96 +++++++++++--------------------------------------
 libguile/weak-table.c |   93 +++++++++++------------------------------------
 6 files changed, 109 insertions(+), 199 deletions(-)

diff --git a/configure.ac b/configure.ac
index e5002b0..d41026d 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1220,7 +1220,7 @@ main (int argc, char **argv)
 # Boehm's GC library
 #
 #--------------------------------------------------------------------
-PKG_CHECK_MODULES([BDW_GC], [bdw-gc])
+PKG_CHECK_MODULES([BDW_GC], [bdw-gc >= 7.2])
 
 save_LIBS="$LIBS"
 LIBS="$BDW_GC_LIBS $LIBS"
diff --git a/libguile/finalizers.c b/libguile/finalizers.c
index 42faf72..7fadd22 100644
--- a/libguile/finalizers.c
+++ b/libguile/finalizers.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2012 Free Software Foundation, Inc.
+/* Copyright (C) 2012, 2013 Free Software Foundation, Inc.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
@@ -305,6 +305,64 @@ scm_i_finalizer_pre_fork (void)
 
 
 
+static void*
+weak_pointer_ref (void *weak_pointer) 
+{
+  return *(void **) weak_pointer;
+}
+
+static void
+weak_gc_finalizer (void *ptr, void *data)
+{
+  void **weak = ptr;
+  void *val;
+  void (*callback) (SCM) = weak[1];
+
+  val = GC_call_with_alloc_lock (weak_pointer_ref, &weak[0]);
+
+  if (!val)
+    return;
+
+  callback (SCM_PACK_POINTER (val));
+
+  scm_i_set_finalizer (ptr, weak_gc_finalizer, data);
+}
+
+/* CALLBACK will be called on OBJ, as long as OBJ is accessible.  It
+   will be called from a finalizer, which may be from an async or from
+   another thread.
+
+   As an implementation detail, the way this works is that we allocate
+   a fresh pointer-less object holding two words.  We know that this
+   object should get collected the next time GC is run, so we attach a
+   finalizer to it so that we get a callback after GC happens.
+
+   The first word of the object holds a weak reference to OBJ, and the
+   second holds the callback pointer.  When the callback is called, we
+   check if the weak reference on OBJ still holds.  If it doesn't hold,
+   then OBJ is no longer accessible, and we're done.  Otherwise we call
+   the callback and re-register a finalizer for our two-word GC object,
+   effectively resuscitating the object so that we will get a callback
+   on the next GC.
+
+   We could use the scm_after_gc_hook, but using a finalizer has the
+   advantage of potentially running in another thread, decreasing pause
+   time.  */
+void
+scm_i_register_weak_gc_callback (SCM obj, void (*callback) (SCM))
+{
+  void **weak = GC_MALLOC_ATOMIC (sizeof (void*) * 2);
+
+  weak[0] = SCM_UNPACK_POINTER (obj);
+  weak[1] = (void*)callback;
+  GC_GENERAL_REGISTER_DISAPPEARING_LINK (weak, SCM2PTR (obj));
+
+  scm_i_set_finalizer (weak, weak_gc_finalizer, NULL);
+}
+
+
+
+
 void
 scm_init_finalizers (void)
 {
diff --git a/libguile/finalizers.h b/libguile/finalizers.h
index ad14d94..2ef0751 100644
--- a/libguile/finalizers.h
+++ b/libguile/finalizers.h
@@ -1,7 +1,7 @@
 #ifndef SCM_FINALIZERS_H
 #define SCM_FINALIZERS_H
 
-/* Copyright (C) 2012 Free Software Foundation, Inc.
+/* Copyright (C) 2012, 2013 Free Software Foundation, Inc.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
@@ -36,6 +36,11 @@ SCM_INTERNAL void scm_i_add_resuscitator (void *obj, 
scm_t_finalizer_proc,
 
 SCM_INTERNAL void scm_i_finalizer_pre_fork (void);
 
+/* CALLBACK will be called on OBJ after each garbage collection, as long
+   as OBJ is accessible.  It will be called from a finalizer, which may
+   be from an async or from another thread. */
+SCM_INTERNAL void scm_i_register_weak_gc_callback (SCM obj, void (*callback) 
(SCM));
+
 SCM_INTERNAL void scm_init_finalizers (void);
 SCM_INTERNAL void scm_init_finalizer_thread (void);
 
diff --git a/libguile/gc.c b/libguile/gc.c
index 71efd03..d580a65 100644
--- a/libguile/gc.c
+++ b/libguile/gc.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1995,1996,1997,1998,1999,2000,2001, 2002, 2003, 2006, 2008, 
2009, 2010, 2011, 2012 Free Software Foundation, Inc.
+/* Copyright (C) 1995,1996,1997,1998,1999,2000,2001, 2002, 2003, 2006, 2008, 
2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
@@ -187,35 +187,6 @@ SCM_DEFINE (scm_set_debug_cell_accesses_x, 
"set-debug-cell-accesses!", 1, 0, 0,
 
 
 
-/* Compatibility.  */
-
-#ifndef HAVE_GC_GET_HEAP_USAGE_SAFE
-static void
-GC_get_heap_usage_safe (GC_word *pheap_size, GC_word *pfree_bytes,
-                        GC_word *punmapped_bytes, GC_word *pbytes_since_gc,
-                        GC_word *ptotal_bytes)
-{
-  *pheap_size = GC_get_heap_size ();
-  *pfree_bytes = GC_get_free_bytes ();
-#ifdef HAVE_GC_GET_UNMAPPED_BYTES
-  *punmapped_bytes = GC_get_unmapped_bytes ();
-#else
-  *punmapped_bytes = 0;
-#endif
-  *pbytes_since_gc = GC_get_bytes_since_gc ();
-  *ptotal_bytes = GC_get_total_bytes ();
-}
-#endif
-
-#ifndef HAVE_GC_GET_FREE_SPACE_DIVISOR
-static GC_word
-GC_get_free_space_divisor (void)
-{
-  return GC_free_space_divisor;
-}
-#endif
-
-
 /* Hooks.  */
 scm_t_c_hook scm_before_gc_c_hook;
 scm_t_c_hook scm_before_mark_c_hook;
@@ -394,9 +365,6 @@ SCM_DEFINE (scm_gc, "gc", 0, 0, 0,
 void
 scm_i_gc (const char *what)
 {
-#ifndef HAVE_GC_SET_START_CALLBACK
-  run_before_gc_c_hook ();
-#endif
   GC_gcollect ();
 }
 
@@ -611,14 +579,6 @@ scm_getenv_int (const char *var, int def)
   return res;
 }
 
-#ifndef HAVE_GC_SET_FINALIZE_ON_DEMAND
-static void
-GC_set_finalize_on_demand (int foo)
-{
-  GC_finalize_on_demand = foo;
-}
-#endif
-
 void
 scm_storage_prehistory ()
 {
@@ -1044,19 +1004,11 @@ scm_init_gc ()
   scm_c_hook_add (&scm_before_gc_c_hook, start_gc_timer, NULL, 0);
   scm_c_hook_add (&scm_after_gc_c_hook, accumulate_gc_timer, NULL, 0);
 
-#if HAVE_GC_GET_HEAP_USAGE_SAFE
   /* GC_get_heap_usage does not take a lock, and so can run in the GC
      start hook.  */
   scm_c_hook_add (&scm_before_gc_c_hook, adjust_gc_frequency, NULL, 0);
-#else
-  /* GC_get_heap_usage might take a lock (and did from 7.2alpha1 to
-     7.2alpha7), so call it in the after_gc_hook.  */
-  scm_c_hook_add (&scm_after_gc_c_hook, adjust_gc_frequency, NULL, 0);
-#endif
 
-#ifdef HAVE_GC_SET_START_CALLBACK
   GC_set_start_callback (run_before_gc_c_hook);
-#endif
 
 #include "libguile/gc.x"
 }
diff --git a/libguile/weak-set.c b/libguile/weak-set.c
index d648dbd..e8523ba 100644
--- a/libguile/weak-set.c
+++ b/libguile/weak-set.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2011, 2012 Free Software Foundation, Inc.
+/* Copyright (C) 2011, 2012, 2013 Free Software Foundation, Inc.
  * 
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
@@ -160,6 +160,15 @@ entry_distance (unsigned long hash, unsigned long k, 
unsigned long size)
     return size - origin + k;
 }
 
+#ifndef HAVE_GC_MOVE_DISAPPEARING_LINK
+static void
+GC_move_disappearing_link (void **from, void **to)
+{
+  GC_unregister_disappearing_link (from);
+  SCM_I_REGISTER_DISAPPEARING_LINK (to, *to);
+}
+#endif
+
 static void
 move_weak_entry (scm_t_weak_entry *from, scm_t_weak_entry *to)
 {
@@ -172,15 +181,7 @@ move_weak_entry (scm_t_weak_entry *from, scm_t_weak_entry 
*to)
       to->key = copy.key;
 
       if (copy.key && SCM_HEAP_OBJECT_P (SCM_PACK (copy.key)))
-        {
-#ifdef HAVE_GC_MOVE_DISAPPEARING_LINK
-          GC_move_disappearing_link ((void **) &from->key, (void **) &to->key);
-#else
-          GC_unregister_disappearing_link ((void **) &from->key);
-          SCM_I_REGISTER_DISAPPEARING_LINK ((void **) &to->key,
-                                            to->key);
-#endif
-        }
+        GC_move_disappearing_link ((void **) &from->key, (void **) &to->key);
     }
   else
     {
@@ -357,12 +358,8 @@ resize_set (scm_t_weak_set *set)
       if (new_size_index == set->size_index)
         return;
       new_size = hashset_size[new_size_index];
-      scm_i_pthread_mutex_unlock (&set->lock);
-      /* Allocating memory might cause finalizers to run, which could
-         run anything, so drop our lock to avoid deadlocks.  */
       new_entries = scm_gc_malloc_pointerless (new_size * 
sizeof(scm_t_weak_entry),
                                                "weak set");
-      scm_i_pthread_mutex_lock (&set->lock);
     }
   while (!is_acceptable_size_index (set, new_size_index));
 
@@ -423,9 +420,9 @@ resize_set (scm_t_weak_set *set)
     }
 }
 
-/* Run after GC via do_vacuum_weak_set, this function runs over the
-   whole table, removing lost weak references, reshuffling the set as it
-   goes.  It might resize the set if it reaps enough entries.  */
+/* Run from a finalizer via do_vacuum_weak_set, this function runs over
+   the whole table, removing lost weak references, reshuffling the set
+   as it goes.  It might resize the set if it reaps enough entries.  */
 static void
 vacuum_weak_set (scm_t_weak_set *set)
 {
@@ -693,63 +690,12 @@ do_vacuum_weak_set (SCM set)
 
   s = SCM_WEAK_SET (set);
 
-  if (scm_i_pthread_mutex_trylock (&s->lock) == 0)
-    {
-      vacuum_weak_set (s);
-      scm_i_pthread_mutex_unlock (&s->lock);
-    }
-
-  return;
-}
-
-/* The before-gc C hook only runs if GC_set_start_callback is available,
-   so if not, fall back on a finalizer-based implementation.  */
-static int
-weak_gc_callback (void **weak)
-{
-  void *val = weak[0];
-  void (*callback) (SCM) = weak[1];
-  
-  if (!val)
-    return 0;
-  
-  callback (SCM_PACK_POINTER (val));
-
-  return 1;
-}
-
-#ifdef HAVE_GC_SET_START_CALLBACK
-static void*
-weak_gc_hook (void *hook_data, void *fn_data, void *data)
-{
-  if (!weak_gc_callback (fn_data))
-    scm_c_hook_remove (&scm_before_gc_c_hook, weak_gc_hook, fn_data);
-
-  return NULL;
-}
-#else
-static void
-weak_gc_finalizer (void *ptr, void *data)
-{
-  if (weak_gc_callback (ptr))
-    scm_i_set_finalizer (ptr, weak_gc_finalizer, data);
-}
-#endif
-
-static void
-scm_c_register_weak_gc_callback (SCM obj, void (*callback) (SCM))
-{
-  void **weak = GC_MALLOC_ATOMIC (sizeof (void*) * 2);
-
-  weak[0] = SCM_UNPACK_POINTER (obj);
-  weak[1] = (void*)callback;
-  GC_GENERAL_REGISTER_DISAPPEARING_LINK (weak, SCM2PTR (obj));
-
-#ifdef HAVE_GC_SET_START_CALLBACK
-  scm_c_hook_add (&scm_after_gc_c_hook, weak_gc_hook, weak, 0);
-#else
-  scm_i_set_finalizer (weak, weak_gc_finalizer, NULL);
-#endif
+  /* We should always be able to grab this lock, because we are run from
+     a finalizer, which runs in another thread (or an async, which is
+     mostly equivalent).  */
+  scm_i_pthread_mutex_lock (&s->lock);
+  vacuum_weak_set (s);
+  scm_i_pthread_mutex_unlock (&s->lock);
 }
 
 SCM
@@ -759,7 +705,7 @@ scm_c_make_weak_set (unsigned long k)
 
   ret = make_weak_set (k);
 
-  scm_c_register_weak_gc_callback (ret, do_vacuum_weak_set);
+  scm_i_register_weak_gc_callback (ret, do_vacuum_weak_set);
 
   return ret;
 }
diff --git a/libguile/weak-table.c b/libguile/weak-table.c
index 9ef6674..e911069 100644
--- a/libguile/weak-table.c
+++ b/libguile/weak-table.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2011, 2012 Free Software Foundation, Inc.
+/* Copyright (C) 2011, 2012, 2013 Free Software Foundation, Inc.
  * 
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
@@ -151,31 +151,26 @@ unregister_disappearing_links (scm_t_weak_entry *entry,
     GC_unregister_disappearing_link ((void **) &entry->value);
 }
 
+#ifndef HAVE_GC_MOVE_DISAPPEARING_LINK
+static void
+GC_move_disappearing_link (void **from, void **to)
+{
+  GC_unregister_disappearing_link (from);
+  SCM_I_REGISTER_DISAPPEARING_LINK (to, *to);
+}
+#endif
+
 static void
 move_disappearing_links (scm_t_weak_entry *from, scm_t_weak_entry *to,
                          SCM key, SCM value, scm_t_weak_table_kind kind)
 {
   if ((kind == SCM_WEAK_TABLE_KIND_KEY || kind == SCM_WEAK_TABLE_KIND_BOTH)
       && SCM_HEAP_OBJECT_P (key))
-    {
-#ifdef HAVE_GC_MOVE_DISAPPEARING_LINK
-      GC_move_disappearing_link ((void **) &from->key, (void **) &to->key);
-#else
-      GC_unregister_disappearing_link ((void **) &from->key);
-      SCM_I_REGISTER_DISAPPEARING_LINK ((void **) &to->key, SCM2PTR (key));
-#endif
-    }
+    GC_move_disappearing_link ((void **) &from->key, (void **) &to->key);
 
   if ((kind == SCM_WEAK_TABLE_KIND_VALUE || kind == SCM_WEAK_TABLE_KIND_BOTH)
       && SCM_HEAP_OBJECT_P (value))
-    {
-#ifdef HAVE_GC_MOVE_DISAPPEARING_LINK
-      GC_move_disappearing_link ((void **) &from->value, (void **) &to->value);
-#else
-      GC_unregister_disappearing_link ((void **) &from->value);
-      SCM_I_REGISTER_DISAPPEARING_LINK ((void **) &to->value, SCM2PTR (value));
-#endif
-    }
+    GC_move_disappearing_link ((void **) &from->value, (void **) &to->value);
 }
 
 static void
@@ -480,11 +475,7 @@ resize_table (scm_t_weak_table *table)
       if (new_size_index == table->size_index)
         return;
       new_size = hashtable_size[new_size_index];
-      scm_i_pthread_mutex_unlock (&table->lock);
-      /* Allocating memory might cause finalizers to run, which could
-         run anything, so drop our lock to avoid deadlocks.  */
       new_entries = allocate_entries (new_size, table->kind);
-      scm_i_pthread_mutex_lock (&table->lock);
     }
   while (!is_acceptable_size_index (table, new_size_index));
 
@@ -814,6 +805,14 @@ do_vacuum_weak_table (SCM table)
 
   t = SCM_WEAK_TABLE (table);
 
+  /* Unlike weak sets, the weak table interface allows custom predicates
+     to call out to arbitrary Scheme.  There are two ways that this code
+     can be re-entrant, then: calling weak hash procedures while in a
+     custom predicate, or via finalizers run explicitly by (gc) or in an
+     async (for non-threaded Guile).  We add a restriction that
+     prohibits the first case, by convention.  But since we can't
+     prohibit the second case, here we trylock instead of lock.  Not so
+     nice.  */
   if (scm_i_pthread_mutex_trylock (&t->lock) == 0)
     {
       vacuum_weak_table (t);
@@ -823,56 +822,6 @@ do_vacuum_weak_table (SCM table)
   return;
 }
 
-/* The before-gc C hook only runs if GC_table_start_callback is available,
-   so if not, fall back on a finalizer-based implementation.  */
-static int
-weak_gc_callback (void **weak)
-{
-  void *val = weak[0];
-  void (*callback) (SCM) = weak[1];
-  
-  if (!val)
-    return 0;
-  
-  callback (SCM_PACK_POINTER (val));
-
-  return 1;
-}
-
-#ifdef HAVE_GC_TABLE_START_CALLBACK
-static void*
-weak_gc_hook (void *hook_data, void *fn_data, void *data)
-{
-  if (!weak_gc_callback (fn_data))
-    scm_c_hook_remove (&scm_before_gc_c_hook, weak_gc_hook, fn_data);
-
-  return NULL;
-}
-#else
-static void
-weak_gc_finalizer (void *ptr, void *data)
-{
-  if (weak_gc_callback (ptr))
-    scm_i_set_finalizer (ptr, weak_gc_finalizer, data);
-}
-#endif
-
-static void
-scm_c_register_weak_gc_callback (SCM obj, void (*callback) (SCM))
-{
-  void **weak = GC_MALLOC_ATOMIC (sizeof (void*) * 2);
-
-  weak[0] = SCM_UNPACK_POINTER (obj);
-  weak[1] = (void*)callback;
-  GC_GENERAL_REGISTER_DISAPPEARING_LINK (weak, SCM2PTR (obj));
-
-#ifdef HAVE_GC_TABLE_START_CALLBACK
-  scm_c_hook_add (&scm_after_gc_c_hook, weak_gc_hook, weak, 0);
-#else
-  scm_i_set_finalizer (weak, weak_gc_finalizer, NULL);
-#endif
-}
-
 SCM
 scm_c_make_weak_table (unsigned long k, scm_t_weak_table_kind kind)
 {
@@ -880,7 +829,7 @@ scm_c_make_weak_table (unsigned long k, 
scm_t_weak_table_kind kind)
 
   ret = make_weak_table (k, kind);
 
-  scm_c_register_weak_gc_callback (ret, do_vacuum_weak_table);
+  scm_i_register_weak_gc_callback (ret, do_vacuum_weak_table);
 
   return ret;
 }


hooks/post-receive
-- 
GNU Guile



reply via email to

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