|
|
|
@ -117,3 +117,25 @@ void mutex_unlock(struct mutex_t *mutex)
|
|
|
|
|
|
|
|
|
|
restoreIRQ(irqstate);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void mutex_unlock_and_sleep(struct mutex_t *mutex)
|
|
|
|
|
{
|
|
|
|
|
DEBUG("%s: unlocking mutex. val: %u pid: %u, and take a nap\n", active_thread->name, mutex->val, thread_pid);
|
|
|
|
|
int irqstate = disableIRQ();
|
|
|
|
|
|
|
|
|
|
if (mutex->val != 0) {
|
|
|
|
|
if (mutex->queue.next) {
|
|
|
|
|
queue_node_t *next = queue_remove_head(&(mutex->queue));
|
|
|
|
|
tcb_t *process = (tcb_t*) next->data;
|
|
|
|
|
DEBUG("%s: waking up waiter.\n", process->name);
|
|
|
|
|
sched_set_status(process, STATUS_PENDING);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
mutex->val = 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
DEBUG("%s: going to sleep.\n", active_thread->name);
|
|
|
|
|
sched_set_status((tcb_t*) active_thread, STATUS_SLEEPING);
|
|
|
|
|
restoreIRQ(irqstate);
|
|
|
|
|
thread_yield();
|
|
|
|
|
}
|
|
|
|
|