/* Conditions */
/* Copyright (C) 2008 Emmanuel Varoquaux
This file is part of XOS.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see . */
#include "sched.h"
#include "proc_queue.h"
#include "proc_struct.h"
#include
#include
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);
}
/* Retourne true si le processus a ete reveille par condition_signal(), false
* si l'attente a ete interrompue. */
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;
}
/* Reveille, s'il en existe, un processus en attente sur la condition. */
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);
}
/* Reveille tous les processus en attente sur la condition. */
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);
}
/* Interrompt l'attente du processus, qui doit etre dans l'etat
* PS_WAITING_INTERRUPTIBLE. */
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);
}