mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-04-30 11:50:28 +02:00
Merge branch 'master' into boehm-demers-weiser-gc
Conflicts: libguile/threads.c
This commit is contained in:
commit
00b8057d1f
11 changed files with 218 additions and 26 deletions
|
@ -97,11 +97,13 @@ static SCM
|
|||
enqueue (SCM q, SCM t)
|
||||
{
|
||||
SCM c = scm_cons (t, SCM_EOL);
|
||||
SCM_CRITICAL_SECTION_START;
|
||||
if (scm_is_null (SCM_CDR (q)))
|
||||
SCM_SETCDR (q, c);
|
||||
else
|
||||
SCM_SETCDR (SCM_CAR (q), c);
|
||||
SCM_SETCAR (q, c);
|
||||
SCM_CRITICAL_SECTION_END;
|
||||
return c;
|
||||
}
|
||||
|
||||
|
@ -114,6 +116,7 @@ static int
|
|||
remqueue (SCM q, SCM c)
|
||||
{
|
||||
SCM p, prev = q;
|
||||
SCM_CRITICAL_SECTION_START;
|
||||
for (p = SCM_CDR (q); !scm_is_null (p); p = SCM_CDR (p))
|
||||
{
|
||||
if (scm_is_eq (p, c))
|
||||
|
@ -121,10 +124,12 @@ remqueue (SCM q, SCM c)
|
|||
if (scm_is_eq (c, SCM_CAR (q)))
|
||||
SCM_SETCAR (q, SCM_CDR (c));
|
||||
SCM_SETCDR (prev, SCM_CDR (c));
|
||||
SCM_CRITICAL_SECTION_END;
|
||||
return 1;
|
||||
}
|
||||
prev = p;
|
||||
}
|
||||
SCM_CRITICAL_SECTION_END;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -134,14 +139,20 @@ remqueue (SCM q, SCM c)
|
|||
static SCM
|
||||
dequeue (SCM q)
|
||||
{
|
||||
SCM c = SCM_CDR (q);
|
||||
SCM c;
|
||||
SCM_CRITICAL_SECTION_START;
|
||||
c = SCM_CDR (q);
|
||||
if (scm_is_null (c))
|
||||
return SCM_BOOL_F;
|
||||
{
|
||||
SCM_CRITICAL_SECTION_END;
|
||||
return SCM_BOOL_F;
|
||||
}
|
||||
else
|
||||
{
|
||||
SCM_SETCDR (q, SCM_CDR (c));
|
||||
if (scm_is_null (SCM_CDR (q)))
|
||||
SCM_SETCAR (q, SCM_EOL);
|
||||
SCM_CRITICAL_SECTION_END;
|
||||
return SCM_CAR (c);
|
||||
}
|
||||
}
|
||||
|
@ -204,8 +215,7 @@ thread_free (SCM obj)
|
|||
interrupted. Upon return of this function, the current thread is
|
||||
no longer on QUEUE, even when the sleep has been interrupted.
|
||||
|
||||
The QUEUE data structure is assumed to be protected by MUTEX and
|
||||
the caller of block_self must hold MUTEX. It will be atomically
|
||||
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
|
||||
|
@ -253,9 +263,8 @@ block_self (SCM queue, SCM sleep_object, scm_i_pthread_mutex_t *mutex,
|
|||
return err;
|
||||
}
|
||||
|
||||
/* Wake up the first thread on QUEUE, if any. The caller must hold
|
||||
the mutex that protects QUEUE. The awoken thread is returned, or
|
||||
#f when the queue was empty.
|
||||
/* Wake up the first thread on QUEUE, if any. The awoken thread is
|
||||
returned, or #f if the queue was empty.
|
||||
*/
|
||||
static SCM
|
||||
unblock_from_queue (SCM queue)
|
||||
|
@ -420,6 +429,7 @@ guilify_self_1 (SCM_STACKITEM *base)
|
|||
t->result = SCM_BOOL_F;
|
||||
t->cleanup_handler = SCM_BOOL_F;
|
||||
t->mutexes = SCM_EOL;
|
||||
t->held_mutex = NULL;
|
||||
t->join_queue = SCM_EOL;
|
||||
t->dynamic_state = SCM_BOOL_F;
|
||||
t->dynwinds = SCM_EOL;
|
||||
|
@ -564,6 +574,14 @@ on_thread_exit (void *v)
|
|||
/* This handler is executed in non-guile mode. */
|
||||
scm_i_thread *t = (scm_i_thread *) v, **tp;
|
||||
|
||||
/* If this thread was cancelled while doing a cond wait, it will
|
||||
still have a mutex locked, so we unlock it here. */
|
||||
if (t->held_mutex)
|
||||
{
|
||||
scm_i_pthread_mutex_unlock (t->held_mutex);
|
||||
t->held_mutex = NULL;
|
||||
}
|
||||
|
||||
scm_i_pthread_setspecific (scm_i_thread_key, v);
|
||||
|
||||
/* Ensure the signal handling thread has been launched, because we might be
|
||||
|
@ -1437,17 +1455,15 @@ fat_mutex_unlock (SCM mutex, SCM cond,
|
|||
{
|
||||
int brk = 0;
|
||||
|
||||
scm_i_scm_pthread_mutex_lock (&c->lock);
|
||||
if (m->level > 0)
|
||||
m->level--;
|
||||
if (m->level == 0)
|
||||
m->owner = unblock_from_queue (m->waiting);
|
||||
|
||||
scm_i_pthread_mutex_unlock (&m->lock);
|
||||
|
||||
t->block_asyncs++;
|
||||
|
||||
err = block_self (c->waiting, cond, &c->lock, waittime);
|
||||
err = block_self (c->waiting, cond, &m->lock, waittime);
|
||||
scm_i_pthread_mutex_unlock (&m->lock);
|
||||
|
||||
if (err == 0)
|
||||
{
|
||||
|
@ -1462,7 +1478,6 @@ fat_mutex_unlock (SCM mutex, SCM cond,
|
|||
else if (err != EINTR)
|
||||
{
|
||||
errno = err;
|
||||
scm_i_pthread_mutex_unlock (&c->lock);
|
||||
scm_syserror (NULL);
|
||||
}
|
||||
|
||||
|
@ -1470,12 +1485,9 @@ fat_mutex_unlock (SCM mutex, SCM cond,
|
|||
{
|
||||
if (relock)
|
||||
scm_lock_mutex_timed (mutex, SCM_UNDEFINED, owner);
|
||||
scm_i_pthread_mutex_unlock (&c->lock);
|
||||
break;
|
||||
}
|
||||
|
||||
scm_i_pthread_mutex_unlock (&c->lock);
|
||||
|
||||
t->block_asyncs--;
|
||||
scm_async_click ();
|
||||
|
||||
|
@ -1583,7 +1595,6 @@ static size_t
|
|||
fat_cond_free (SCM mx)
|
||||
{
|
||||
fat_cond *c = SCM_CONDVAR_DATA (mx);
|
||||
scm_i_pthread_mutex_destroy (&c->lock);
|
||||
scm_gc_free (c, sizeof (fat_cond), "condition-variable");
|
||||
return 0;
|
||||
}
|
||||
|
@ -1607,7 +1618,6 @@ SCM_DEFINE (scm_make_condition_variable, "make-condition-variable", 0, 0, 0,
|
|||
SCM cv;
|
||||
|
||||
c = scm_gc_malloc (sizeof (fat_cond), "condition variable");
|
||||
scm_i_pthread_mutex_init (&c->lock, 0);
|
||||
c->waiting = SCM_EOL;
|
||||
SCM_NEWSMOB (cv, scm_tc16_condvar, (scm_t_bits) c);
|
||||
c->waiting = make_queue ();
|
||||
|
@ -1646,9 +1656,7 @@ SCM_DEFINE (scm_timed_wait_condition_variable, "wait-condition-variable", 2, 1,
|
|||
static void
|
||||
fat_cond_signal (fat_cond *c)
|
||||
{
|
||||
scm_i_scm_pthread_mutex_lock (&c->lock);
|
||||
unblock_from_queue (c->waiting);
|
||||
scm_i_pthread_mutex_unlock (&c->lock);
|
||||
}
|
||||
|
||||
SCM_DEFINE (scm_signal_condition_variable, "signal-condition-variable", 1, 0, 0,
|
||||
|
@ -1665,10 +1673,8 @@ SCM_DEFINE (scm_signal_condition_variable, "signal-condition-variable", 1, 0, 0,
|
|||
static void
|
||||
fat_cond_broadcast (fat_cond *c)
|
||||
{
|
||||
scm_i_scm_pthread_mutex_lock (&c->lock);
|
||||
while (scm_is_true (unblock_from_queue (c->waiting)))
|
||||
;
|
||||
scm_i_pthread_mutex_unlock (&c->lock);
|
||||
}
|
||||
|
||||
SCM_DEFINE (scm_broadcast_condition_variable, "broadcast-condition-variable", 1, 0, 0,
|
||||
|
@ -1833,7 +1839,11 @@ scm_dynwind_pthread_mutex_lock (scm_i_pthread_mutex_t *mutex)
|
|||
int
|
||||
scm_pthread_cond_wait (scm_i_pthread_cond_t *cond, scm_i_pthread_mutex_t *mutex)
|
||||
{
|
||||
scm_t_guile_ticket t = scm_leave_guile ();
|
||||
((scm_i_thread *)t)->held_mutex = mutex;
|
||||
int res = scm_i_pthread_cond_wait (cond, mutex);
|
||||
((scm_i_thread *)t)->held_mutex = NULL;
|
||||
scm_enter_guile (t);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@ -1842,7 +1852,11 @@ scm_pthread_cond_timedwait (scm_i_pthread_cond_t *cond,
|
|||
scm_i_pthread_mutex_t *mutex,
|
||||
const scm_t_timespec *wt)
|
||||
{
|
||||
scm_t_guile_ticket t = scm_leave_guile ();
|
||||
((scm_i_thread *)t)->held_mutex = mutex;
|
||||
int res = scm_i_pthread_cond_timedwait (cond, mutex, wt);
|
||||
((scm_i_thread *)t)->held_mutex = NULL;
|
||||
scm_enter_guile (t);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue