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

commit 1520a5e4255ea4955b9986d489e635f694fbfbe1
Author: Andy Wingo <wi...@pobox.com>
AuthorDate: Wed Jun 25 11:40:21 2025 +0200

    Convert thread launch data to be vector
    
    Before, it was untagged, which is a problem for precise tracing.
    
    * libguile/threads.c (make_launch_data, protect_launch_data)
    (unprotect_launch_data, really_launch, launch_thread)
    (scm_sys_call_with_new_thread): Use a vector for launch data.
---
 libguile/threads.c | 70 ++++++++++++++++++++++++++++++++++--------------------
 1 file changed, 44 insertions(+), 26 deletions(-)

diff --git a/libguile/threads.c b/libguile/threads.c
index 56d9758ac..4bfa2702c 100644
--- a/libguile/threads.c
+++ b/libguile/threads.c
@@ -65,6 +65,7 @@
 #include "symbols.h"
 #include "trace.h"
 #include "variable.h"
+#include "vectors-internal.h"
 #include "version.h"
 #include "vm.h"
 #include "whippet-embedder.h"
@@ -724,61 +725,80 @@ scm_call_with_new_thread (SCM thunk, SCM handler)
   return scm_call_2 (call_with_new_thread, thunk, handler);
 }
 
-typedef struct launch_data launch_data;
+enum
+  {
+    LAUNCH_DATA_PREV,
+    LAUNCH_DATA_NEXT,
+    LAUNCH_DATA_DYNAMIC_STATE,
+    LAUNCH_DATA_THUNK,
+    LAUNCH_DATA_FIELD_COUNT
+  };
 
-struct launch_data {
-  launch_data *prev;
-  launch_data *next;
-  SCM dynamic_state;
-  SCM thunk;
-};
+static struct scm_vector*
+make_launch_data (SCM dynamic_state, SCM thunk)
+{
+  struct scm_vector *ret =
+    scm_to_vector (scm_c_make_vector (LAUNCH_DATA_FIELD_COUNT, SCM_BOOL_F));
+  scm_i_vector_set_x (ret, LAUNCH_DATA_DYNAMIC_STATE, dynamic_state);
+  scm_i_vector_set_x (ret, LAUNCH_DATA_THUNK, thunk);
+  return ret;
+}
 
 /* GC-protect the launch data for new threads.  */
-static launch_data *protected_launch_data;
+static struct scm_vector *protected_launch_data;
 static scm_i_pthread_mutex_t protected_launch_data_lock =
   SCM_I_PTHREAD_MUTEX_INITIALIZER;
 
 static void
-protect_launch_data (launch_data *data)
+protect_launch_data (struct scm_vector *data)
 {
   scm_i_pthread_mutex_lock (&protected_launch_data_lock);
-  data->next = protected_launch_data;
   if (protected_launch_data)
-    protected_launch_data->prev = data;
+    {
+      scm_i_vector_set_x (data, LAUNCH_DATA_NEXT,
+                          scm_from_vector (protected_launch_data));
+      scm_i_vector_set_x (protected_launch_data, LAUNCH_DATA_PREV,
+                          scm_from_vector (data));
+    }
   protected_launch_data = data;
   scm_i_pthread_mutex_unlock (&protected_launch_data_lock);
 }
 
-static void
-unprotect_launch_data (launch_data *data)
+static struct scm_vector *
+unprotect_launch_data (struct scm_vector *data)
 {
   scm_i_pthread_mutex_lock (&protected_launch_data_lock);
-  if (data->next)
-    data->next->prev = data->prev;
-  if (data->prev)
-    data->prev->next = data->next;
+  SCM prev = scm_i_vector_ref (data, LAUNCH_DATA_PREV);
+  SCM next = scm_i_vector_ref (data, LAUNCH_DATA_NEXT);
+  if (scm_is_true (next))
+    scm_i_vector_set_x (scm_to_vector (next), LAUNCH_DATA_PREV, prev);
+  if (scm_is_true (prev))
+    scm_i_vector_set_x (scm_to_vector (prev), LAUNCH_DATA_NEXT, next);
   else
-    protected_launch_data = data->next;
+    protected_launch_data = scm_is_true (next) ? scm_to_vector (next) : NULL;
   scm_i_pthread_mutex_unlock (&protected_launch_data_lock);
+  return data;
 }
 
 static void *
 really_launch (void *d)
 {
+  struct scm_vector *data = unprotect_launch_data (d);
   scm_thread *t = SCM_I_CURRENT_THREAD;
-  unprotect_launch_data (d);
   /* The thread starts with asyncs blocked.  */
   t->block_asyncs++;
-  SCM_I_CURRENT_THREAD->result = scm_call_0 (((launch_data *)d)->thunk);
+  SCM_I_CURRENT_THREAD->result =
+    scm_call_0 (scm_i_vector_ref (data, LAUNCH_DATA_THUNK));
   return 0;
 }
 
 static void *
 launch_thread (void *d)
 {
-  launch_data *data = (launch_data *)d;
+  struct scm_vector *data = d;
   scm_i_pthread_detach (scm_i_pthread_self ());
-  scm_i_with_guile (really_launch, d, data->dynamic_state);
+  scm_i_with_guile (really_launch, d,
+                    scm_i_vector_ref (data, LAUNCH_DATA_DYNAMIC_STATE));
   return NULL;
 }
 
@@ -787,15 +807,13 @@ SCM_DEFINE (scm_sys_call_with_new_thread, 
"%call-with-new-thread", 1, 0, 0,
            (SCM thunk), "")
 #define FUNC_NAME s_scm_sys_call_with_new_thread
 {
-  launch_data *data;
   scm_i_pthread_t id;
   int err;
 
   SCM_ASSERT (scm_is_true (scm_thunk_p (thunk)), thunk, SCM_ARG1, FUNC_NAME);
 
-  data = scm_gc_typed_calloc (launch_data);
-  data->dynamic_state = scm_current_dynamic_state ();
-  data->thunk = thunk;
+  struct scm_vector *data = make_launch_data (scm_current_dynamic_state (),
+                                              thunk);
   protect_launch_data (data);
   err = scm_i_pthread_create (&id, NULL, launch_thread, data);
   if (err)

Reply via email to