Download java en tiempo real

Document related concepts
no text concepts found
Transcript
JAVA EN TIEMPO REAL
Andrés Jesús Mesones Luque
[email protected]
Ingeniería en Informática
Curso 06/07
Universidad de Córdoba
Sistemas en Tiempo Real
Java en Tiempo Real
Índice de contenido
1. Introducción........................................................................................................................3
2. Vista general de las áreas afectadas.................................................................................3
3 Planificación........................................................................................................................5
4 Gestión de memoria............................................................................................................7
4.1 Áreas de memoria.......................................................................................................7
5 Sincronización.....................................................................................................................8
5.1 Colas de espera...........................................................................................................8
5.2 Preveción de la inversión de prioridades....................................................................8
5.3 Determinismo...............................................................................................................8
6 Manejo de eventos asíncronos...........................................................................................8
7 Transferencia asíncrona del control...................................................................................9
7.1 Principios Metodológicos...........................................................................................10
7.2 Principios de expresibilidad (expressibility)...............................................................10
7.3 Principios semánticos................................................................................................10
7.4 Principios Prácticos...................................................................................................11
8 Terminación asíncrona de hilos de tiempo real................................................................11
9 Acceso a memoria física...................................................................................................12
9.1 Acceso a memoria “en crudo”...................................................................................13
9.2 Áreas de memoria física............................................................................................13
Bibliografía...........................................................................................................................14
2 de 14
Sistemas en Tiempo Real
Java en Tiempo Real
1. Introducción
El Grupo de Expertos en Tiempo Real para Java es el responsable de producir una
especificación que extienda la especificación del lenguaje Java y de la máquina virtual
Java y proveer una API que permita la creación, verificación, análisis, ejecución y manejo
de hilos Java cuyas condiciones de corrección incluyan restricciones temporales (hilos en
tiempo real).
Extraído de la especificación (en adelante nos referiremos a esta especificación como
RTSJ - Real-Time Specification for Java) [1] y contrastado con [2] se presentan a
continuación los cambios más importantes introducidos en el lenguaje Java para permitir
su uso en la programación de sistemas de tiempo real. El trabajo que se presenta se
desarrolla primero dando una vista general de las áreas del lenguaje afectadas para pasar
después a entrar más en detalle en cómo se han diseñado los cambios.
2. Vista general de las áreas afectadas
A continuación se indican las directivas a seguir en cada área. Estas directivas se
definieron en la primera reunión de los ocho ingenieros principales en Mendocino,
California, a finales de Marzo de 1999; y más adelante aclaradas a finales de Septiembre
del mismo año.
Planificación de hilos y envío a ejecución: A la luz de la diversidad de modelos de
planificación y envío a ejecución (en adelante envío) y el reconocimiento de que cada
modelo tiene una amplia aplicabilidad en las diferentes aplicaciones industriales de tiempo
real, se concluye que la dirección a tomar en la especificación de la planificación debería
permitir un mecanismo de planificación subyacente para usarlo con los hilos Java en
tiempo real, pero no se debe especificar la naturaleza de todos los mecanismos de
planificación posibles. La especificación está pensada para permitir implementaciones que
provean algoritmos de planificación no anticipados.
Las implementaciones permitirán la asignación de parámetros apropiados para el
mecanismo de planificación utilizado así como proveer los métodos necesarios para la
creación, administración, admisión y finalización de los hilos Java en tiempo real. También
se espera que, por ahora, la planificación y envío de hilos esté ligada a una
implementación particular. Sin embargo se provee suficiente flexibilidad en el marco de
3 de 14
Sistemas en Tiempo Real
Java en Tiempo Real
trabajo para la planificación de hilos como para permitir futuras versiones de la
especificación y permitir la carga dinámica de módulos para políticas de planificación.
Para acomodar la práctica actual RTSJ necesita un planificador base en todas las
implementaciones. Este planificador base debe resultar familiar a los programadores en
tiempo real. Está basado en prioridad, y debe tener como mucho 28 prioridades únicas.
Gestión de la memoria: La gestión automática de la memoria es una característica de
Java particularmente importante, por lo que RTSJ permite, en la medida de lo posible, que
la gestión de memoria sea implementada por el sistema y no introducirla en las tareas de
programación. En un intento de acomodar los diferentes conjuntos de recolección de
basura se define un sistema de ubicación (allocation) de memoria que debería:
•
Ser independiente de cualquier algoritmo de recolección de basura en particular.
•
Permitir al programa caracterizar de forma precisa el efecto de un algoritmo de
recolección de basura sobre el tiempo de ejecución, las prioridades, y el envío de
los hilos Java en tiempo real
•
Permitir la ubicación de objetos sin interferencia de ningún algoritmo de
recolección de basura
Sincronización y compartición de recursos: La lógica normalmente requiere un
acceso serial a los recursos. Los sistemas en tiempo real añaden cierta complejidad:
controlar la inversión de prioridades. La especificación menos intrusiva para permitir una
sincronización segura en tiempo real es requerir que las implementaciones de la directiva
synchronized de Java incluyan uno o más algoritmos que prevengan la inversión de
prioridad entre hilos Java en tiempo real que comparten un recurso. También se tuvo en
cuenta que algunas veces el uso de la directiva synchronized que implemente el algoritmo
de inversión de prioridades requerido no es suficiente para prevenir la inversión de
prioridades y permitir que los hilos tengan una elegibilidad de ejecución logicamente
mayor que el colector de basura. Se proveen un conjunto de clases sin cola de espera
para usarlas en dichas situaciones.
Manejo de eventos asíncrono: Los sistemas en tiempo real normalmente interactúan
de forma muy cercana con el mundo real. Respecto a la ejecución de lógica, el mundo
real es asíncrono. RTSJ generaliza el mecanismo de Java para manejar eventos
asíncronos. Las clases requeridas representan cosas que puden suceder y lógica que se
4 de 14
Sistemas en Tiempo Real
Java en Tiempo Real
ejecuta cuando estas cosas ocurren. Una característica notable es que la ejecución de
dicha lógica es planificada y enviado a ejecución por un planificador implementado.
Transferencia del control asíncrona: Algunas veces el mundo real cambia de forma
tan drástica (y asíncrona) que el punto actual de ejecución debe ser inmediatamente
cambiado a otro punto. RTSJ incluye un mecanismo que extiende el manejo de
excepciones de Java para permitir aplicaciones que cambien el control de otro hilo Java.
Es importante resaltar que RTSJ restringe esta transferencia de control asíncrona a
situaciones específicamente escritas con la asunción de que la localización de su control
puede cambiar de forma asíncrona.
Finalización asíncrona de hilos: De nuevo, debido a los drásticos y asíncronos
cambios del mundo real, la lógica de la aplicación necesita una forma de transferir de
forma segura su control a su
exterior y terminar de una forma normal. Note que al
contrario del tradicional, inseguro y desaprobado menanismo de Java para parar los hilos,
el mecanismo RTSJ para manejo de eventos asíncronos y transferencia del control es
seguro.
Acceso a memoria física: Aunque no es un aspecto ligado únicamente a los sistemas
en tiempo real, el acceso a memoria física es deseable para la mayoría de las
aplicaciones que pueden hacer un uso productivo de una implementación de RTJS. Se
define una clase que permite a los programadores un acceso a memoria física a nivel de
byte así como una clase que permite la construcción de objetos en memoria física.
A continuación se detalla más profundamente la especificación para el diseño de estos
aspectos.
3 Planificación
Uno de los aspectos concernientes a la programación en tiempo real es asegurar una
ejecución de secuencias de instrucciones máquina que sea correcta y predecible en el
tiempo. Los diferentes esquemas de planificación llaman a estas secuencias de
instrucciones de diferentes formas. Los nombres típicamente usados incluyen los hilos,
tareas, módulos y bloques. RTJS introduce el concepto de objeto planificlable
(schedulable object). Estos son objetos que maneja el el planificador base,
RealtimeThread y sus subclases junto a AsyncEventHandler y sus subclases.
5 de 14
Sistemas en Tiempo Real
Java en Tiempo Real
“Timely execution of schedulable objects” significa que el programador puede
determinar si los hilos completaran siempre su ejecución en base a unos requisitos de
tiempo dados mediante
el análisis del programa, probando el programa en
implementaciones concretas, o haciendo ambas cosas. Ésta es la esencia de la
programación en tiempo real: la adición de requisitos temporales para establecer las
condiciones correctas de computación.
Se utiliza aquí el termino planificación (o algoritmo de planificación) como la producción
de un orden de ejecución para un conjunto de objetos planificables (schedulable objects).
Esta planificación trata de optimizar una métrica en particular (una métrica que mida si se
ajusta correctamente el sistema a los requisitos temporales). Un análisis de viabilidad
determina si una planificación tiene un valor aceptable para dicha métrica.
Muchos sistemas utilizan la prioridad en los hilos para tratar de determinar una
planificación. La prioridad suele ser un entero asociado a un objeto planificable, esta
prioridad indica al sistema el orden en que deben ejecutarse los hilos. Generalizando el
concepto de prioridad aparece el concepto de execution elegibility. Utilizamos el término
envío a ejecución para hablar de la parte del sistema encargada de elegir el hilo con la
mayor execution elegibility del conjunto de hilos que están listos para ejecución. En los
sistemas de tiempo real actuales la asignación de prioridades suele estar bajo el control
de programador en oposición de un control por parte del sistema. El planificador base de
RJST también permite al programador controlar la asignación de prioridades. Sin
embargo, el planificador base también hereda métodos de su superclase que deben
ayudar a determinar la viabilidad.
Para el planifiador base, los métodos deben asumir un procesador suficientemente
rápido para completar cualquier carga propuesta en la planificación. En RTSJ se espera
que el planificador base sea utilizado como clase padre en implementaciones particulares,
y para estas implementaciones, los métodos de viabilidad deben indicar correctamente la
viabilidad real del sistema según la planificación dada.
RTSJ requiere unas clases con el formato de nombre <string>Paremeters (por
ejemplo SchedulingParameters). Una instancia de uno de estas clases 'parámetros'
representa una demanda de recursos para uno o más objetos planificables. Por ejemplo la
subclase PriorityParameters contiene la métrica execution elegibility del planificador base,
por ejemplo prioridad. En algún momento las instancias de estas clases parámetros se
6 de 14
Sistemas en Tiempo Real
Java en Tiempo Real
ligan a un objeto planificable. Los objetos planificables asumen entonces las
características de los valores en el objeto parámetro.
RTSJ está hecho de forma que se pueden instalar otros algoritmos de planificación y
algoritmos de análisis de la viabilidad en una implementación de la especificación. Esto se
hace porque entendemos que los sistemas de tiempo real existentes en la industria han
tenido requisitos muy variados respecto a la planificación. El uso de la plataforma Java
ayuda a producir código fuente portable (Write Once, Run anywhere). RTSJ contribuye a
este objetivo por un lado y no lo hace por otro, ya que también se permiten planificadores
específicos de la plataforma (que no son portables).
4 Gestión de memoria
El colector de basura de memoria siempre ha sido considerado un obstáculo para la
programación en tiempo real, ya que introduce latencias impredecibles. RTSJ proporciona
varias extensiones al modelo de memoria, que soporta una gestión de memoria que no
interfiere con el código en tiempo-real. Este objetivo se consigue permitiendo la ubicación
de objetos fuera del montón (heap) tanto para objetos short-lived y long-lived.
4.1 Áreas de memoria
RTSJ introduce el concepto de área de memoria. Un área de memoria es una porción
de memoria que se debe usar para la ubicación de objetos. Algunas áreas de memoria
existen fuera del montón y restringen lo que el sistema y el colector de basura pueden y
deben hacer con los objetos ahí ubicados.
Algunos objetos en estas áreas de memoria nunca son tratados por el colector, sin
embargo el colector debe ser capaz de escanear estas áreas de memoria en busca de
referencias a objetos que estén en el montón, para conservar la integridad del mismo.
Hay cuatro tipos básicos de áreas de memoria:
1. Scoped memory que proporciona un mecanismo para la gestión de objetos que
tienen un tiempo de vida definido por su alcance.
2. Memoria física, permite la creación de objetos en regiones específicas de
memoria que tienen alguna característica importante (por ejemplo una región que
tiene un acceso más rápido).
7 de 14
Sistemas en Tiempo Real
Java en Tiempo Real
3. Memoria inmortal; representa unárea de memoria que contiene objetos que se
referencian desde objetos planificables sin excepciones ni retraso causado por el
colector de basura.
4. Montón (heap memory). RTSJ no cambia el tiempo de vida de los objetos del
montón. El tiempo de vida es todavía determinado por visibilidad.
5 Sincronización
5.1 Colas de espera
La espera de hilos y manejadores de eventos asíncronos para adquirir un recurso debe
ser liberada en el orden de preferencia de ejecución. Esto se aplica tanto al procesador
como a bloques de código donde se hace sincronía (secciones críticas, ...). Si existen
varios objetos planificables con la misma preferencia de ejecución se irá despertando a
dichos objetos en orden de llegada (FIFO).
5.2 Preveción de la inversión de prioridades
RTSJ
provee
una
implementación
de
la
primitiva
synchronized
con
un
comportamiento por defecto que asegura que no exista una inversión de prioridades
ilimitada.
El protocolo de herencia de prioridades debe implementarse por defecto. La
especificación también proporciona un mecanismo para que el programador pueda pasar
por alto esta política, o sustituirla por la que a él le interese.
5.3 Determinismo
La implementación debe ofrecer un límite superior en cuanto al tiempo de espera
necesario para que se libere un monitor o un cerrojo.
6 Manejo de eventos asíncronos
Para el manejo de eventos asíncronos se tienen dos clases, AsyncEvent y
AsyncEventHandler. Un objeto AsyncEvent representa algo que puede suceder,
como puede ser una señal POSIX, una interrupción hardware o cualquier otro evento.
Cuando ocurre uno de estos eventos, las instancias de AsyncEventHandler asociadas
8 de 14
Sistemas en Tiempo Real
Java en Tiempo Real
a dichos eventos son programadas y se invoca el evento handleAsyncEvent para que
haga lo necesario en atención al evento. AsyncEvent proporciona métodos para
establecer los manejadores asociados al evento.
Una instancia de AsyncEventHandler es similar a un hilo. Es un objeto ejecutable
(Runnable). Lo que distingue un AsyncEventHandler de los demás objetos
ejecutables es que éste tiene asociadas instancias de ReleaseParameters,
SchedulingParameters y MemoryParameters que controlan la ejecución del
manejador cuando se dispara el evento correspondiente. Cuando ocurre un evento, los
manejadores se ejecutan de forma asíncrona de acuerdo a los parámetros establecidos
de tal forma que parece que el manejador tiene asignado su propio hilo. Se espera que el
sistema sea capaz de manejar correctamente un gran número de instancias de
AsyncEvent y AsyncEventHandler. El número de manejadores que se ejecuten se
espera que sea menor.
Una forma especializada de AsyncEvent es la clase Timer, que representa un
evento cuya activación está dirigida por el tiempo. Hay dos tipos de timers:
OneShotTimer y PeriodicTimer. Las instancias de OneShotTimer se disparan una
sola vez, las de PeriodicTimer se disparan inicialmente al tiempo especificado y tras
esta vez, se repiten periódicamente según el intervalo de tiempo especificado.
Los timers son dirigidos por objetos del tipo Clock. Existe un tipo de reloj que
representa un reloj de tiempo real, se llama Clock.getRealtimeClock. La clase
Clock puede extenderse para representar otros relojes.
7 Transferencia asíncrona del control
En muchas ocasiones un programador de tiempo real se encuentra con una situación
en la que el coste computacional de un algoritmo es muy variable, el algoritmo es iterativo
y produce resultados más refinados en cada iteración. Si el sistema, antes de empezar la
ejecución, puede determinar solo un límite de tiempo de cuanto tardará la ejecución,
entonces utilizará la transferencia de control asíncrona para transmitir los resultados tras
el límite de tiempo establecido puede ser un modo de programación adecuado. RTSJ
soporta este y otros estilos de programación que harán uso de transferencia asíncrona del
control.
9 de 14
Sistemas en Tiempo Real
Java en Tiempo Real
La aproximación que RTSJ usa para conseguir la transferencia asíncrona del control se
vasa en varios principios enumerados a continuación.
7.1 Principios Metodológicos
●
Aunque un método permita transferencia asíncrona del control, algunas
secciones de código deben ejecutarse hasta que se completen; en tal caso
transferencia asíncrona del control queda diferido. Estas secciones son métodos de
sincronización, inicializadores estáticos y sentencias sincronizadas.
●
El código que responde a la transferencia asíncrona del control no vuelve al
punto del objeto planificable donde se disparó el transferencia asíncrona del
control; esto es, transferencia asíncrona del control es una transferencia de control
sin condiciones.
7.2 Principios de expresibilidad (expressibility)
●
Un mecanismo que necesita de transferencia asíncrona del control puede ser
disparado explícitamente en un objeto planificable. Este lanzamiento puede ser
directo (desde un hilo a un objeto planificable) o indirecto (a través de un
manejador de eventos asíncrono).
●
Debe ser posible lanzar una transferencia asíncrona del control basándose en
cualquier evento asíncono.
●
Utilizando transferencia asíncrona del control debe poderse abortar hilos de
tiempo real de una forma que no conlleve los riesgos de los métodos stop() y
destroy() de la clase Thread.
7.3 Principios semánticos
●
Si la transferencia asíncrona del control se modela sin manejo de excepciones
debe existir algún mecanismo que asegure que si ocurre una excepción asíncrona,
que esta sea capturada sólo por el manejador especificado, y no por el resto de
manejadores de propósito general que se encuentran en el camino de propagación
de las excepciones.
●
Los transferencias anidadas no deben funcionar correctamente. Considere por
ejemplo dos timers anidados basados en transferencia asíncrona del control, y
10 de 14
Sistemas en Tiempo Real
Java en Tiempo Real
suponga que el timeout del timer exterior es menor que el del timer anidado. Si el
timer exterior finaliza mientras el control se encuentra en el código anidado,
entonces el código anidado será abortado y el control transferido a cláusula
ctransferencia asíncrona del controlh apropiada para el timer exterior. Una
implementación que maneje el timeout exterior en el código fuente o que espere al
timer más largo es incorrecta.
7.4 Principios Prácticos
●
Deberían existir idiomas directos para los casos comunes como manejadores de
timers o terminación de hilos de tiempo real.
●
Si un código con un timeout acaba antes de que expire el timer, éste debe ser
parado de forma automática, y sus recursos devueltos al sistema.
8 Terminación asíncrona de hilos de tiempo real
Aunque esta cuestión no es un aspecto único de tiempo real, muchos sistemas
dirigidos por eventos que interactúan con el mundo real (con humanos, máquinas, ...)
pueden requerir cambios en el comportamiento de su cómputo como resultado de
cambios significantes en el mundo real. Sería conveniente programar hilos que terminan
de forma anormal cuando el mundo cambia de forma que el hilo deja de ser útil. Sin esta
facilidad, un hilo o un conjunto de hilos deben ser programados de forma que su
comportamiento se anticipe a los posibles cambios de estado del sistema externo. Es una
tarea más sencilla codificar hilos que cooperen solo para uno (o unos pocos) de los
posibles estados del sistema externo. Cuando el sistema externo cambia de estado, el
cambio en el comportamiento de la computación debe ser manejado por un 'oráculo' que
se encarga de finalizar el conjunto de hilos útiles en el estado anterior e invoque un nuevo
conjunto de hilos apropiado al nuevo estado del sistema externo. Puesto que los posibles
cambios de estado del sistema externo se codifican solamente en el oráculo y no en cada
hilo, el diseño del sistema resultante es más sencillo.
Versiones anteriores de Java proporcionaban mecanismos para conseguir estos
efectos: en particular los métodos stop() y destroy() de la clase Thread. Sin
embargo, puesto que stop() puede dejar los objetos compartidos en un estado
inconsistente, stop() se ha considerado obsoleto. El uso de destroy() puede conducir
11 de 14
Sistemas en Tiempo Real
Java en Tiempo Real
a un estado erróneo si un hilo es destruido mientras mantiene bloqueado un cerrojo. Uno
de los objetivos de RTSJ era conseguir los requerimientos de terminación asíncrona de
hilos sin introducir peligros similares a los que existen con los métodos stop() o
destroy().
RTSJ consigue una terminación asíncrona de hilos en tiempo real de forma segura
utilizando una combinación de manejadores de eventos asíncronos y de la transferencia
de control asíncrona. Para crear un juego de hilos en tiempo real considera los siguientes
pasos:
●
Hace que todos los métodos del hilo en tiempo real puedan interrumpirse.
●
Crea un oráculo que monitoriza el mundo exteno a través de un número de
manejadores de eventos asíncronos.
●
Hacer que los manejadores de eventos interrumpan cada uno de los hilos
afectados por el cambio.
●
Tras la interrupción deben crear un nuevo conjunto de hilos apropiado al estado
del mundo externo.
9 Acceso a memoria física
RTSJ define clases para programadores que deseen acceder directamente a memoria
física desde código escrito en lenguaje Java. RawMemoryAccess define métodos que
permiten al programador construir un objeto que representa un rango de memoria física.
El acceso a memoria física se consigue a traves de los métodos get[type]() y
set[type](), donde type indica el tamaño de palabra ( byte, short, int, long, float y
double).
Las
clases
VTPhysicalMemory,
LTPhysicalMemory
e
InmortalPhysicalMemory permiten construir un objeto que representa un rango de
direcciones de memoria física. PhysicalMemoryManager es una clase disponible para
su uso por varios objetos que acceden a memoria física (VTPhysicalMemory,
LTPhysicalMemory,
InmortalPhysicalMemory,
RawMemoryAccess
y
RawMemoryFloatAccess ) para crear objetos del tipo correcto que se limitan a áreas de
memoria física con las características apropiadas.
12 de 14
Sistemas en Tiempo Real
Java en Tiempo Real
9.1 Acceso a memoria “en crudo”
La clase RawMemoryAccess modela un rango de memoria física como una secuencia
fija de bytes. Un complemento de los métodos de acceso permite acceder a los
contenidos del área física utilizando diferentes tamaños de palabra, interpretando así los
datos como byte, short, int, o long o como arrays de estos tipos.
La clase RawMemoryAccess permite implementar en un programa en tiempo real
drivers de dispositivos, entrada/salida a bajo nivel,...
Un área de memoria de este tipo no puede contener referencias a objetos Java.
9.2 Áreas de memoria física
En muchos casos la necesidad de que la ejecución sea predecible nos lleva a necesitar
diferentes tipos de acceso a memoria por motivos de rendimiento o por otros motivos. Las
clases
VTPhysicalMemory,
LTPhysicalMemory
y
InmortalPhysicalMemory
permiten esta flexibilidad. El programador construirá un objeto de memoria física en la
dirección ocupada por la RAM más rápida.
13 de 14
Sistemas en Tiempo Real
Java en Tiempo Real
Bibliografía
[1] http://www.rtsj.org/specjavadoc/book_index.html
Real-Time for Java Expert Group (RTJEG). 29 de Noviembre de 2006.
[2] Wellings, Andy. Concurrent and real-time programming in Java. Chichester: John
Wiley & Sons, 2004. ISBN 047084437X.
14 de 14