Download java en tiempo real
Document related concepts
no text concepts found
Transcript
JAVA EN TIEMPO REAL Andrés Jesús Mesones Luque i02melua@uco.es 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