From 9287a516ff485a7e05a935fed0191fcbfd4e23a3 Mon Sep 17 00:00:00 2001 From: Juan Jose Garcia Ripoll Date: Fri, 13 Jul 2012 21:35:38 +0200 Subject: [PATCH] Yet another iteration for condition variables: now the lock is only released only once the thread has been added to the queue. --- src/c/alloc_2.d | 2 -- src/c/threads/condition_variable.d | 14 +++++++++++--- src/h/object.h | 1 - 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/src/c/alloc_2.d b/src/c/alloc_2.d index e891f8b3e..adb4b655b 100644 --- a/src/c/alloc_2.d +++ b/src/c/alloc_2.d @@ -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)); diff --git a/src/c/threads/condition_variable.d b/src/c/threads/condition_variable.d index 570cfb31b..160f832e7 100644 --- a/src/c/threads/condition_variable.d +++ b/src/c/threads/condition_variable.d @@ -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) diff --git a/src/h/object.h b/src/h/object.h index 0bf3c7a32..8d29d574a 100644 --- a/src/h/object.h +++ b/src/h/object.h @@ -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 */