mirror of
https://gitlab.com/embeddable-common-lisp/ecl.git
synced 2026-01-15 05:43:19 -08:00
Yet another iteration for condition variables: now the lock is only released only once the thread has been added to the queue.
This commit is contained in:
parent
8e853cdcce
commit
9287a516ff
3 changed files with 11 additions and 6 deletions
|
|
@ -462,7 +462,6 @@ cl_object_mark_proc(void *addr, struct GC_ms_entry *msp, struct GC_ms_entry *msl
|
|||
MAYBE_MARK(o->condition_variable.queue_spinlock);
|
||||
MAYBE_MARK(o->condition_variable.queue_list);
|
||||
MAYBE_MARK(o->condition_variable.lock);
|
||||
MAYBE_MARK(o->condition_variable.signaled);
|
||||
break;
|
||||
case t_rwlock:
|
||||
MAYBE_MARK(o->rwlock.name);
|
||||
|
|
@ -1015,7 +1014,6 @@ init_alloc(void)
|
|||
to_bitmap(&o, &(o.rwlock.mutex));
|
||||
# endif
|
||||
type_info[t_condition_variable].descriptor =
|
||||
to_bitmap(&o, &(o.condition_variable.signaled)) |
|
||||
to_bitmap(&o, &(o.condition_variable.lock)) |
|
||||
to_bitmap(&o, &(o.condition_variable.queue_list)) |
|
||||
to_bitmap(&o, &(o.condition_variable.queue_spinlock));
|
||||
|
|
|
|||
|
|
@ -33,7 +33,14 @@ mp_make_condition_variable(void)
|
|||
static cl_object
|
||||
condition_variable_wait(cl_env_ptr env, cl_object cv)
|
||||
{
|
||||
return cv->condition_variable.signaled;
|
||||
cl_object lock = cv->condition_variable.lock;
|
||||
cl_object own_process = env->own_process;
|
||||
/* We have entered the queue and still own the mutex? */
|
||||
if (lock->lock.owner == own_process) {
|
||||
mp_giveup_lock(lock);
|
||||
}
|
||||
/* We always return when we have been explicitly awaken */
|
||||
return (own_process->process.waiting_for != cv)? ECL_T : ECL_NIL;
|
||||
}
|
||||
|
||||
cl_object
|
||||
|
|
@ -64,8 +71,9 @@ mp_condition_variable_wait(cl_object cv, cl_object lock)
|
|||
FEerror("mp:condition-variable-wait can not be used with recursive"
|
||||
" locks:~%~S", 1, lock);
|
||||
}
|
||||
print_lock("waiting cv %p", cv, env);
|
||||
cv->condition_variable.lock = lock;
|
||||
env->own_process->process.waiting_for = cv;
|
||||
mp_giveup_lock(cv->condition_variable.lock = lock);
|
||||
ecl_wait_on(env, condition_variable_wait, cv);
|
||||
mp_get_lock_wait(lock);
|
||||
@(return ECL_T)
|
||||
|
|
@ -81,7 +89,6 @@ cl_object
|
|||
mp_condition_variable_signal(cl_object cv)
|
||||
{
|
||||
cl_object lock = cv->condition_variable.lock;
|
||||
cv->condition_variable.signaled = ECL_T;
|
||||
ecl_wakeup_waiters(ecl_process_env(), cv,
|
||||
ECL_WAKEUP_RESET_FLAG | ECL_WAKEUP_ONE);
|
||||
@(return ECL_T)
|
||||
|
|
@ -90,6 +97,7 @@ mp_condition_variable_signal(cl_object cv)
|
|||
cl_object
|
||||
mp_condition_variable_broadcast(cl_object cv)
|
||||
{
|
||||
print_lock("waking up cv", cv);
|
||||
ecl_wakeup_waiters(ecl_process_env(), cv,
|
||||
ECL_WAKEUP_RESET_FLAG | ECL_WAKEUP_ALL);
|
||||
@(return ECL_T)
|
||||
|
|
|
|||
|
|
@ -954,7 +954,6 @@ struct ecl_condition_variable {
|
|||
cl_object queue_list;
|
||||
cl_object queue_spinlock;
|
||||
cl_object lock;
|
||||
cl_object signaled;
|
||||
};
|
||||
#endif /* ECL_THREADS */
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue