[Guile-commits] 01/02: Move call-with-new-thread to Scheme
wingo pushed a commit to branch master in repository guile. commit f3bfe29235199e12b961c3fd1fa92666ad031d0d Author: Andy Wingo Date: Tue Oct 25 22:24:19 2016 +0200 Move call-with-new-thread to Scheme * libguile/threads.c (scm_call_with_new_thread): Trampoline to Scheme. (launch_data, really_launch, scm_sys_call_with_new_thread): Simplify. (scm_init_ice_9_threads): Capture call-with-new-thread variable. * module/ice-9/threads.scm (call-with-new-thread): Add implementation in Scheme. Should allow for easier cancel-thread via prompt abort. --- libguile/threads.c | 83 +- module/ice-9/threads.scm | 33 ++ 2 files changed, 63 insertions(+), 53 deletions(-) diff --git a/libguile/threads.c b/libguile/threads.c index 9f11ac7..1dece56 100644 --- a/libguile/threads.c +++ b/libguile/threads.c @@ -858,34 +858,29 @@ scm_without_guile (void *(*func)(void *), void *data) /*** Thread creation */ +/* Because (ice-9 boot-9) loads up (ice-9 threads), we know that this + variable will get loaded before a call to scm_call_with_new_thread + and therefore no lock or pthread_once_t is needed. */ +static SCM call_with_new_thread_var; + +SCM +scm_call_with_new_thread (SCM thunk, SCM handler) +{ + SCM call_with_new_thread = scm_variable_ref (call_with_new_thread_var); + if (SCM_UNBNDP (handler)) +return scm_call_1 (call_with_new_thread, thunk); + return scm_call_2 (call_with_new_thread, thunk, handler); +} + typedef struct { SCM parent; SCM thunk; - SCM handler; - SCM thread; - scm_i_pthread_mutex_t mutex; - scm_i_pthread_cond_t cond; } launch_data; static void * really_launch (void *d) { - launch_data *data = (launch_data *)d; - SCM thunk = data->thunk, handler = data->handler; - scm_i_thread *t; - - t = SCM_I_CURRENT_THREAD; - - scm_i_scm_pthread_mutex_lock (&data->mutex); - data->thread = scm_current_thread (); - scm_i_pthread_cond_signal (&data->cond); - scm_i_pthread_mutex_unlock (&data->mutex); - - if (SCM_UNBNDP (handler)) -t->result = scm_call_0 (thunk); - else -t->result = scm_catch (SCM_BOOL_T, thunk, handler); - + SCM_I_CURRENT_THREAD->result = scm_call_0 (((launch_data *)d)->thunk); return 0; } @@ -898,51 +893,29 @@ launch_thread (void *d) return NULL; } -SCM_DEFINE (scm_call_with_new_thread, "call-with-new-thread", 1, 1, 0, - (SCM thunk, SCM handler), - "Call @code{thunk} in a new thread and with a new dynamic state,\n" - "returning a new thread object representing the thread. The procedure\n" - "@var{thunk} is called via @code{with-continuation-barrier}.\n" - "\n" - "When @var{handler} is specified, then @var{thunk} is called from\n" - "within a @code{catch} with tag @code{#t} that has @var{handler} as its\n" - "handler. This catch is established inside the continuation barrier.\n" - "\n" - "Once @var{thunk} or @var{handler} returns, the return value is made\n" - "the @emph{exit value} of the thread and the thread is terminated.") -#define FUNC_NAME s_scm_call_with_new_thread -{ - launch_data data; +SCM_INTERNAL SCM scm_sys_call_with_new_thread (SCM); +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); - SCM_ASSERT (SCM_UNBNDP (handler) || scm_is_true (scm_procedure_p (handler)), - handler, SCM_ARG2, FUNC_NAME); GC_collect_a_little (); - data.parent = scm_current_dynamic_state (); - data.thunk = thunk; - data.handler = handler; - data.thread = SCM_BOOL_F; - scm_i_pthread_mutex_init (&data.mutex, NULL); - scm_i_pthread_cond_init (&data.cond, NULL); - - scm_i_scm_pthread_mutex_lock (&data.mutex); - err = scm_i_pthread_create (&id, NULL, launch_thread, &data); + data = scm_gc_typed_calloc (launch_data); + data->parent = scm_current_dynamic_state (); + data->thunk = thunk; + err = scm_i_pthread_create (&id, NULL, launch_thread, data); if (err) { - scm_i_pthread_mutex_unlock (&data.mutex); errno = err; scm_syserror (NULL); } - while (scm_is_false (data.thread)) -scm_i_scm_pthread_cond_wait (&data.cond, &data.mutex); - - scm_i_pthread_mutex_unlock (&data.mutex); - - return data.thread; + return SCM_UNSPECIFIED; } #undef FUNC_NAME @@ -2097,6 +2070,10 @@ static void scm_init_ice_9_threads (void *unused) { #include "libguile/threads.x" + + call_with_new_thread_var = +scm_module_variable (scm_current_module (), + scm_from_latin1_symbol ("call-with-new-thread")); } void diff --git a/module/ice-9/threads.scm b/module/ice-9/threads.scm index 49d070b..f0f08e0 100644 --- a/module/ice-9/threads.
[Guile-commits] branch master updated (9807d2d -> c957ec7)
wingo pushed a change to branch master in repository guile. from 9807d2d Fix tree-il code generation for ECMAscript `new' expression. new f3bfe29 Move call-with-new-thread to Scheme new c957ec7 Use atomics for async interrupts The 2 revisions listed above as "new" are entirely new to this repository and will be described in separate emails. The revisions listed as "adds" were already present in the repository and have only been added to this reference. Summary of changes: libguile/__scm.h|4 - libguile/_scm.h | 24 +- libguile/async.c| 181 +++ libguile/async.h|1 - libguile/atomics-internal.h | 27 +++ libguile/error.c|4 +- libguile/finalizers.c | 26 +++ libguile/fports.c |4 +- libguile/gc.c |9 +-- libguile/init.c |2 +- libguile/scmsigs.c |5 +- libguile/threads.c | 103 ++-- libguile/threads.h | 18 +++-- libguile/vm-engine.c| 19 - module/ice-9/threads.scm| 33 15 files changed, 215 insertions(+), 245 deletions(-)
[Guile-commits] 02/02: Use atomics for async interrupts
wingo pushed a commit to branch master in repository guile. commit c957ec7ab0f0a028910dc737e12191f7bdc1ca93 Author: Andy Wingo Date: Wed Oct 26 22:32:51 2016 +0200 Use atomics for async interrupts * libguile/__scm.h (SCM_TICK): Always define as scm_async_tick(). * libguile/error.c (scm_syserror, scm_syserror_msg): * libguile/fports.c (fport_read, fport_write): * libguile/_scm.h (SCM_SYSCALL): Replace SCM_ASYNC_TICK with scm_async_tick (). (SCM_ASYNC_TICK, SCM_ASYNC_TICK_WITH_CODE) (SCM_ASYNC_TICK_WITH_GUARD_CODE): Remove internal definitions. We inline into vm-engine.c, the only place where it matters. * libguile/async.h: * libguile/async.c (scm_async_tick, scm_i_setup_sleep): (scm_i_reset_sleep, scm_system_async_mark_for_thread): * libguile/threads.h (struct scm_thread_wake_data): * libguile/threads.h (scm_i_thread): * libguile/threads.c (block_self, guilify_self_1, scm_std_select): Rewrite to use sequentially-consistent atomic references. * libguile/atomics-internal.h (scm_atomic_set_pointer): (scm_atomic_ref_pointer): New definitions. * libguile/finalizers.c (queue_finalizer_async): We can allocate, so just use scm_system_async_mark_for_thread instead of the set-cdr! shenanigans. * libguile/scmsigs.c (take_signal): * libguile/gc.c (queue_after_gc_hook): Adapt to new asyncs mechanism. Can't allocate but we're just manipulating the current thread when no other threads are running so we should be good. * libguile/vm-engine.c (VM_HANDLE_INTERRUPTS): Inline the async_tick business. --- libguile/__scm.h|4 - libguile/_scm.h | 24 +- libguile/async.c| 181 +++ libguile/async.h|1 - libguile/atomics-internal.h | 27 +++ libguile/error.c|4 +- libguile/finalizers.c | 26 +++ libguile/fports.c |4 +- libguile/gc.c |9 +-- libguile/init.c |2 +- libguile/scmsigs.c |5 +- libguile/threads.c | 20 ++--- libguile/threads.h | 18 +++-- libguile/vm-engine.c| 19 - 14 files changed, 152 insertions(+), 192 deletions(-) diff --git a/libguile/__scm.h b/libguile/__scm.h index 31e3952..1ea4822 100644 --- a/libguile/__scm.h +++ b/libguile/__scm.h @@ -474,11 +474,7 @@ typedef long SCM_STACKITEM; #define SCM_STACK_PTR(ptr) ((SCM_STACKITEM *) (void *) (ptr)) -#ifdef BUILDING_LIBGUILE -#define SCM_TICK SCM_ASYNC_TICK -#else #define SCM_TICK scm_async_tick () -#endif diff --git a/libguile/_scm.h b/libguile/_scm.h index 60ad082..e482b7e 100644 --- a/libguile/_scm.h +++ b/libguile/_scm.h @@ -100,7 +100,7 @@ errno = 0; \ line;\ if (EVMSERR == errno && (vaxc$errno>>3)==(SS$_CONTROLC>>3)) \ - SCM_ASYNC_TICK; \ +scm_async_tick (); \ else \ break; \ } \ @@ -119,7 +119,7 @@ line;\ if (errno == EINTR) \ { \ - SCM_ASYNC_TICK; \ + scm_async_tick ();\ errno = EINTR;\ } \ } \ @@ -225,26 +225,6 @@ void scm_ia64_longjmp (scm_i_jmp_buf *, int); -#define SCM_ASYNC_TICK_WITH_GUARD_CODE(thr, pre, post) \ - do\ -{ \ - if (SCM_UNLIKELY (thr->pending_asyncs)) \ -{ \ - pre; \ - scm_async_tick ();\ - post; \ -} \ -} \ - while (0) - -#define SCM_ASYNC_TICK_WITH_CODE(thr, stmt) \ - SCM_ASYNC_TICK_WITH_GUARD_CODE (thr, stmt, (void) 0) -#define SCM_ASYNC_TICK \ - SCM_ASYNC_TICK_WITH_CODE (SCM_I_CURRENT_THREAD, (void) 0) - - - - #if (defined __GNUC__) # define SCM_NOINLINE __attribute__ ((__noinline__)) #else diff --git a/libguile/async.c b/libguile/asyn
[Guile-commits] Success: Hydra job gnu:guile-master:build_clang.i686-linux
Hi, The status of Hydra job ‘gnu:guile-master:build_clang.i686-linux’ has changed from "Failed with output" to "Success". For details, see https://hydra.nixos.org/build/42673232 Yay! Regards, The Hydra build daemon.
[Guile-commits] Failed with output: Hydra job gnu:guile-master:build_clang.i686-linux
Hi, The status of Hydra job ‘gnu:guile-master:build_clang.i686-linux’ has changed from "Success" to "Failed with output". For details, see https://hydra.nixos.org/build/42647853 Go forth and fix it. Regards, The Hydra build daemon.