Proibida cópia ou divulgação sem
permissão escrita do CMG Brasil.
Linux Real-Time
e
Java Real-Time
um mundo sem delays
Flavio C Buccianti
flaviocb@gmail.com
Agenda
Introdução ao real-time e Enterprise real-time
Extensões ao Real-Time Linux
o patch CONFIG_PREEMPT_RT
Real-time Java
Conclusão
Definições
Real-Time Operating Systems (RTOS) são sistemas que garantem o
intervalo de tempo entre a ocorrência de um evento e do início da
execução do código que está esperando esse evento ocorrer.
Esse tempo é geralmente chamado de “latência”
Diferentes tipos de latência
– Latência do Scheduler
– Latencia da Interrupção
Hard x Soft Real-time
Sistemas com Hard Real-Time tem a maxima latência previsivel (via
“longest code path analysis”)
Soft Real-Time: latência de “melhor esforço”
Real-Time Tradicional
Geralmente usado em pequenos sistemas embarcados
Monoprocessado (Sistemas SMP são muito complexos para o max.
code path analysis)
Velocidades de CPU restritas
Usados para captura de dados e análise “real-time” imediata
todos querem “hard real-time”
“Soft Real Time” é geralmente mencionado como “not real-time at all”
TCP/IP é muito complexo para o max. code path analysis
RTOS's geralmente não tem suporte a TCP/IP
Os tempos mudaram ........
Os computadores estão mais rápidos
O Cray-1 (1976) tinha 160MFLOPs e 8MB de memoria
– um sistema embarcado modesto para os padrões de hoje.
– Não seria capaz de rodar nem o Mozilla ou OpenOffice !
Hoje é possível rodar muito mais instruções em somente 10us.
As expectativas são maiores do que antes. TCP/IP é obrigatório.
Até maquinas embarcadas pequenas precisam de SMP devido a
processadores multi-core.
Mudanças de requerimentos nos softwares empresariais: alta capacidade
processamento não é mais suficiente, são necessárias garantias de latência
também !
Arquiteturas complexas multi-tier fazem a latência aumentar
O resultado ?
Um novo tipo de real-time
Vamos chama-lo de “Enterprise real-time” para diferencia-lo das
aplicações real-time tradicionais
Caracteristicas
Suporta grandes sistemas SMP
TCP/IP é requerido
Capacidade de suportar produtos de middleware existentes.
– Databases, Web servers
– Certamente sem as caracteristicas de real-time..
Suportar liguagens de alto nível
Tenha o “hard real-time” à prova de não-determinismo
Escala de tempos de latência
10 s
1 s
100 μs
10 ms
100
ms
1 ms
10 μs
STRATEGY
TACTICS
COORDINATION
ACTUATION
SENSING
MODULATION
SIGNALING CUSTOM HARDWARE
PERCEPTIONREACTION
COGNITION
Extensões do Real-Time Linux
Primeiros patches e scripts atualizaram RHEL4U2 32-bit x86
2.6.16 Linux kernel
2.6.16-rt22 CONFIG_PREEMPT_RT patch (Ingo Molnar)
interfaces adicionadas ao glibc para suportar priority inheritance
melhorias nas bibliotecas do PAM para permitir que usuários
não-root tenham acesso aos recursos do real-time.
acesso direto à memória física requerido para estar em
conformidade com o RTSJ
bug fixes e patches de estabilização
Patch CONFIG_PREEMPT_RT
High-resolution timers
Kernel e userspace priority inheritance
Hardware e software interrupt handlers rodam como kernel threads
(permitindo o ajuste da prioridade real-time)
Interrupt e Scheduler com máxima latência de 20us ( medida)
Priority Inheritance
Em ambiente de computação Real-Time, priority inheritance é a
maneira usada para eliminar possíveis problemas de inversão de
prioridade. Usando esse modelo, o algoritimo de scheduling de
processos, vai aumentar a prioridade de um processo, para a
máxima prioridade sobre qualquer processo que esteja agurdando
um recurso que o processo tenha feito o lock de um recurso.
A idéia básica do protocolo de priority inheritance é que quando
um processo bloqueia um ou mais processos com prioridade
superior, o protocolo ignora a prioridade original do processo e
executa sua a parte crítica do código na maior prioridade
disponível acima ou igual ao dos processos que ele está
bloqueando. Depois de executar a sessão crítica do processo e
fazer o unlock do recurso, o processo retorna ao seu nível original
de prioridade.
Priority Inheritance
Considere três processos:
Processo Prioridade
A Alta
B Media
C Baixa
onde: “A” está bloqueado aguardando algum recurso compartilhado que
“C” fez um lock e está utilizando.
O protocolo de priority inheritance fará com que “C” execute sua sessão
critica na prioridade de “A” (alta).
Como resultado “B” vai ser impedido de ganhar o controle sobre “C” e
vai ser bloqueado, ou seja, o processo “B” que tem mais alta prioridade,
vai ter que esperar que a sessão crítica do processo “C” seja executada
porque “C” agora tem a mesma priodade que “A” (alta).
Quando “C” sai de sua sessão cítica, ele volta a ter sua prioridade
original (baixa) e libera o processamento para “A” que tem prioridade
mais alta, e pode agora também alocar o recurso que estava bloqueado
por “C”.
sem Priority Inheritance
lock
lockA
Alta
B
Media
C
Baixa
com Priority Inheritance
lock
lockA
Alta
B
Media
C
Baixa
unlock
X lock unlock
Prioridades de real time via programa
#include <stdio.h>
#include <sched.h>
int main()
{
struct sched_param sp;
sp.sched_priority = 90;
if (sched_setscheduler(0, SCHED_FIFO, &sp) != 0) {
perror("sched_setscheduler");
return -1;
}
printf("hello real-time!n");
return 0;
}
Criando pthreads real-time
#include <pthread.h>
#include <stdio.h>
void * func(void *arg)
{
// coloque seu código aqui...
printf("hello real-time!n");
return NULL;
}
int main()
{
pthread_t pthread;
pthread_attr_t attr;
struct sched_param param;
int ret;
param.sched_priority = 90;
pthread_attr_init(&attr);
pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);
pthread_attr_setschedparam(&attr, &param);
pthread_attr_setschedpolicy(&attr, SCHED_FIFO);
if ((ret = pthread_create(&pthread, &attr, func, NULL))) {
printf("pthread_create failed: %d (%s)n", ret, strerror(ret));
pthread_attr_destroy(&attr);
return -1;
}
pthread_attr_destroy(&attr);
return 0;
}
Setando prioridade na mão: usando chrt
Uma aplicação normal pode rodar como Real-time:
$ chrt -f -p 90 <PID>
Referências:
•http://rt.wiki.kernel.org/index.php/Main_Page
Software Suportado
Como o ambiente de userspace é RHEL ou SLES com pequenas adições
às bibliotecas de C.
Qualquer produto de software que tenha sido testado/homologado para o
RHEL/SLES (nas mesmas versões disponíveis do RT) e que não dependa
de módulos binários do kernel deve rodar sem problemas.
Alguns produtos em produção nos usuários do Real-Time Linux:
Clearcase
Tivoli Storage Manager (TSM)
Tivoli Enterprise Console (TEC) Agent
Etc….
Real-Time Java
http://www-03.ibm.com/press/us/en/pressrelease/21033.wss
USS ZUMWALT, destroyer DDG 1000 da Marinha Americana
• Lançado ao mar em outubro de 2013
• Utiliza Linux RT e Java RT para diversos sistemas internos:
Comando e controle
Navegação
Ajuste de Mira
Controle de armas
Sistemas de Radar
Menor tripulação a bordo
Menor complexidade entre sistemas
RTSJ Real-Time Specification for Java
Primeira extensão da linguagem Java
A arquitetura não define um RT garbage collector
Define 4 áreas de memória:
1. Scoped memory
2. Physical memory
3. Immortal memory
4. Heap memory
RTSJ Real Time Specification for Java
Define NonHeapRealTime threads
NHRT threads podem usar somente scoped e immortal memory
NHRT threads não podem referenciar “Heap” memory, porque a
parada total em caso de mover objetos Java não é aceitável pelas
threads real-time.
– Qualquer tentativa de referenciar a memória normal a partir the
uma thread NHRT causará um uncatchable exception
– Significa que NHRT não pode usar a maioria das bibliotecas
Java a não ser que elas sejam auditadas com cuidado para que
não leiam, escrevam ou aloquem objetos no heap. A maioria da
bibliotecas Java não são compatíveis com NHRT.
char size = 'L' ;
char [ ] sizes = { 'S' , 'M' , 'L' } ;
0
1
2
0x21B08
'S'
'M'
'L'
'L'
sizes [ ]
size
HeapStack
Variáveis primitivas e matrizes
char [ ]
Shirt myShirt = new Shirt ( “Polo”, 'M' ) ;
Shirt [ ] shirts = { new Shirt (“Polo”, 'S') ,
new Shirt (“Oxford”, 'M' ) ,
new Shirt (“Polo”, 'L' )} ;
0
1
2
0x23162shirts [ ]
myShirt
Heap
Stack
Variáveis Reference e matrizes
0x0088
0x0432
0x0776
0x73128
Polo
M
Polo
Polo
Oxford
S
M
L
Java Real Time
Dois fabricantes produzem o Java Real Time de acordo com o RTSJ
e que podem ser executados em ambiente Linux RT:
• IBM (Websphere Real Time)
• Oracle (Sun Java Real-Time System)
Features da JVM real-time
RTSJ: Real-Time Specification for Java
Metronome: um garbage collector real-time
AOT: Ahead of Time compilation
Metronome -garbage collector RT
Um garbage collector desenhado por David F. Bacon IBM TJW Research
Center para workloads de real-time.
Tuning knobs:
Max. time slice “roubado” pelo the GC (ex.: 100us)
Max. % of CPU time usado pelo GC (ex.: 30% sobre 1ms)
O que fazer se a aplicação gera mais garbage do que o GC pode
manusear:
– Imprimir uma warning message e fazer um “stop the world” GC
– Abortar o programa uma vez que as garantias de real-time não
conseguem ser sustentadas.
Max. heap memory usada pela JVM
– Aumentado-a pode ajudar se a aplicação tem um perfil de gerar
garbage collection em formato “burst”
Nenhuma outra JVM tem essas caracteristicas !
Metronome – um garbage
collector real-time
Garbage Collector tradicionall
•Tempos de utilização imprevisível
•Latência imprevisivel
Metronome – um garbage
collector real-time
Garbage collector com intervalos de 1 ms
Iniciando um programa RT com controle de GC
java -Xrealtime -Xgc:targetUtilization=70 nomeprograma
Metronome – um garbage
collector real-time
Metronome GC pré-configurado para 30% de GC
e 70% do tempo para aplicação
POSIX SCHED_OTHER
40 níveis de prioridade
a JVM RT usa o default Linux priority para threads regulares
POSIX SCHED_FIFO
não tem time slice (diferente da SCHED_RR)
executa até ser bloqueada (I/O, etc...)
executa até liberar o controle voluntáriamente
é feito um preempt por uma thread the mais alta prioridade
99 prioridades
RTSJ requer 28 níveis numerados de 11 a 38
distribuidas entre as prioridades 11 e 89
a aplicação assinala um dos 28 níveis
não tem ajuste dinâmico de prioridade
Scheduling
Exemplo de uma thread Realtime
import javax.realtime.RealtimeThread;
import javax.realtime.PriorityParameters;
import javax.realtime.PriorityScheduler;
public class MyThread extends RealtimeThread {
public MyThread() {
this.setName("MyThread");
this.setSchedulingParameters(
new PriorityParameters(
PriorityScheduler.getMinPriority(this)+1));
}
public void run() {
while (true) {
// do work
}
}
}
Exemplo: thread NoHeapRealtime
import javax.realtime.NoHeapRealtimeThread;
import javax.realtime.PriorityParameters;
import javax.realtime.PriorityScheduler;
import javax.realtime.MemoryArea;
public class MyThread extends NoHeapRealtimeThread {
public MyThread(MemoryArea memArea) {
super(null, memArea);
this.setName("MyThread");
this.setSchedulingParameters(
new PriorityParameters(
PriorityScheduler.getMinPriority(this)+1));
}
public void run() {
// do work
}
}
• Heap memory – Heap tradicional porém gerenciada pelo Metronome
Garbage Collector.
• Scoped memory – as aplicações podem usar e requisitar, porém
somente pode ser usada por real-time threads. Tem um contador de
utilização que quando chega a zero é liberada.
• Immortal memory – usada para carga de classes e inicialização
estática mesmo que a aplicação não faça uso especifico dela.
Representa uma área de memória contendo objetos que podem
ser referenciados por qualquer schedulable object incluindo no-
heap real-time threads e no-heap asynchronous event handlers.,
sem excessões ou delays de garbage collection.
• Physical memory – premite que objetos sejam criados em regiões
específicas da memória real que tenham características únicas e
importantes tal como memória que tenha um acesso mais rápido.
Em geral é pouco usado e não afeta o usuario normal de JVM.
O Java RT implementa 4 tipos de memória:
Immortal memory
A Immortal Memory é um recurso de memoria compartilhado entre
todos os objetos e threads “esqueduláveis” numa aplicação.
Os objetos alocados na Immortal memory estão sempre disponíveis
para as non-heap threads e para os assichronous event handlers,
esses objetos não estão sujeitos aos delays causados pelo processo
de garabage collection.
Esses objetos são liberados pelo sistema quando o programa
termina.
Parâmetro para definir a Immortal Memory:
-Xgc:immortalMemorySize=20m sets 20 MB
Exemplo de uso de ImmortalMemory
import javax.realtime.MemoryArea;
public class MyObject {
Object obj;
public MyObject(MemoryArea memArea) {
memArea.enter(new Runnable() {
public void run() {
// do something
}
});
}
}
import javax.realtime.RealtimeThread;
import javax.realtime.PriorityParameters;
import javax.realtime.PriorityScheduler;
import javax.realtime.HeapMemory;
import javax.realtime.ImmortalMemory;
public class MyThread extends RealtimeThread {
public MyThread() {
this.setName("MyThread");
this.setSchedulingParameters(
new PriorityParameters(
PriorityScheduler.getMinPriority(this)+1));
}
public void run() {
final MyObject myObject =
new MyObject(HeapMemory.instance());,
ImmortalMemory.instance().enter(new Runnable() {
public void run() {
// do work in immortal heap
}
});
}
}
Scoped memory
• O padrão RTSJ introduziu o conceito de scoped memory.
• Ele pode ser usado por objetos que tenham uma duração bem definida.
• Um scope pode ser definido explicitamente ou ele pode ser anexado à um
schedulable object (uma thread real-time ou à um asynchronous event handler)
que efetivamente cria o scope antes que ele execute o método run() do objeto.
• Cada scope tem um contador de referência e quando ele chega a zero, os
objetos que residem nesse scope podem ser fechados (finalizados) e a memória
associada a esse scope é liberada.
• O re-uso do scope fica bloqueado até que finalização esteja completa.
• Parâmtero para definir scoped memory:
• -Xgc:scopedMemoryMaximumSize (default 8 MB)
Exemplo de uso de ScopedMemory
import javax.realtime.RealtimeThread;
import javax.realtime.PriorityParameters;
import javax.realtime.PriorityScheduler;
import javax.realtime.LTMemory;
import javax.realtime.ScopedMemory;
import javax.realtime.SizeEstimator;
public class MyThread extends RealtimeThread {
static final int load = 1000000;
public MyThread() {
this.setName("MyThread");
this.setSchedulingParameters(
new PriorityParameters(
PriorityScheduler.getMinPriority(this)+1));
this.setDaemon(true);
}
public void run() {
SizeEstimator size = new SizeEstimator();
/**
* Calulate the memory footprint of all objects
*/
size.reserve(long[][].class, load);
size.reserve(long[].class, load * 50);
ScopedMemory memArea = new LTMemory(size);
while (true) {
/* A scoped memory area is being used. Normally the garbage collector would have to deal with the
* unused classes, but with scoped memory we are throwing away all of the objects in the scope when
* we exit the enter() method. This will put much less load on the garbage collector. */
memArea.enter(new Runnable() {
public void run() {
int count = 0;
long[][] array = new long[load][];
for (int n = 0; n < array.length; n++) {
array[count] = new long[50];
}
});
}
}}
AOT – compilação Ahead of Time
Reduz a pausa causada pelo compilador JIT
Dificil pois o Java tem features da linguagem que requerem o compilador
JIT por questões de performance.
sx.: subclasses definindo “new types” podem ser carregadas
dinamicamente no tempo de execução.
A performance obtida pelo uso do AOT é uma alternativa entre o codigo
interpretado e código totalmente otimizado gerado pelo JIT.
Ahead-of-time (AOT)
Compila os programas (classes) antes de ser executado
AOT evita o problema do JIT não compilar o codigo antes que ele seja
requerido para execução.
Just-InTime (JIT)
JIT NÃO causa delays indesejados em código real time.
JIT é executado como uma thread de alta prioridade (SCHED_OTHER)
roda acima das threads normais do Java
roda abaixo das threads real-time
O trabalho de alta-prioridade não é interrompido pelo trabalho do JIT
O trabalho real-time é executado em tempo porém o trabalho real-time
pode acabar tendo que interpretar bytecodes porque o JIT não
conseguiu compilar em tempo os métodos que estavam na fila.
AOT e JIT
Pode-se controlar quando e como o compilador JIT opera,
usando a classe java.lang.Compiler fornecida com o SDK
standard.
A JVM suporta os métodos:
Compile.compileClass()
Compiler.enable()
Compiler.disable()
Sem Metronome e AOT
10 s
1 s
100 μs
10 ms
100 ms
1 ms
10 μs
RealTimeThread com Heap
NoHeapRealTimeThread
com Scopes
Com Metronome e AOT
10 s
1 s
100 μs
10 ms
100 ms
1 ms
10 μs
RealTimeThread com Heap
NoHeapRealTimeThread
com Scopes
Scoped memory
Parâmetro:
-Xgc:scopedMemoryMaximumSize (default 8 MB)
Immortal memory
Parâmetro:
-Xgc:immortalMemorySize=20m (seta 20 MB)
Porque Real-time Java ?
Para fornecedores dos orgãos de defesa e militares , o Java é o novo ADA
É difícil de encontrar programadores ADA...
Sistemas de defesa
– precisam de real-time
– estão cada vez mais integrados outros sistemas e mais complexos.
Setor Financeiro
Aplicações automatizadas de compra/venda tem necessidade de real-time.
Web sites com tempo de resposta garantido
Numa arquitetura muti-tier onde orequerimento de tempo de resposta de
milisegundos para satisfazer o requisito de um page-load abaixo de 1 segundo.
Conclusão
Enterprise Real-Time: uma nova maneira de “pensar”real-time
Mais poderoso e com mais features do que o tradicional “hard
real-time”
Melhor determinismo do que o esperado pelo soft real-time
Java Real Time e Real-Time Linux Extensions
Implementação do conceito de enterprise real-time
Disponível para os “lead adopters”
Metronome GC e AOT tornam o uso do de programas real-time
em Java mais fáceis e “mais saborosos”.
Algumas referências:
http://www.ibm.com/developerworks/java/jdk/linux/download.html
http://pic.dhe.ibm.com/infocenter/realtime/v3r0m0/index.jsp
http://docs.oracle.com/javase/realtime/doc_2.2/release/JavaRTSInstallation.html
http://www.research.ibm.com/journal/sj47-2.html
http://www.oracle.com/technetwork/articles/javase/index-138577.html
https://blogs.oracle.com/delsart/entry/real_time_java_programming_rt
http://docs.oracle.com/javase/realtime/doc_2.2u1/release/JavaRTSGarbageCollection.html
http://www.ibm.com/developerworks/java/library/j-devrtj1/index.html?ca=dat-
Demonstração:
Harmonicon:
http://www.youtube.com/watch?v=jid4WaILPBk
- Sintetizador MIDI escrito em Java RT
- Música em real-time mesmo com a máquina sobrecarregada
http://www.youtube.com/watch?v=AKfmBMTx0gM
- Explicação geral sobre features e funcionamento
Proibida cópia ou divulgação sem
permissão escrita do CMG Brasil.
Flavio C Buccianti
flaviocb@gmail.com
OBRIGADO !

Linux Real-Time e Java Real Time, um mundo sem delays! por Flávio Buccianti

