Java temps reel : Java-RTS

Bertrand Dupouy


SOMMAIRE

  1. Documentation
  2. Exercice 1 : ordonnancement
  3. Exercice 2 : ordonnancement et concurrence
  4. Exercice 3 : outils de développement



Ce TP illustre le développement d'une application temps réel en utilisant la JVM temps réel de Sun.

1-. Documentation

  1. Temps réel Sun
  2. API Java RTS
  3. Le support de cours.
Utilisation de la JVM temps réel :
  1. Elle est installée sur les machines de la salle C133 et sur la machine lame5.enst.fr.
  2. Il faut être un utilisateur privilégié pour utiliser cet environnement temps réel
  3. les outils de développement s'utilisent comme suit  :
    1. sur lame5.enst.fr :
      sudo  /opt/SUNWrtjv/bin/javac 
      sudo  /opt/SUNWrtjv/bin/java 
      
    2. en salle C133 :
      sudo /opt/rtsj/jrts2.1/bin/javac
      sudo /opt/rtsj/jrts2.1/bin/java
      

2-. Exercice 1 : ordonnancement

Le scénario à mettre en place met en jeu plusieurs tâches :

On partira du canevas proposé dans le fichier disponible ici (ExoRT1.java).

Avant de le compléter, on répondra aux questions suivantes :

Questions préliminaires :

  1. Comment doit-on choisir les priorités des deux tâches périodiques et de l'horloge ? Pourquoi ?
  2. Pourquoi les tâches périodiques utilisent-t-elles une zone mémoire du type LTMemory ?
  3. Pourquoi l'espace mémoire (cf. Mem. restante dans la trace ci-dessous) diminue-t-il à chaque activation de tâche ?
  4. Est-il correct de tracer l'exécution avec System.out.println ?
    Comment faudrait-il faire ?

A faire :

  1. Prendre le code source de ExoRT1.java et compléter les lignes comportant la mention  :    A COMPLETER
  2. Exécuter le programme ainsi :
    1. Premier type d'exécution (en utilisant les options par défaut) :
      la tâche dont la période est 4 manque des échéances,
    2. Deuxième type d'exécution :
      donner des paramètres d'entrée tels que les tâches se terminent par épuisement de la mémoire de type LTMemory,
L'exécution du programme doit produire ce type de trace :
$ sudo  /opt/SUNWrtjv/bin/java ExoRT1      
...
Nom      Priorite      Activation                Periode          Cout          Echeance
null : 68      nullnull(1000 ms, 0 ns)null
ThRT-1 : 67      (38934 ms, 712828 ns)(3000 ms, 0 ns)(1000 ms, 0 ns)(1500 ms, 0 ns)
ThRT-2 : 66      (38934 ms, 712828 ns)(4000 ms, 0 ns)(1000 ms, 0 ns)(500 ms, 0 ns)
Date d ACTIVATION des threads :(33967 ms, 392220 ns)
Lancement de null : RealtimeThread-0
Lancement de ThRT-1 : RealtimeThread-1
Lancement de ThRT-2 : RealtimeThread-2
Periodes : PPCM = 12000
00:00
00:01
00:02
00:03
Thread[RealtimeThread-2,66,main] : ThRT-2 num : 2date d activation :(38935 ms, 385748 ns)
Thread[RealtimeThread-1,67,main] : ThRT-1 num : 1date d activation :(38935 ms, 385824 ns)
ThRT-2 date RE-activation :(38936 ms, 66948 ns) Mem. restante :28344
ThRT-1 date RE-activation :(38936 ms, 387152 ns) Mem. restante :27096
00:04
00:05
00:06
ThRT-1 date RE-activation :(41934 ms, 815076 ns) Mem. restante :25736
00:07
ThRT-2 date RE-activation :(42934 ms, 802596 ns) Mem. restante :24432
00:08
00:09
ThRT-1 date RE-activation :(44934 ms, 792144 ns) Mem. restante :23128
00:10
00:11
--- main : ThRT-1 present
ThRT-2 date RE-activation :(46934 ms, 787832 ns) Mem. restante :21824
00:12
ThRT-1 date RE-activation :(47934 ms, 789556 ns) Mem. restante :20520
00:13
00:14

3-. Exercice 2 : ordonnancement et concurrence

On va maintenant mettre en oeuvre un scénario du type producteur/consommateur :
A faire : L'exécution du programme doit produire ce type de trace :
$ sudo  /opt/SUNWrtjv/bin/java ExoRT2 3  4
Nom      Priorite      Activation                Periode          Cout          Echeance
null : 68      nullnull(1000 ms, 0 ns)null
PRODUCTEUR-1 : 67      (1225188817737 ms, 276108 ns)(3000 ms, 0 ns)(1000 ms, 0 ns)(1500 ms, 0 ns)
PRODUCTEUR-2 : 66      (1225188817737 ms, 276108 ns)(4000 ms, 0 ns)(1000 ms, 0 ns)(1500 ms, 0 ns)
PRODUCTEUR-3 : 65      (1225188817737 ms, 276108 ns)(5000 ms, 0 ns)(1000 ms, 0 ns)(1500 ms, 0 ns)
 PPCM des periodes = 60000


Date de lancement des threads : (1225188811767 ms, 674724 ns)
Date d activation  : (1225188817737 ms, 276108 ns)
Lancement de null
Lancement de PRODUCTEUR-1
Lancement de PRODUCTEUR-2
Lancement de PRODUCTEUR-3
CONSOMMATEUR-1: DEBUT 
00:00
00:01
00:02
00:03
00:04
PRODUCTEUR-1 date d activation :(1225188817738 ms, 29852 ns)
PRODUCTEUR-2 date d activation :(1225188817738 ms, 43704 ns)
PRODUCTEUR-1 depose : 1001
PRODUCTEUR-2 depose : 2001
PRODUCTEUR-3 date d activation :(1225188817738 ms, 62792 ns)
CONSOMMATEUR-1 a pris : 1001 reveil dans : 3061
PRODUCTEUR-3 depose : 3001
00:05
00:06
00:07
PRODUCTEUR-1 depose : 1002
00:08
CONSOMMATEUR-1 a pris : 2001 reveil dans : 5848
PRODUCTEUR-2 depose : 2002
00:09
PRODUCTEUR-3 depose : 3002
00:10
00:11
00:12
Thread[RealtimeServerThread-1,30,] : Echeance depassee pour PRODUCTEUR-1
00:13
CONSOMMATEUR-1 a pris : 3001 reveil dans : 3329
PRODUCTEUR-1 depose : 1003
00:14
Thread[RealtimeServerThread-3,30,] : Echeance depassee pour PRODUCTEUR-2

4-. Exercice 3 : outils de développement

Pour éviter tout accès mémoire non-prédictible, il faut (au moins) précompiler les sources et précharger les fichiers .class.
Les étapes à suivre sont les suivantes :
  1. Génération du byte code,
  2. Construction la liste de précompilation, option :
    
    -XX:+RTSJBuildCompilationList (->nhrt.precompile)
    
  3. Construction la liste de préchargement, options :
    
    -Drtsj.precompile=nhrt.precompile
    -XX:+RTSJBuildPreloadList (->itc.preload)
    -XX:+RTSJBuildClassInitializationList (->itc.preinit)
    
  4. Exécution avec contrôle et suivi de la taille de la mémoire utilisée par le garbage collector, options :
    
    -Drtsj.preinit=itc.preinit
    -Drtsj.precompile=nhrt.precompile
    -Drtsj.preload=itc.preload 
    -XX:RTGCCriticalReservedBytes=10m -XX:+ITCRT -XX:+PrintGC
    
On trouvera :