Está en la página 1de 7

dio de un S.O. Gestin de procesos.

Introduccin y Tabla de Pr
JuanCarlos PerezCortes

Estudio de un S.O. Gestin de procesos. Introduccin y Tabla de Procesos.

Table of Contents
Tema 8. Gestin de procesos..............................................................................................................................1
8.1 Introduccin.......................................................................................................................................1
8.2 Tipos de procesos...............................................................................................................................1
8.3 Polticas de planificacin en Linux....................................................................................................1
8.4 Estructuras utilizadas por el planificador...........................................................................................2
8.5 El planificador: schedule().................................................................................................................2

Tema 8. Gestin de procesos


Planificacin.
Juan Carlos Prez y Sergio Sez
Juan Carlos Prez jcperez@disca.upv.es
Sergio Sez ssaez@disca.upv.es

8.1 Introduccin
En este tema se van a estudiar las funciones relacionadas con el proceso de planificacin.
El algoritmo de planificacin es el encargado de elegir, en un momento dado, el proceso ms
prioritario del sistema, de entre los que estn preparados para ejecucin.
En Linux, la planificacin de procesos se lleva a cabo en la funcin schedule()[kernel/sched.c#L549].
Aun as, existen otras funciones que tambin estn involucradas en la planificacin, como ya
veremos.
El algoritmo de planificacin de Linux utiliza diversas polticas de planificacin, en funcin del tipo
de proceso. En este tema se vern las diversas polticas y como afectan las polticas de planificacin a
la organizacin de los procesos y a su planificacin.

8.2 Tipos de procesos


El algoritmo de planificacin deber repartir de la forma ms justa posible el uso de la CPU entre diversos
tipos de procesos:
Los procesos de tiempo real, que son aquellos cuyo tiempo de respuesta tiene que estar acotado para
que no excedan un cierto umbral mximo.
Los procesos en segundo plano (procesos de clculo y servidores), que no tienen interaccin con el
usuario y cuyo tiempo de respuesta no es en absoluto crtico.
Los procesos interactivos, no suelen usar mucho tiempo de cmputo, pero, cuando lo requieren, la
respuesta debe ser relativamente rpida, ya que al otro lado hay un usuario (normalmente
impaciente).
Nota: Los procesos en segundo plano, al igual que los procesos interactivos, pueden llegar a tener una fuerte
actividad de E/S, por lo que a veces sern dificiles de distinguir.

8.3 Polticas de planificacin en Linux


Existen tres polticas de planificacin en Linux para dos tipos de procesos: los procesos normales de UNIX y
los procesos de tiempo real.
Los procesos normales de UNIX, incluyendo a los procesos interactivos, se planifican bajo la poltica
Tema 8. Gestin de procesos

Estudio de un S.O. Gestin de procesos. Introduccin y Tabla de Procesos.


SCHED_OTHER. sta es una poltica de tipo Round Robin pero en la que cada proceso tiene un
quantum diferente, y en la que se intentar potenciar el tiempo de respuesta de los procesos
interactivos. El proceso elegido ser aquel al que le quede mayor cantidad de quantum por consumir.
Los procesos de tiempo real son aquellos que deben tener un tiempo de respuesta garantizado, por
ello son los ms prioritarios del sistema. Bajo este tipo de polticas, el procesador se le conceder al
proceso de tiempo real con mayor prioridad preparado para ejecucin. Existen dos variantes:
SCHED_FIFO: Estos procesos no pierden el procesador hasta que se bloquean asimismos, o
se activa un proceso de tiempo real con mayor prioridad.
SCHED_RR: Se comportan igual que en el caso anterior, salvo que cuando se les acaba el
quantum ceden el procesador voluntariamente a otros procesos de tiempo real con la misma
prioridad (Se colocan al final de la "cola" de su prioridad).
Los procesos de tiempo real tienen una prioridad fija (indicada en el campo rt_priority de su
task_struct).

8.4 Estructuras utilizadas por el planificador


A parte del task_struct de cada proceso, el planificador utiliza otras estructuras de datos. Slo se van a
ver algunas de ellas, sobretodo las del caso uniprocesador. El resto se comentarn, en su caso, en el momento
de su utilizacin.
El proceso actual se identifica mediante la macro current[include/asmi386/current.h#L13]. Esta macro es
una invocacin a la funcin get_current()[include/asmi386/current.h#L6], que devuelve el puntero a la
task_struct del proceso actual a partir del puntero de pila del ncleo.
El procesador actual se obtiene con la macro smp_processor_id()[include/asmi386/smp.h]. Esta
macro simplemente devuelve el contenido del campo processor del proceso actual.
Las tareas iniciales[kernel/sched.c#L79] son las tareas predeterminadas para cada procesador. Si
no hay ninguna otra tarea lista para ejecutarse en dicho procesador, se ejecutar la tarea inicial
correspondiente. Para acceder a la tarea inicial de cada procesador se utiliza la macro
idle_task(this_cpu)[kernel/sched.c#L115].
Existen dos cerrojos para las colas de tareas:
spinlock_t runqueue_lock[kernel/sched.c#L92]: Es un cerrojo sobre las lista de tareas en
ejecucin. La cabeza de la lista es runqueue_head[kernel/sched.c#L95].
rwlock_t tasklist_lock[kernel/sched.c#L93]: Es un cerrojo de lectura/escritura sobre la
lista que contiene a todas las tareas del sistema.

8.5 El planificador: schedule()


Vamos a analizar paso a paso el cdigo de schedule[kernel/sched.c#L539].
Declaraciones y control de errores
Se definen, entre otros, los punteros a la tabla de procesos prev y next, que apuntarn,
respectivamente, al proceso que estaba en ejecucin antes de planificar y al que se debe poner en
8.4 Estructuras utilizadas por el planificador

Estudio de un S.O. Gestin de procesos. Introduccin y Tabla de Procesos.


marcha (prev y next pueden acabr siendo el mismo proceso). [#5514]
Se hace una prebsqueda del cerrojo que vamos a utilizar en breve. [#557]
Se comprueba que el proceso actual tiene un mapa de memoria activo. Si no es as, es un fallo grave:
BUG. [#559]
Se obtienen los punteros al proceso actual (prev) y la cpu actual (this_cpu). [#5612]
Comprueba si estamos en una rutina de servicio, en cuyo caso algo ha ido mal: BUG. [#5647]

Preliminares a la planificacin
Se adquiere el cerrojo sobre la cola de ejecucin. [#577]
Si el proceso actual (prev) sigue la poltica round robinSCHED_RR, entonces hay que comprobar si
ya se le ha acabado el quantum y en su caso enviarlo al final de la cola de preparados. [#5804]
Si el proceso actual no est en el estado TASK_RUNNING, hay que quitarlo de la cola de preparados.
Si est bloqueado pero aceptando seales (TASK_INTERRUPTIBLE), se comprueba si hay que
enviarle una seal y despertarlo. Si no, se elimina tambin de la cola (al no ejecutarse el break).
[#58695]

Se elimina la marca de que hay que replanificar al proceso actual (need_resched).


need_resched es un campo del proceso en lugar de una variable global, para facilitar el trabajo en
multiproceso simtrico (SMP). [#596]

Seleccionando el siguiente proceso a ejecutar


La tarea idle asociada al procesador actual se considera como la tarea predeterminada "en ejecucin"
cuando no hay ningn otro proceso real preparado. Su prioridad se establece a 1000. [#6067]
Se recorrer la lista de procesos en ejecucin (TASK_RUNNING) buscando al proceso ms prioritario
en ese momento, que quedar alamacenado en la variable next. [#60815]
El puntero a la tabla de procesos p se utilizar para acceder a los procesos de la lista. [#609]
Para cada proceso de la lista de ejecucin se comprueba si se puede ejecutar en esta CPU. No est en
ejecucin en otra CPU (cpus_runnable distinto de ~0) y el campo cpus_allowed indica que
s se puede ejecutar en esta CPU. Esta comprobacin se realiza con la macro
can_schedule()[kernel/sched.c#L118]. Se comprueba que no est en ejecucin en otra CPU porque
los procesos que estn ejecutndose en alguna CPU siguen en la lista de procesoso en ejecucin.[#610]

Seleccionando el siguiente proceso a ejecutar (cont.)


Se calcula el peso o prioridad del proceso invocando a la funcin goodness()[kernel/sched.c#L130]. Se
le pasa como parmetros el puntero a la task_struct del proceso, el identificador de la CPU
actual y un puntero al mapa de memoria activo hasta ahora. [#611]
En c tendremos siempre el mayor valor de prioridad y en next el puntero al proceso con la mxima
prioridad. [#6123]
La funcin goodness()[kernel/sched.c#L130] devuelve un valor que representa la urgencia de ejecucin
de acuerdo a diversos criterios:
El valor base de weight, variable que al final se devuelve, resulta de sumar diversos valores
...
Si el proceso ha cedido voluntariamente la CPU (SCHED_YIELD), se devolver 1. [#1535]
El valor de weight resulta de sumar el numero de ticks que le quedan al proceso
8.4 Estructuras utilizadas por el planificador

Estudio de un S.O. Gestin de procesos. Introduccin y Tabla de Procesos.


(p>counter, prioridad dinmica) [#168] ms su prioridad esttica (20p>nice) [#182].
En multiproceso simtrico se le da ms prioridad a los procesos que no cambian de
procesador. [#1756]
Para reducir cambios de contexto, se le da una pequea ventaja a los procesos que comparten
el mismo mapa de memoria que el proceso actual (threads). [#1801]
Los procesos de tiempo real (SCHED_FIFO y SCHED_RR) tienen ms importancia que el
resto de procesos. Su peso es 1000 ms su prioridad de tiempo real, que siempre ser
superior al de los procesos "normales" (SCHED_OTHER). [#191]
Hay que tener en cuenta que la funcin goodness es invocada varias veces (pueden ser muchas)
cada vez que se planifica. Esto implica que su simplicidad y eficiencia son cruciales para las
prestaciones del sistema.
Por otro lado, tambin es crucial que los valores obtenidos sean razonables y contemplen
correctamente las situaciones ms importantes. Obteniendo:
1 si el proceso ha cedido la CPU.
0 si el proceso ha agotado su quantum.
>1 si el proceso tiene quantum. Cuanto ms quantum, ms prioridad.
>1000 si el proceso es de tiempo real.

Rellenando el quantum de los procesos


Si el bucle no ha encontrado a ningn proceso con quantum por ejecutar, entonces se llena el
quantum de todos los procesos. [#61828]
Se libera el cerrojo sobre la cola de ejecucin, pues durante un periodo considerable de tiempo, no
vamos a manipularla. Posteriormente se adquiere un cerrojo de lectura sobre la lista de procesos del
sistema. [#6212]
Para cada proceso, se rellena su contador con el valor que tuviera divido por dos (para evitar que
sature) ms el valor de la prioridad esttica obtenido a partir del campo
nice (NICE_TO_TICKS[kernel/sched.c#L48]). [#6234] Obsrvese cmo a TODOS los procesos se les
actualiza su variable counter aunque no estn en la cola de procesos activos. De esta forma se
beneficia a los procesos que necesitan poco tiempo de CPU (procesos interactivos como editores de
texto, intrpretes de rdenes, etc) y se penaliza a los que consumen mucho.
Finalmente, se libera el cerrojo de lectura sobre la lista de tareas y se vuelve adquirir el cerrojo sobre
la lista de ejecucin, saltando a la etiqueta repeat_schedule, para repetir el proceso de
seleccin. [#6257]

Almacenando la decisin del algoritmo de planificacin


Una vez se llega a este punto, ya es inevitable que el proceso apuntado por la variable next se apropie de la
CPU. A continuacin se actualiza la informacin asociada a esta decisin.
Almacena el puntero al proceso escogido en la estructura sched_data (struct
schedule_data[kernel/sched.c#L101]) [#635]En el caso multiprocesador, tambin se almacena el
instante en que el proceso adquiere la CPU (en ciclos). [#653]
Actualiza los campos processor y cpu_runnable del proceso escogido mediante la funcin
task_set_cpu()[include/linux/sched.h#L556]. [#636]
Se libera el cerrojo sobre la cola de ejecucin. [#637]
8.4 Estructuras utilizadas por el planificador

Estudio de un S.O. Gestin de procesos. Introduccin y Tabla de Procesos.


En el caso poco probable de que el proceso escogido sea el mismo que estaba en ejecucin, se toma
un atajo para saltarnos el cambio de contexto, limpiando el bit SCHED_YIELD y saltando al final de
schedule(). [#63943]

Llevando a cabo el cambio de contexto


Si el proceso candidato (el ms prioritario) no es el mismo que el ltimo proceso en ejecucin se producir un
cambio de contexto.
Se incrementa el nmero de cambios de contexto. Dato que se puede consultar en el fichero especial
/proc/stat.[#663]
prepare_to_switch() es una funcin vaca en el i386. [#673]
En este bloque de cdigo se lleva a cabo el cambio de contexto del mapa de memoria. Se estudiar en
el siguiente tema. [#67491]
En la macro switch_to se lleva a cabo el resto del cambio de contexto. Es importante insistir en
que DE switch_to NO SE VUELVE (al menos hasta que "nos vuelvan a planificar"). Se
estudiar en el siguiente tema.
La funcin __schedule_tail[kernel/sched.c#L467], en el caso uniprocesador, limpia el bit
SCHED_YIELD del proceso que ha abandonado la CPU. [#698]En el caso multiprocesador, si dicho
proceso est en estado TASK_RUNNING se intenta buscar otra CPU en la que se pueda ejecutar.

Finalizando la planificacin
Finalmente, y antes de abandonar el planificador, se llevan a cabo un par de acciones ms.
Se vuelve a adquirir el cerrojo del ncleo que se libero en la lnea #569. [#701]
Si al final de llegar al planificador, el nuevo proceso escogido ya necesita volver a planificarse (que
todo puede pasar ;) ), se vuelve casi al principio del planificador a repetir todo el proceso (para qu
esperar ms?). [#7023]
Por ltimo, se vuelve de la funcin schedule(), pero como se ha cambiado la pila del ncleo por
la del nuevo proceso, la direccin de retorno ser la del punto en el que se invoco a
schedule() desde dicho proceso. [#704]

8.4 Estructuras utilizadas por el planificador

También podría gustarte