  • 1.
    Proibida cópia oudivulgação sem permissão escrita do CMG Brasil. Linux Real-Time e Java Real-Time um mundo sem delays Flavio C Buccianti flaviocb@gmail.com
  • 2.
    Agenda Introdução ao real-timee Enterprise real-time Extensões ao Real-Time Linux o patch CONFIG_PREEMPT_RT Real-time Java Conclusão
  • 3.
    Definições Real-Time Operating Systems(RTOS) são sistemas que garantem o intervalo de tempo entre a ocorrência de um evento e do início da execução do código que está esperando esse evento ocorrer. Esse tempo é geralmente chamado de “latência” Diferentes tipos de latência – Latência do Scheduler – Latencia da Interrupção Hard x Soft Real-time Sistemas com Hard Real-Time tem a maxima latência previsivel (via “longest code path analysis”) Soft Real-Time: latência de “melhor esforço”
  • 4.
    Real-Time Tradicional Geralmente usadoem pequenos sistemas embarcados Monoprocessado (Sistemas SMP são muito complexos para o max. code path analysis) Velocidades de CPU restritas Usados para captura de dados e análise “real-time” imediata todos querem “hard real-time” “Soft Real Time” é geralmente mencionado como “not real-time at all” TCP/IP é muito complexo para o max. code path analysis RTOS's geralmente não tem suporte a TCP/IP
  • 5.
    Os tempos mudaram........ Os computadores estão mais rápidos O Cray-1 (1976) tinha 160MFLOPs e 8MB de memoria – um sistema embarcado modesto para os padrões de hoje. – Não seria capaz de rodar nem o Mozilla ou OpenOffice ! Hoje é possível rodar muito mais instruções em somente 10us. As expectativas são maiores do que antes. TCP/IP é obrigatório. Até maquinas embarcadas pequenas precisam de SMP devido a processadores multi-core. Mudanças de requerimentos nos softwares empresariais: alta capacidade processamento não é mais suficiente, são necessárias garantias de latência também ! Arquiteturas complexas multi-tier fazem a latência aumentar
  • 6.
    O resultado ? Umnovo tipo de real-time Vamos chama-lo de “Enterprise real-time” para diferencia-lo das aplicações real-time tradicionais Caracteristicas Suporta grandes sistemas SMP TCP/IP é requerido Capacidade de suportar produtos de middleware existentes. – Databases, Web servers – Certamente sem as caracteristicas de real-time.. Suportar liguagens de alto nível Tenha o “hard real-time” à prova de não-determinismo
  • 7.
    Escala de temposde latência 10 s 1 s 100 μs 10 ms 100 ms 1 ms 10 μs STRATEGY TACTICS COORDINATION ACTUATION SENSING MODULATION SIGNALING CUSTOM HARDWARE PERCEPTIONREACTION COGNITION
  • 8.
    Extensões do Real-TimeLinux Primeiros patches e scripts atualizaram RHEL4U2 32-bit x86 2.6.16 Linux kernel 2.6.16-rt22 CONFIG_PREEMPT_RT patch (Ingo Molnar) interfaces adicionadas ao glibc para suportar priority inheritance melhorias nas bibliotecas do PAM para permitir que usuários não-root tenham acesso aos recursos do real-time. acesso direto à memória física requerido para estar em conformidade com o RTSJ bug fixes e patches de estabilização
  • 9.
    Patch CONFIG_PREEMPT_RT High-resolution timers Kernele userspace priority inheritance Hardware e software interrupt handlers rodam como kernel threads (permitindo o ajuste da prioridade real-time) Interrupt e Scheduler com máxima latência de 20us ( medida)
  • 10.
    Priority Inheritance Em ambientede computação Real-Time, priority inheritance é a maneira usada para eliminar possíveis problemas de inversão de prioridade. Usando esse modelo, o algoritimo de scheduling de processos, vai aumentar a prioridade de um processo, para a máxima prioridade sobre qualquer processo que esteja agurdando um recurso que o processo tenha feito o lock de um recurso. A idéia básica do protocolo de priority inheritance é que quando um processo bloqueia um ou mais processos com prioridade superior, o protocolo ignora a prioridade original do processo e executa sua a parte crítica do código na maior prioridade disponível acima ou igual ao dos processos que ele está bloqueando. Depois de executar a sessão crítica do processo e fazer o unlock do recurso, o processo retorna ao seu nível original de prioridade.
  • 11.
    Priority Inheritance Considere trêsprocessos: Processo Prioridade A Alta B Media C Baixa onde: “A” está bloqueado aguardando algum recurso compartilhado que “C” fez um lock e está utilizando. O protocolo de priority inheritance fará com que “C” execute sua sessão critica na prioridade de “A” (alta). Como resultado “B” vai ser impedido de ganhar o controle sobre “C” e vai ser bloqueado, ou seja, o processo “B” que tem mais alta prioridade, vai ter que esperar que a sessão crítica do processo “C” seja executada porque “C” agora tem a mesma priodade que “A” (alta). Quando “C” sai de sua sessão cítica, ele volta a ter sua prioridade original (baixa) e libera o processamento para “A” que tem prioridade mais alta, e pode agora também alocar o recurso que estava bloqueado por “C”.
  • 12.
  • 13.
  • 14.
    Prioridades de realtime via programa #include <stdio.h> #include <sched.h> int main() { struct sched_param sp; sp.sched_priority = 90; if (sched_setscheduler(0, SCHED_FIFO, &sp) != 0) { perror("sched_setscheduler"); return -1; } printf("hello real-time!n"); return 0; }
  • 15.
    Criando pthreads real-time #include<pthread.h> #include <stdio.h> void * func(void *arg) { // coloque seu código aqui... printf("hello real-time!n"); return NULL; } int main() { pthread_t pthread; pthread_attr_t attr; struct sched_param param; int ret; param.sched_priority = 90; pthread_attr_init(&attr); pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED); pthread_attr_setschedparam(&attr, &param); pthread_attr_setschedpolicy(&attr, SCHED_FIFO); if ((ret = pthread_create(&pthread, &attr, func, NULL))) { printf("pthread_create failed: %d (%s)n", ret, strerror(ret)); pthread_attr_destroy(&attr); return -1; } pthread_attr_destroy(&attr); return 0; }
  • 16.
    Setando prioridade namão: usando chrt Uma aplicação normal pode rodar como Real-time: $ chrt -f -p 90 <PID>
  • 17.
  • 18.
    Software Suportado Como oambiente de userspace é RHEL ou SLES com pequenas adições às bibliotecas de C. Qualquer produto de software que tenha sido testado/homologado para o RHEL/SLES (nas mesmas versões disponíveis do RT) e que não dependa de módulos binários do kernel deve rodar sem problemas. Alguns produtos em produção nos usuários do Real-Time Linux: Clearcase Tivoli Storage Manager (TSM) Tivoli Enterprise Console (TEC) Agent Etc….
  • 19.
  • 20.
    http://www-03.ibm.com/press/us/en/pressrelease/21033.wss USS ZUMWALT, destroyerDDG 1000 da Marinha Americana • Lançado ao mar em outubro de 2013 • Utiliza Linux RT e Java RT para diversos sistemas internos: Comando e controle Navegação Ajuste de Mira Controle de armas Sistemas de Radar Menor tripulação a bordo Menor complexidade entre sistemas
  • 21.
    RTSJ Real-Time Specificationfor Java Primeira extensão da linguagem Java A arquitetura não define um RT garbage collector Define 4 áreas de memória: 1. Scoped memory 2. Physical memory 3. Immortal memory 4. Heap memory
  • 22.
    RTSJ Real TimeSpecification for Java Define NonHeapRealTime threads NHRT threads podem usar somente scoped e immortal memory NHRT threads não podem referenciar “Heap” memory, porque a parada total em caso de mover objetos Java não é aceitável pelas threads real-time. – Qualquer tentativa de referenciar a memória normal a partir the uma thread NHRT causará um uncatchable exception – Significa que NHRT não pode usar a maioria das bibliotecas Java a não ser que elas sejam auditadas com cuidado para que não leiam, escrevam ou aloquem objetos no heap. A maioria da bibliotecas Java não são compatíveis com NHRT.
  • 23.
    char size ='L' ; char [ ] sizes = { 'S' , 'M' , 'L' } ; 0 1 2 0x21B08 'S' 'M' 'L' 'L' sizes [ ] size HeapStack Variáveis primitivas e matrizes char [ ]
  • 24.
    Shirt myShirt =new Shirt ( “Polo”, 'M' ) ; Shirt [ ] shirts = { new Shirt (“Polo”, 'S') , new Shirt (“Oxford”, 'M' ) , new Shirt (“Polo”, 'L' )} ; 0 1 2 0x23162shirts [ ] myShirt Heap Stack Variáveis Reference e matrizes 0x0088 0x0432 0x0776 0x73128 Polo M Polo Polo Oxford S M L
  • 25.
    Java Real Time Doisfabricantes produzem o Java Real Time de acordo com o RTSJ e que podem ser executados em ambiente Linux RT: • IBM (Websphere Real Time) • Oracle (Sun Java Real-Time System)
  • 27.
    Features da JVMreal-time RTSJ: Real-Time Specification for Java Metronome: um garbage collector real-time AOT: Ahead of Time compilation
  • 28.
    Metronome -garbage collectorRT Um garbage collector desenhado por David F. Bacon IBM TJW Research Center para workloads de real-time. Tuning knobs: Max. time slice “roubado” pelo the GC (ex.: 100us) Max. % of CPU time usado pelo GC (ex.: 30% sobre 1ms) O que fazer se a aplicação gera mais garbage do que o GC pode manusear: – Imprimir uma warning message e fazer um “stop the world” GC – Abortar o programa uma vez que as garantias de real-time não conseguem ser sustentadas. Max. heap memory usada pela JVM – Aumentado-a pode ajudar se a aplicação tem um perfil de gerar garbage collection em formato “burst” Nenhuma outra JVM tem essas caracteristicas !
  • 29.
    Metronome – umgarbage collector real-time Garbage Collector tradicionall •Tempos de utilização imprevisível •Latência imprevisivel
  • 30.
    Metronome – umgarbage collector real-time Garbage collector com intervalos de 1 ms
  • 31.
    Iniciando um programaRT com controle de GC java -Xrealtime -Xgc:targetUtilization=70 nomeprograma
  • 32.
    Metronome – umgarbage collector real-time Metronome GC pré-configurado para 30% de GC e 70% do tempo para aplicação
  • 34.
    POSIX SCHED_OTHER 40 níveisde prioridade a JVM RT usa o default Linux priority para threads regulares POSIX SCHED_FIFO não tem time slice (diferente da SCHED_RR) executa até ser bloqueada (I/O, etc...) executa até liberar o controle voluntáriamente é feito um preempt por uma thread the mais alta prioridade 99 prioridades RTSJ requer 28 níveis numerados de 11 a 38 distribuidas entre as prioridades 11 e 89 a aplicação assinala um dos 28 níveis não tem ajuste dinâmico de prioridade Scheduling
  • 36.
    Exemplo de umathread Realtime import javax.realtime.RealtimeThread; import javax.realtime.PriorityParameters; import javax.realtime.PriorityScheduler; public class MyThread extends RealtimeThread { public MyThread() { this.setName("MyThread"); this.setSchedulingParameters( new PriorityParameters( PriorityScheduler.getMinPriority(this)+1)); } public void run() { while (true) { // do work } } }
  • 37.
    Exemplo: thread NoHeapRealtime importjavax.realtime.NoHeapRealtimeThread; import javax.realtime.PriorityParameters; import javax.realtime.PriorityScheduler; import javax.realtime.MemoryArea; public class MyThread extends NoHeapRealtimeThread { public MyThread(MemoryArea memArea) { super(null, memArea); this.setName("MyThread"); this.setSchedulingParameters( new PriorityParameters( PriorityScheduler.getMinPriority(this)+1)); } public void run() { // do work } }
  • 38.
    • Heap memory– Heap tradicional porém gerenciada pelo Metronome Garbage Collector. • Scoped memory – as aplicações podem usar e requisitar, porém somente pode ser usada por real-time threads. Tem um contador de utilização que quando chega a zero é liberada. • Immortal memory – usada para carga de classes e inicialização estática mesmo que a aplicação não faça uso especifico dela. Representa uma área de memória contendo objetos que podem ser referenciados por qualquer schedulable object incluindo no- heap real-time threads e no-heap asynchronous event handlers., sem excessões ou delays de garbage collection. • Physical memory – premite que objetos sejam criados em regiões específicas da memória real que tenham características únicas e importantes tal como memória que tenha um acesso mais rápido. Em geral é pouco usado e não afeta o usuario normal de JVM. O Java RT implementa 4 tipos de memória:
  • 39.
    Immortal memory A ImmortalMemory é um recurso de memoria compartilhado entre todos os objetos e threads “esqueduláveis” numa aplicação. Os objetos alocados na Immortal memory estão sempre disponíveis para as non-heap threads e para os assichronous event handlers, esses objetos não estão sujeitos aos delays causados pelo processo de garabage collection. Esses objetos são liberados pelo sistema quando o programa termina. Parâmetro para definir a Immortal Memory: -Xgc:immortalMemorySize=20m sets 20 MB
  • 40.
    Exemplo de usode ImmortalMemory import javax.realtime.MemoryArea; public class MyObject { Object obj; public MyObject(MemoryArea memArea) { memArea.enter(new Runnable() { public void run() { // do something } }); } } import javax.realtime.RealtimeThread; import javax.realtime.PriorityParameters; import javax.realtime.PriorityScheduler; import javax.realtime.HeapMemory; import javax.realtime.ImmortalMemory; public class MyThread extends RealtimeThread { public MyThread() { this.setName("MyThread"); this.setSchedulingParameters( new PriorityParameters( PriorityScheduler.getMinPriority(this)+1)); } public void run() { final MyObject myObject = new MyObject(HeapMemory.instance());, ImmortalMemory.instance().enter(new Runnable() { public void run() { // do work in immortal heap } }); } }
  • 41.
    Scoped memory • Opadrão RTSJ introduziu o conceito de scoped memory. • Ele pode ser usado por objetos que tenham uma duração bem definida. • Um scope pode ser definido explicitamente ou ele pode ser anexado à um schedulable object (uma thread real-time ou à um asynchronous event handler) que efetivamente cria o scope antes que ele execute o método run() do objeto. • Cada scope tem um contador de referência e quando ele chega a zero, os objetos que residem nesse scope podem ser fechados (finalizados) e a memória associada a esse scope é liberada. • O re-uso do scope fica bloqueado até que finalização esteja completa. • Parâmtero para definir scoped memory: • -Xgc:scopedMemoryMaximumSize (default 8 MB)
  • 42.
    Exemplo de usode ScopedMemory import javax.realtime.RealtimeThread; import javax.realtime.PriorityParameters; import javax.realtime.PriorityScheduler; import javax.realtime.LTMemory; import javax.realtime.ScopedMemory; import javax.realtime.SizeEstimator; public class MyThread extends RealtimeThread { static final int load = 1000000; public MyThread() { this.setName("MyThread"); this.setSchedulingParameters( new PriorityParameters( PriorityScheduler.getMinPriority(this)+1)); this.setDaemon(true); } public void run() { SizeEstimator size = new SizeEstimator(); /** * Calulate the memory footprint of all objects */ size.reserve(long[][].class, load); size.reserve(long[].class, load * 50); ScopedMemory memArea = new LTMemory(size); while (true) { /* A scoped memory area is being used. Normally the garbage collector would have to deal with the * unused classes, but with scoped memory we are throwing away all of the objects in the scope when * we exit the enter() method. This will put much less load on the garbage collector. */ memArea.enter(new Runnable() { public void run() { int count = 0; long[][] array = new long[load][]; for (int n = 0; n < array.length; n++) { array[count] = new long[50]; } }); } }}
  • 43.
    AOT – compilaçãoAhead of Time Reduz a pausa causada pelo compilador JIT Dificil pois o Java tem features da linguagem que requerem o compilador JIT por questões de performance. sx.: subclasses definindo “new types” podem ser carregadas dinamicamente no tempo de execução. A performance obtida pelo uso do AOT é uma alternativa entre o codigo interpretado e código totalmente otimizado gerado pelo JIT.
  • 44.
    Ahead-of-time (AOT) Compila osprogramas (classes) antes de ser executado AOT evita o problema do JIT não compilar o codigo antes que ele seja requerido para execução. Just-InTime (JIT) JIT NÃO causa delays indesejados em código real time. JIT é executado como uma thread de alta prioridade (SCHED_OTHER) roda acima das threads normais do Java roda abaixo das threads real-time O trabalho de alta-prioridade não é interrompido pelo trabalho do JIT O trabalho real-time é executado em tempo porém o trabalho real-time pode acabar tendo que interpretar bytecodes porque o JIT não conseguiu compilar em tempo os métodos que estavam na fila. AOT e JIT
  • 45.
    Pode-se controlar quandoe como o compilador JIT opera, usando a classe java.lang.Compiler fornecida com o SDK standard. A JVM suporta os métodos: Compile.compileClass() Compiler.enable() Compiler.disable()
  • 47.
    Sem Metronome eAOT 10 s 1 s 100 μs 10 ms 100 ms 1 ms 10 μs RealTimeThread com Heap NoHeapRealTimeThread com Scopes
  • 48.
    Com Metronome eAOT 10 s 1 s 100 μs 10 ms 100 ms 1 ms 10 μs RealTimeThread com Heap NoHeapRealTimeThread com Scopes
  • 49.
  • 50.
  • 53.
    Porque Real-time Java? Para fornecedores dos orgãos de defesa e militares , o Java é o novo ADA É difícil de encontrar programadores ADA... Sistemas de defesa – precisam de real-time – estão cada vez mais integrados outros sistemas e mais complexos. Setor Financeiro Aplicações automatizadas de compra/venda tem necessidade de real-time. Web sites com tempo de resposta garantido Numa arquitetura muti-tier onde orequerimento de tempo de resposta de milisegundos para satisfazer o requisito de um page-load abaixo de 1 segundo.
  • 54.
    Conclusão Enterprise Real-Time: umanova maneira de “pensar”real-time Mais poderoso e com mais features do que o tradicional “hard real-time” Melhor determinismo do que o esperado pelo soft real-time Java Real Time e Real-Time Linux Extensions Implementação do conceito de enterprise real-time Disponível para os “lead adopters” Metronome GC e AOT tornam o uso do de programas real-time em Java mais fáceis e “mais saborosos”.
  • 55.
  • 56.
    Demonstração: Harmonicon: http://www.youtube.com/watch?v=jid4WaILPBk - Sintetizador MIDIescrito em Java RT - Música em real-time mesmo com a máquina sobrecarregada http://www.youtube.com/watch?v=AKfmBMTx0gM - Explicação geral sobre features e funcionamento
  • 57.
    Proibida cópia oudivulgação sem permissão escrita do CMG Brasil. Flavio C Buccianti flaviocb@gmail.com OBRIGADO !