#include "sched.h"
#include "proc_queue.h"
#include "proc_struct.h"
#include <asm.h>
#include <enums.h>
void condition_init(struct condition_struct *condition)
{
proc_queue_init(&condition->proc_queue);
}
void condition_wait(struct condition_struct *condition)
{
int intr;
disable_intr(intr);
sched_remove(current);
current->state = PS_WAITING_UNINTERRUPTIBLE;
current->condition = condition;
proc_queue_push(&condition->proc_queue, current);
schedule();
restore_intr(intr);
}
int condition_wait_interruptible(struct condition_struct *condition)
{
int retval;
int intr;
disable_intr(intr);
sched_remove(current);
current->state = PS_WAITING_INTERRUPTIBLE;
current->condition = condition;
proc_queue_push(&condition->proc_queue, current);
schedule();
retval = !current->interrupted;
restore_intr(intr);
return retval;
}
void condition_signal(struct condition_struct *condition)
{
int intr;
struct proc_struct *proc;
disable_intr(intr);
if ((proc = proc_queue_pop(&condition->proc_queue))) {
proc->state = PS_RUNNING;
proc->interrupted = 0;
sched_add(proc);
}
restore_intr(intr);
}
void condition_signal_all(struct condition_struct *condition)
{
int intr;
struct proc_struct *proc;
disable_intr(intr);
while ((proc = proc_queue_pop(&condition->proc_queue))) {
proc->state = PS_RUNNING;
proc->interrupted = 0;
sched_add(proc);
}
restore_intr(intr);
}
void condition_interrupt(struct proc_struct *proc)
{
int intr;
disable_intr(intr);
proc_queue_remove(&proc->condition->proc_queue, proc);
proc->state = PS_RUNNING;
proc->interrupted = 1;
sched_add(proc);
restore_intr(intr);
}