domingo, 15 de noviembre de 2015

EL RELOJ

El reloj es un elemento imprescindible en cualquier sistema informático. Es necesario aclarar desde el
principio que se trata de un término que presenta varias acepciones en este entorno:

• El reloj del procesador, que marca el ritmo con el que se ejecutan las instrucciones.
• El reloj del sistema, que mantiene la fecha y la hora en el mismo.
• El reloj temporizador, que hace que el sistema operativo se active periódicamente para realizar las
labores correspondientes.

La primera acepción queda fuera de esta presentación ya que no involucra al sistema operativo,
consistiendo generalmente en una señal generada por un cristal de cuarzo que alimenta directamente el
procesador. Este apartado se centra en los dos últimos sentidos del término ya que en ellos sí que interviene
el sistema operativo.

El hardware del reloj

Para medir el tiempo sólo se requiere un componente que genere una señal periódica que sirva como base
de tiempo. Normalmente se dispone de un circuito temporizador que, a partir de las oscilaciones producidas por un cristal de cuarzo, genera periódicamente interrupciones (a cada una de estas interrupciones del reloj se las suele denominar en inglés tick). Este elemento está conectado generalmente a una línea de interrupción de alta prioridad del procesador debido a la importancia de los eventos que produce.

La mayoría de estos temporizadores permiten programar su frecuencia de interrupción. Típicamente
contienen un registro interno que actúa como un contador que se decrementa por cada oscilación del cristal
generando una interrupción cuando llega a cero. El valor que se carga en este contador determina la
frecuencia de interrupción del temporizador, que se comporta, por tanto, como un divisor de frecuencia.
Además de ser programable la frecuencia de interrupción, estos dispositivos frecuentemente presentan
varios modos de operación seleccionables. Suelen poseer un modo de «un solo disparo» en el que cuando el
contador llega a cero y se genera la interrupción, el temporizador se desactiva hasta que se le reprograme
cargando un nuevo valor en el contador. Otro típico modo de operación es el de «onda cuadrada» en el que
al llegar a cero el contador y generar la interrupción el propio temporizador vuelve a recargar el valor
original en el contador sin ninguna intervención externa.

Hay que resaltar que generalmente un circuito de este tipo incluye varios temporizadores independientes, lo
que permite, en principio, que el sistema operativo lo use para diferentes labores. Sin embargo, en muchos
casos no todos ellos son utilizables para esta misión ya que no están conectados a líneas de interrupción del
procesador.
Un ejemplo típico de este componente es el circuito temporizador 8253 que forma parte de un PC estándar.
Tiene tres temporizadores pero sólo uno de ellos está conectado a una línea de interrupción (en concreto, a
la línea IRQ número O). Los otros están destinados a otros usos. Por ejemplo, uno de ellos está conectado al altavoz del equipo. La frecuencia de entrada del circuito es de 1,193 MHz. Dado que utiliza un contador
interno de 16 bits, el temporizador se puede programar en el rango de frecuencias desde 18,5 Hz (con el
contador igual a 65536) hasta 1,193 MHz (con el contador igual a 1). Cada temporizador puede
programarse de forma independiente presentando diversos modos de operación, entre ellos, el de «un solo
disparo» y el de «onda cuadrada».

Otro elemento hardware presente en prácticamente la totalidad de los equipos actuales es un reloj
alimentado por una batería (denominado en ocasiones reloj CMOS) que mantiene la fecha y la hora cuando
la máquina está apagada.

El software del reloj

Dado que la labor fundamental del hardware del reloj es la generación periódica de interrupciones, el
trabajo principal de la parte del sistema operativo que se encarga del reloj es el manejo de estas
interrupciones. Puesto que, como se analizará a continuación, las operaciones asociadas al tratamiento de
una interrupción de reloj pueden implicar un trabajo considerable, es preciso establecer un compromiso a la
hora de fijar la frecuencia de interrupción del reloj de manera que se consiga una precisión aceptable en la
medición del tiempo, pero manteniendo la sobrecarga debida al tratamiento de las interrupciones en unos
términos razonables. Un valor típico de frecuencia de interrupción, usado en muchos sistemas UNIX, es de
100 Hz (o sea, una interrupción cada 10 ms).
Hay que resaltar que, dado que las interrupciones del reloj son de alta prioridad, mientras se procesan no se
aceptan interrupciones de otros dispositivos menos prioritarios. Se debe, por tanto. minimizar la duración
de la rutina de tratamiento para asegurar que no se pierden interrupciones de menor prioridad debido a la
ocurrencia de una segunda interrupción de un dispositivo antes de que se hubiera tratado la primera. Para
evitar esta posibilidad, muchos sistemas operativos dividen el trabajo asociado con una interrupción de reloj
en dos partes:

• Operaciones más urgentes que se ejecutan en el ámbito de la rutina de interrupción.
• Operaciones menos urgentes que lleva a cabo una rutina que ejecuta con una prioridad más baja
que cualquier dispositivo del sistema. Esta función es activada por la propia rutina de interrupción
de reloj mediante un mecanismo generalmente denominado interrupción software (en el caso de
Linux se denomina «mitad inferior»).

Aunque la labor principal del sistema operativo con respecto al manejo del reloj es el tratamiento de sus
interrupciones, hay que hacer notar que también debe realizar su iniciación y llevar a cabo las llamadas al
sistema relacionadas con el mismo.
Con independencia de cual sea el sistema operativo específico, se pueden identificar las siguientes
operaciones como las funciones principales del software de manejo del reloj:
• Mantenimiento de la fecha y de la hora.
• Gestión de temporizadores.
• Contabilidad y estadísticas.
• Soporte para la planificación de procesos.

Mantenimiento de la fecha y de la hora

En el arranque del equipo, el sistema operativo debe programar el circuito temporizador del sistema
cargándole en su contador interno el valor correspondiente a la frecuencia deseada y estableciendo un modo
de operación de «onda cuadrada», si es que el temporizador dispone del mismo. Asimismo, debe leer el
reloj mantenido por una batería para obtener la fecha y hora actual.
A partir de ese momento, el sistema operativo se encargará de actualizar la hora según se vayan
produciendo las interrupciones.
La principal cuestión referente a este tema es cómo se almacena internamente la información de la fecha y
la hora. En la mayoría de los sistemas la fecha se representa como el número de unidades de tiempo
transcurridas desde una determina fecha en el pasado. Por ejemplo, los sistemas UNIX toman como fecha
base el 1 de enero de 1970. Algunos de ellos almacenan el número de segundos transcurridos desde esta
fecha, mientras que otros guardan el número de microsegundos que han pasado desde entonces. Por lo que
se refiere a Windows, la fecha se almacena Como el número de centenas de nanosegundos (l0- segundos)
transcurridos desde la fecha de referencia del 1 de enero de 1601.
Sea cual sea la información almacenada para mantener la fecha y la hora, es muy importante que se le dedique un espacio de almacenamiento suficiente para que se puedan representar fechas en un futuro a
medio o incluso a largo plazo. De esta forma se asegura que la vida del sistema operativo no quede limitada
por este aspecto. Así, por ejemplo, un sistema UNIX que use una variable de 32 bits para guardar el número de segundos desde la fecha de referencia (1- 1-1970) permitiría representar fechas hasta principios del siglo XXII.

Otro aspecto importante es cómo tratar las peculiaridades existentes en el horario de cada país. Esto no sólo
implica las diferencias que hay dependiendo del huso horario al que pertenezca el país, sino también la
existencia en algunos países de políticas de cambio de horario con el objetivo de ahorrar energía. En el caso
del sistema UNIX, el sistema operativo almacena la hora en el sistema de tiempo estándar UTC (Universal
Ceordinated Time), con independencia de las peculiaridades del país donde reside la máquina. La
conversión al horario local no la realiza el sistema operativo sino las bibliotecas del sistema.
Por último, es interesante resaltar que algunos sistemas operativos, además de un servicio para cambiar la
hora en el sistema de forma inmediata, ofrecen un servicio que permite hacer este ajuste de forma progresiva, para así no perturbar bruscamente el estado del sistema. Observe que un cambio inmediato de la
hora que implique un retraso de la misma puede causar situaciones problemáticas en el sistema (evidentemente, el tiempo real nunca va hacia atrás).

Gestión de temporizadores

En numerosas ocasiones un programa necesita esperar un cierto plazo de tiempo antes de realizar una
determinada acción. El sistema operativo ofrece servicios que permiten a los programas establecer
temporizaciones y se encarga de notificarles cuando se cumple el plazo especificado (en caso de UNIX
mediante una señal). Pero no sólo los programas de usuario necesitan este mecanismo, el propio sistema
operativo también lo requiere. El módulo de comunicaciones del sistema operativo, por ejemplo, requiere
establecer plazos de tiempo para poder detectar si un mensaje se pierde. Otro ejemplo es el manejador del
disquete que, una vez arrancado el motor del mismo, requiere esperar un determinado tiempo para que la
velocidad de rotación se estabilice antes de poder acceder al dispositivo.

