void condvar_wait(struct condvar *cv, struct mutex *m) { uint32_t old_itr_status; struct wait_queue_elem wqe; old_itr_status = thread_mask_exceptions(THREAD_EXCP_ALL); /* Link this condvar to this mutex until reinitialized */ cpu_spin_lock(&cv->spin_lock); TEE_ASSERT(!cv->m || cv->m == m); cv->m = m; cpu_spin_unlock(&cv->spin_lock); cpu_spin_lock(&m->spin_lock); /* Add to mutex wait queue as a condvar waiter */ wq_wait_init_condvar(&m->wq, &wqe, cv); /* Unlock the mutex */ TEE_ASSERT(m->value == MUTEX_VALUE_LOCKED); thread_rem_mutex(m); m->value = MUTEX_VALUE_UNLOCKED; cpu_spin_unlock(&m->spin_lock); thread_unmask_exceptions(old_itr_status); /* Wake eventual waiters */ wq_wake_one(&m->wq); wq_wait_final(&m->wq, &wqe); mutex_lock(m); }
void mutex_unlock(struct mutex *m) { uint32_t old_itr_status; old_itr_status = thread_mask_exceptions(THREAD_EXCP_ALL); cpu_spin_lock(&m->spin_lock); TEE_ASSERT(m->value == MUTEX_VALUE_LOCKED); thread_rem_mutex(m); m->value = MUTEX_VALUE_UNLOCKED; cpu_spin_unlock(&m->spin_lock); thread_unmask_exceptions(old_itr_status); wq_wake_one(&m->wq); }
static void __mutex_unlock(struct mutex *m, const char *fname, int lineno) { uint32_t old_itr_status; assert_have_no_spinlock(); assert(thread_get_id_may_fail() != -1); old_itr_status = cpu_spin_lock_xsave(&m->spin_lock); if (m->value != MUTEX_VALUE_LOCKED) panic(); thread_rem_mutex(m); m->value = MUTEX_VALUE_UNLOCKED; cpu_spin_unlock_xrestore(&m->spin_lock, old_itr_status); wq_wake_one(&m->wq, m, fname, lineno); }