wingo pushed a commit to branch wip-whippet
in repository guile.

commit 033d94335af87353e26ff635cf4339f866d91d4b
Author: Andy Wingo <wi...@pobox.com>
AuthorDate: Wed Jul 2 09:45:51 2025 +0200

    Refactor sloppy smob allocation
    
    * libguile/smob.c (scm_smob_descriptor_observe_sloppy_size):
    (scm_new_smob, scm_new_double_smob): Refactor to avoid the global lock
    when allocating managed smobs.
---
 libguile/smob.c | 41 +++++++++++++++++++++--------------------
 1 file changed, 21 insertions(+), 20 deletions(-)

diff --git a/libguile/smob.c b/libguile/smob.c
index 7845e746a..e1f895491 100644
--- a/libguile/smob.c
+++ b/libguile/smob.c
@@ -278,6 +278,19 @@ scm_i_finalize_smob (struct scm_thread *thread, SCM smob)
     free_smob (smob);
 }
 
+static void
+scm_smob_descriptor_observe_sloppy_size (scm_smob_descriptor *desc, size_t 
size)
+{
+  scm_i_pthread_mutex_lock (&scm_i_misc_mutex);
+  if (desc->observed_size != size)
+    {
+      if (desc->observed_size)
+        abort ();
+      desc->observed_size = size;
+    }
+  scm_i_pthread_mutex_unlock (&scm_i_misc_mutex);
+}
+
 /* Return a SMOB with typecode TC.  */
 SCM
 scm_new_smob (scm_t_bits tc, scm_t_bits data)
@@ -288,15 +301,6 @@ scm_new_smob (scm_t_bits tc, scm_t_bits data)
   struct scm_single_smob *ret;
   size_t sz = sizeof (*ret);
 
-  scm_i_pthread_mutex_lock (&scm_i_misc_mutex);
-  if (desc->observed_size != 2)
-    {
-      if (desc->observed_size)
-        abort ();
-      desc->observed_size = 2;
-    }
-  scm_i_pthread_mutex_unlock (&scm_i_misc_mutex);
-
   if (desc->field_count)
     {
       if (desc->field_count != 1)
@@ -309,7 +313,10 @@ scm_new_smob (scm_t_bits tc, scm_t_bits data)
         ret = scm_allocate_tagged (thr, sz);
     }
   else
-    ret = scm_allocate_sloppy (thr, sz);
+    {
+      scm_smob_descriptor_observe_sloppy_size (desc, 2);
+      ret = scm_allocate_sloppy (thr, sz);
+    }
 
   ret->header.tag_and_flags = tc;
   ret->data_1 = data;
@@ -331,15 +338,6 @@ scm_new_double_smob (scm_t_bits tc, scm_t_bits data1,
   struct scm_double_smob *ret;
   size_t sz = sizeof (*ret);
 
-  scm_i_pthread_mutex_lock (&scm_i_misc_mutex);
-  if (desc->observed_size != 4)
-    {
-      if (desc->observed_size)
-        abort ();
-      desc->observed_size = 4;
-    }
-  scm_i_pthread_mutex_unlock (&scm_i_misc_mutex);
-
   if (desc->field_count)
     {
       if (!(desc->field_count == 2 || desc->field_count == 3))
@@ -352,7 +350,10 @@ scm_new_double_smob (scm_t_bits tc, scm_t_bits data1,
         ret = scm_allocate_tagged (thr, sz);
     }
   else
-    ret = scm_allocate_sloppy (thr, sz);
+    {
+      scm_smob_descriptor_observe_sloppy_size (desc, 4);
+      ret = scm_allocate_sloppy (thr, sz);
+    }
 
   ret->header.tag_and_flags = tc;
   ret->data_1 = data1;

Reply via email to