/** * @brief Release mutex */ status_t mutex_release(mutex_t *m) { #if MUTEX_CHECK ASSERT(m->magic == MUTEX_MAGIC); if (current_thread != m->holder) panic("mutex_release: thread %p (%s) tried to release mutex %p it doesn't own. owned by %p (%s)\n", current_thread, current_thread->name, m, m->holder, m->holder ? m->holder->name : "none"); #endif enter_critical_section(); #if MUTEX_CHECK m->holder = 0; #endif if (unlikely(--m->count >= 1)) { /* release a thread */ wait_queue_wake_one(&m->wait, true, NO_ERROR); } exit_critical_section(); return NO_ERROR; }
/** * @brief Signal an event * * Signals an event. If EVENT_FLAG_AUTOUNSIGNAL is set in the event * object's flags, only one waiting thread is allowed to proceed. Otherwise, * all waiting threads are allowed to proceed until such time as * event_unsignal() is called. * * @param e Event object * @param reschedule If true, waiting thread(s) are executed immediately, * and the current thread resumes only after the * waiting threads have been satisfied. If false, * waiting threads are placed at the end of the run * queue. * * @return Returns NO_ERROR on success. */ status_t event_signal(event_t *e, bool reschedule) { enter_critical_section(); #if EVENT_CHECK ASSERT(e->magic == EVENT_MAGIC); #endif if (!e->signalled) { if (e->flags & EVENT_FLAG_AUTOUNSIGNAL) { /* try to release one thread and leave unsignalled if successful */ if (wait_queue_wake_one(&e->wait, reschedule, NO_ERROR) <= 0) { /* * if we didn't actually find a thread to wake up, go to * signalled state and let the next call to event_wait * unsignal the event. */ e->signalled = true; } } else { /* release all threads and remain signalled */ e->signalled = true; wait_queue_wake_all(&e->wait, reschedule, NO_ERROR); } } exit_critical_section(); return NO_ERROR; }