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)