1
Fork 0
mirror of https://git.savannah.gnu.org/git/guile.git synced 2025-07-02 07:40:30 +02:00

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.
This commit is contained in:
Andy Wingo 2025-06-25 11:40:21 +02:00
parent 5fe6bc9d66
commit 1520a5e425

View file

@ -65,6 +65,7 @@
#include "symbols.h" #include "symbols.h"
#include "trace.h" #include "trace.h"
#include "variable.h" #include "variable.h"
#include "vectors-internal.h"
#include "version.h" #include "version.h"
#include "vm.h" #include "vm.h"
#include "whippet-embedder.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); 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 { static struct scm_vector*
launch_data *prev; make_launch_data (SCM dynamic_state, SCM thunk)
launch_data *next; {
SCM dynamic_state; struct scm_vector *ret =
SCM thunk; 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. */ /* 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 = static scm_i_pthread_mutex_t protected_launch_data_lock =
SCM_I_PTHREAD_MUTEX_INITIALIZER; SCM_I_PTHREAD_MUTEX_INITIALIZER;
static void static void
protect_launch_data (launch_data *data) protect_launch_data (struct scm_vector *data)
{ {
scm_i_pthread_mutex_lock (&protected_launch_data_lock); scm_i_pthread_mutex_lock (&protected_launch_data_lock);
data->next = protected_launch_data;
if (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; protected_launch_data = data;
scm_i_pthread_mutex_unlock (&protected_launch_data_lock); scm_i_pthread_mutex_unlock (&protected_launch_data_lock);
} }
static void static struct scm_vector *
unprotect_launch_data (launch_data *data) unprotect_launch_data (struct scm_vector *data)
{ {
scm_i_pthread_mutex_lock (&protected_launch_data_lock); scm_i_pthread_mutex_lock (&protected_launch_data_lock);
if (data->next) SCM prev = scm_i_vector_ref (data, LAUNCH_DATA_PREV);
data->next->prev = data->prev; SCM next = scm_i_vector_ref (data, LAUNCH_DATA_NEXT);
if (data->prev) if (scm_is_true (next))
data->prev->next = data->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 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); scm_i_pthread_mutex_unlock (&protected_launch_data_lock);
return data;
} }
static void * static void *
really_launch (void *d) really_launch (void *d)
{ {
struct scm_vector *data = unprotect_launch_data (d);
scm_thread *t = SCM_I_CURRENT_THREAD; scm_thread *t = SCM_I_CURRENT_THREAD;
unprotect_launch_data (d);
/* The thread starts with asyncs blocked. */ /* The thread starts with asyncs blocked. */
t->block_asyncs++; 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; return 0;
} }
static void * static void *
launch_thread (void *d) 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_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; return NULL;
} }
@ -787,15 +807,13 @@ SCM_DEFINE (scm_sys_call_with_new_thread, "%call-with-new-thread", 1, 0, 0,
(SCM thunk), "") (SCM thunk), "")
#define FUNC_NAME s_scm_sys_call_with_new_thread #define FUNC_NAME s_scm_sys_call_with_new_thread
{ {
launch_data *data;
scm_i_pthread_t id; scm_i_pthread_t id;
int err; int err;
SCM_ASSERT (scm_is_true (scm_thunk_p (thunk)), thunk, SCM_ARG1, FUNC_NAME); SCM_ASSERT (scm_is_true (scm_thunk_p (thunk)), thunk, SCM_ARG1, FUNC_NAME);
data = scm_gc_typed_calloc (launch_data); struct scm_vector *data = make_launch_data (scm_current_dynamic_state (),
data->dynamic_state = scm_current_dynamic_state (); thunk);
data->thunk = thunk;
protect_launch_data (data); protect_launch_data (data);
err = scm_i_pthread_create (&id, NULL, launch_thread, data); err = scm_i_pthread_create (&id, NULL, launch_thread, data);
if (err) if (err)