/* 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); }