Dado que en la mayoría de los equipos existe un único temporizador (o un número muy reducido de ellos),
es necesario que el sistema operativo lo gestione de manera que sobre él puedan crearse los múltiples
temporizadores que puedan requerirse en el sistema en un determinado momento.
El sistema operativo maneja generalmente de manera integrada tanto los temporizadores de los procesos de
usuario como los internos. Para ello mantiene una lista de temporizadores activos. En cada elemento de la
lista se almacena típicamente el número de unidades de tiempo (para facilitar el trabajo, generalmente se
almacena el número de interrupciones de reloj requeridas) que falta para que se cumpla el plazo y la
función que se invocará cuando éste finalice. Así, en el ejemplo del disquete se corresponderá con una
función del manejador de dicho dispositivo. En el caso de una temporización de un programa de usuario, la
función corresponderá con una rutina del sistema operativo encargada de mandar la notificación al proceso
(en UNIX, la señal).

Existen diversas alternativas a la hora de gestionar la lista de temporizadores. Una organización típica
consiste en ordenar la lista de forma creciente según el tiempo que queda por cumplirse el plazo de cada
temporizador. Además, para reducir la gestión asociada a cada interrupción, el plazo de cada temporizador
se guarda de forma relativa a los anteriores en la lista. Así se almacenan las unidades que quedarán
pendientes cuando se hayan cumplido todas las temporizaciones correspondientes a elementos anteriores
de la lista. Con este esquema se complica la inserción, puesto que es necesario buscar la posición
correspondiente en la lista y reajustar el plazo del elemento situado a continuación de la posición de inserción. Sin embargo, se agiliza el tratamiento de la interrupción  ya que sólo hay que modificar el elemento de cabeza, en lugar de tener que actualizar todos los temporizadores.

En último lugar hay que resaltar que generalmente la gestión de temporizadores es una de las operaciones
que no se ejecutan directamente dentro de la rutina de interrupción sino, como se comentó previamente, en
una rutina de menor prioridad. Esto se debe a que esta operación puede conllevar un tiempo considerable
por la posible ejecución de las rutinas asociadas a todos aquellos temporizadores que se han cumplido en la
interrupción de reloj en curso.

Contabilidad y estadísticas

Puesto que la rutina de interrupción se ejecuta periódicamente, desde ella se puede realizar un muestreo de
diversos aspectos del estado del sistema llevando a cabo funciones de contabilidad y estadística. Es
necesario resaltar que, dado que se trata de un muestreo del comportamiento de una determinada variable y
no de un seguimiento exhaustivo de la misma, los resultados no son exactos, aunque si la frecuencia de
interrupción es suficientemente alta, pueden considerarse aceptables.

Dos de las funciones de este tipo presentes en la mayoría de los sistemas operativos son las siguientes:
• Contabilidad del uso del procesador por parte de cada proceso.
• Obtención de perfiles de ejecución.

Por lo que se refiere a la primera función, en cada interrupción se detecta qué proceso está ejecutando y a
éste se le carga el uso del procesador en ese intervalo. Generalmente, el sistema operativo distingue a la
hora de realizar esta contabilidad si el proceso estaba ejecutando en modo usuario o en modo sistema.

Algunos sistemas operativos utilizan también esta información para implementar temporizadores virtuales,
en los que el reloj sólo «corre» cuando está ejecutando el proceso en cuestión, o para poder establecer
límites en el uso del procesador.

Con respecto a los perfiles, se trata de obtener información sobre la ejecución de un programa que permita
determinar cuánto tiempo tarda en ejecutarse cada parte del mismo. Esta información permite que el
programador detecte los posibles cuellos de botella del programa para poder así optimizar su ejecución.
Cuando un proceso tiene activada esta opción, el sistema operativo toma una muestra del valor del contador
de programa del proceso cada vez que una interrupción encuentra que ese proceso estaba ejecutando.

La acumulación de esta información durante toda la ejecución del proceso permite que el sistema operativo
obtenga una especie de histograma de las direcciones de las instrucciones que ejecuta el programa.

Soporte a la planificación de procesos
La mayoría de los algoritmos de planificación de procesos tienen en cuenta de una forma u otra el tiempo y,
por tanto, implican la ejecución de ciertas acciones de planificación dentro de la rutina de interrupción.
En el caso de un algoritmo round-robin, en cada interrupción de reloj se le descuenta el tiempo
correspondiente a la rodaja asignada al proceso. Cuando se produce la interrupción de reloj que consume la
rodaja, se realiza la replanificación.
Otros algoritmos requieren que cada cierto tiempo se recalcule la prioridad de los procesos teniendo en
cuenta el uso del procesador en el último intervalo. Nuevamente, estas acciones estarán
asociadas con la interrupción de reloj.

No hay comentarios:

Publicar un comentario