12.10.2014 Views

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

SHOW MORE
SHOW LESS

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

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!