TEMA 2. GESTIÃN DE PROCESOS - Universidad de AlmerÃa
TEMA 2. GESTIÃN DE PROCESOS - Universidad de AlmerÃa
TEMA 2. GESTIÃN DE PROCESOS - Universidad de AlmerÃa
You also want an ePaper? Increase the reach of your titles
YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.
Diseño <strong>de</strong> Sistemas Operativos<br />
Tema <strong>2.</strong> Gestión <strong>de</strong> Procesos<br />
• La función down(sem) <strong>de</strong>crementa el contador y si el resultado es negativo entonces llama a<br />
__down_failed, que llamará a __down. Esta función está construida a base <strong>de</strong> macros, que al<br />
expandirse darían lugar a este código:<br />
void __down(struct semaphore * sem)<br />
{<br />
struct task_struct *tsk = current;<br />
struct wait_queue wait = { tsk, NULL };<br />
tsk->state = (TASK_UNINTERRUPTIBLE);<br />
add_wait_queue(&sem->wait, &wait);<br />
for (;;)<br />
{<br />
if (waking_non_zero(sem))<br />
break;<br />
schedule();<br />
tsk->state = (TASK_UNINTERRUPTIBLE);<br />
}<br />
tsk->state = TASK_RUNNING;<br />
remove_wait_queue(&sem->wait, &wait);<br />
it_queue(&sem->wait, &wait);<br />
}<br />
• Los pasos que se siguen son:<br />
− Se pone el proceso en estado bloqueado (Como veremos en el tema <strong>de</strong> planificación, en<br />
Linux el estado “bloqueado” presenta dos posibilida<strong>de</strong>s: TASK_INTERRUPTIBLE o<br />
TASK_UNINTERRUPTIBLE, que indican respectivamente si una señal pue<strong>de</strong> matar o no al<br />
proceso mientras está bloqueado).<br />
− Se inserta en la cola <strong>de</strong> espera <strong>de</strong>l semáforo.<br />
− Se entra en un bucle para asegurar que sólo un proceso pasará el semáforo <strong>de</strong>spués <strong>de</strong> la<br />
operación up. Se hace uso <strong>de</strong>l campo waking, llamando a la función waking_non_zero, que,<br />
<strong>de</strong> forma atómica, hace lo siguiente: (1) Si waking es mayor que cero le resta uno y <strong>de</strong>vuelve<br />
un uno (cierto), con lo cual saldrá <strong>de</strong>l bucle. (2) Si no, directamente <strong>de</strong>vuelve un cero (falso),<br />
dando lugar a que se llame a schedule, que pondrá otro proceso en ejecución (el proceso<br />
actual sigue en estado “bloqueado” mientras a tsk->state no se le asigne<br />
TASK_RUNNING). La i<strong>de</strong>a general es que el primer proceso en <strong>de</strong>spertar sale <strong>de</strong>l bucle y el<br />
resto, no. Cuál sea este proceso vendrá <strong>de</strong>terminado por la política <strong>de</strong> planificación.<br />
− Se pone el proceso en estado activo.<br />
− Se quita <strong>de</strong> la cola <strong>de</strong>l semáforo.<br />
<strong>2.</strong>8.6. Algunos Aspectos <strong>de</strong> Implementación en la Sincronización <strong>de</strong> Procesos.<br />
• El archivo fuente kernel/sched.c contiene funciones <strong>de</strong> servicio que permiten la sincronización <strong>de</strong><br />
procesos en modo kernel. Estas funciones se utilizan en todas las partes <strong>de</strong>l kernel cuando un<br />
proceso <strong>de</strong>be suspen<strong>de</strong>rse en espera <strong>de</strong> un evento (dormir), y cuando <strong>de</strong>be ser “<strong>de</strong>spertado”.<br />
• La función add_to_runqueue inserta un <strong>de</strong>scriptor <strong>de</strong> proceso en la lista <strong>de</strong> procesos “Listos para<br />
ejecutarse”. La función <strong>de</strong>l_from_runqueue permite suprimir un <strong>de</strong>scriptor <strong>de</strong> esta lista. Un<br />
<strong>de</strong>scriptor <strong>de</strong> proceso pue<strong>de</strong> colocarse al final <strong>de</strong> la lista utilizando la función move_last_runqueue.<br />
• Las colas <strong>de</strong> espera (wait queues) son manipuladas por las funciones __add_wait_queue y<br />
__remove_wait_queue, <strong>de</strong>claradas en el archivo <strong>de</strong> cabecera . Se aña<strong>de</strong> un<br />
elemento a la cola <strong>de</strong> espera utilizando __add_wait_queue, y se suprime <strong>de</strong> dicha cola utilizando<br />
__remove_wait_queue. Las funciones add_wait_queue y remove_wait_queue llaman<br />
respectivamente a __add_wait_queue y __remove_wait_queue ocultando previamente todas las<br />
interrupciones (funciones atómicas).<br />
• La función wake_up_process <strong>de</strong>spierta un proceso suspendido (dormido), pone su estado a<br />
TASK_RUNNING (Listo para su ejecución) y lo inserta en la lista <strong>de</strong> procesos “Listos para<br />
ejecutarse”.<br />
Departamento <strong>de</strong> Lenguajes y Computación. <strong>Universidad</strong> <strong>de</strong> Almería Página <strong>2.</strong>50