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:
parent
1ed9dea34a
commit
6bb51193df
4 changed files with 16 additions and 22 deletions
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue