1
Fork 0
mirror of https://git.savannah.gnu.org/git/guile.git synced 2025-05-20 03:30:27 +02:00

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.
This commit is contained in:
Andy Wingo 2016-11-13 15:08:45 +01:00
parent 1ed9dea34a
commit 6bb51193df
4 changed files with 16 additions and 22 deletions

View file

@ -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;

View file

@ -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);

View file

@ -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;

View file

@ -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;