diff options
author | Andy Wingo <wingo@pobox.com> | 2016-11-13 15:08:45 +0100 |
---|---|---|
committer | Andy Wingo <wingo@pobox.com> | 2016-11-13 15:56:21 +0100 |
commit | 6bb51193df3620d962df87caf8cfbf6a4256a540 (patch) | |
tree | 12e1a47062da6c71670d995de1530541fe3a7d64 | |
parent | 1ed9dea34aa8cb0cbae17200c31d1ac91a6a01de (diff) |
Refactor GC implications of thread sleep
* libguile/async.c (struct scm_thread_wake_data): Move definition here.
(scm_i_setup_sleep): Remove "sleep_object". Caller now responsible
for scm_remember_upto_here_1 as appropriate.
(scm_system_async_mark_for_thread): Remove scm_remember_upto_here_1
call.
* libguile/async.h (scm_i_setup_sleep): Adapt prototype.
* libguile/threads.h (struct scm_thread_wake_data): Remove definition.
* libguile/threads.c (block_self): Remove sleep_object argument.
(scm_join_thread_timed, scm_timed_lock_mutex)
(scm_timed_wait_condition_variable, scm_std_select): Adapt.
-rw-r--r-- | libguile/async.c | 12 | ||||
-rw-r--r-- | libguile/async.h | 2 | ||||
-rw-r--r-- | libguile/threads.c | 17 | ||||
-rw-r--r-- | libguile/threads.h | 7 |
4 files changed, 16 insertions, 22 deletions
diff --git a/libguile/async.c b/libguile/async.c index b4a2c2ad2..174a87afb 100644 --- a/libguile/async.c +++ b/libguile/async.c @@ -75,15 +75,19 @@ scm_async_tick (void) } } +struct scm_thread_wake_data { + scm_i_pthread_mutex_t *mutex; + int fd; +}; + int scm_i_setup_sleep (scm_i_thread *t, - SCM sleep_object, scm_i_pthread_mutex_t *sleep_mutex, + scm_i_pthread_mutex_t *sleep_mutex, int sleep_fd) { struct scm_thread_wake_data *wake; wake = scm_gc_typed_calloc (struct scm_thread_wake_data); - wake->object = sleep_object; wake->mutex = sleep_mutex; wake->fd = sleep_fd; @@ -148,10 +152,6 @@ SCM_DEFINE (scm_system_async_mark_for_thread, "system-async-mark", 1, 1, 0, scm_i_pthread_cond_signal (&t->sleep_cond); scm_i_pthread_mutex_unlock (wake->mutex); - /* This is needed to protect wake->mutex. - */ - scm_remember_upto_here_1 (wake->object); - if (wake->fd >= 0) { char dummy = 0; diff --git a/libguile/async.h b/libguile/async.h index 2a57236ca..343cc2ae6 100644 --- a/libguile/async.h +++ b/libguile/async.h @@ -35,7 +35,7 @@ SCM_API void scm_switch (void); SCM_API SCM scm_system_async_mark (SCM a); SCM_API SCM scm_system_async_mark_for_thread (SCM a, SCM thread); SCM_INTERNAL int scm_i_setup_sleep (scm_i_thread *, - SCM obj, scm_i_pthread_mutex_t *m, + scm_i_pthread_mutex_t *m, int fd); SCM_INTERNAL void scm_i_reset_sleep (scm_i_thread *); SCM_API SCM scm_noop (SCM args); diff --git a/libguile/threads.c b/libguile/threads.c index 863c84f71..211e57ee2 100644 --- a/libguile/threads.c +++ b/libguile/threads.c @@ -290,9 +290,6 @@ thread_print (SCM exp, SCM port, scm_print_state *pstate SCM_UNUSED) The caller of block_self must hold MUTEX. It will be atomically unlocked while sleeping, just as with scm_i_pthread_cond_wait. - SLEEP_OBJECT is an arbitrary SCM value that is kept alive as long - as MUTEX is needed. - When WAITTIME is not NULL, the sleep will be aborted at that time. The return value of block_self is an errno value. It will be zero @@ -304,14 +301,14 @@ thread_print (SCM exp, SCM port, scm_print_state *pstate SCM_UNUSED) The system asyncs themselves are not executed by block_self. */ static int -block_self (SCM queue, SCM sleep_object, scm_i_pthread_mutex_t *mutex, +block_self (SCM queue, scm_i_pthread_mutex_t *mutex, const scm_t_timespec *waittime) { scm_i_thread *t = SCM_I_CURRENT_THREAD; SCM q_handle; int err; - if (scm_i_setup_sleep (t, sleep_object, mutex, -1)) + if (scm_i_setup_sleep (t, mutex, -1)) { scm_i_reset_sleep (t); err = EINTR; @@ -988,8 +985,9 @@ SCM_DEFINE (scm_join_thread_timed, "join-thread", 1, 2, 0, { while (1) { - int err = block_self (t->join_queue, thread, &t->admin_mutex, + int err = block_self (t->join_queue, &t->admin_mutex, timeout_ptr); + scm_remember_upto_here_1 (thread); if (err == 0) { if (t->exited) @@ -1200,7 +1198,8 @@ SCM_DEFINE (scm_timed_lock_mutex, "lock-mutex", 1, 1, 0, return SCM_BOOL_F; } } - block_self (m->waiting, mutex, &m->lock, waittime); + block_self (m->waiting, &m->lock, waittime); + scm_remember_upto_here_1 (mutex); scm_i_pthread_mutex_unlock (&m->lock); SCM_TICK; scm_i_scm_pthread_mutex_lock (&m->lock); @@ -1425,7 +1424,7 @@ SCM_DEFINE (scm_timed_wait_condition_variable, "wait-condition-variable", 2, 1, t->block_asyncs++; - err = block_self (c->waiting, cond, &m->lock, waittime); + err = block_self (c->waiting, &m->lock, waittime); scm_i_pthread_mutex_unlock (&m->lock); if (err == 0) @@ -1543,7 +1542,7 @@ scm_std_select (int nfds, readfds = &my_readfds; } - while (scm_i_setup_sleep (t, SCM_BOOL_F, NULL, t->sleep_pipe[1])) + while (scm_i_setup_sleep (t, NULL, t->sleep_pipe[1])) { scm_i_reset_sleep (t); SCM_TICK; diff --git a/libguile/threads.h b/libguile/threads.h index ce8148f4e..db52f16b7 100644 --- a/libguile/threads.h +++ b/libguile/threads.h @@ -47,12 +47,7 @@ SCM_API scm_t_bits scm_tc16_thread; SCM_API scm_t_bits scm_tc16_mutex; SCM_API scm_t_bits scm_tc16_condvar; -struct scm_thread_wake_data -{ - SCM object; - scm_i_pthread_mutex_t *mutex; - int fd; -}; +struct scm_thread_wake_data; typedef struct scm_i_thread { struct scm_i_thread *next_thread; |