• Aucun résultat trouvé

Java Temps Reel. par la pratique. 2009/2010

N/A
N/A
Protected

Academic year: 2022

Partager "Java Temps Reel. par la pratique. 2009/2010"

Copied!
40
0
0

Texte intégral

(1)

Serge.Midonnet@univ-paris-est.fr

Java Temps Reel

par la pratique

2009/2010

(2)

Plan du Cours

Introduction - Motivation pour le temps réel La concurrence : les threads java Le temps réel : RTSJ

Ordonnancement

Priorité fixe / Priorité Dynamique Entités Ordonnançables

Modèle théorique de tâches et Classes RTSJ

Paramètres d’ordonnancement (SchedulingParameters) Paramètres d’activation (ReleaseParameters) / modèles de trafic Analyse de Faisabilité (conditions)

Charge Processeur / Temps de réponse / Période d’étude Tolérance aux Fautes: Détecteurs et Interruptions asynchrones Partage de Ressource et Algorithmes de Synchronisations

2

(3)

Chapitre 1

Concurrence et Temps Réel

La programmation concurrente est l’ensemble des mécanismes permettant l’exécution concurrente d’actions spécifiées de façon séquentielle.

En Java, deux mécanismes pour implanter la concurrence:

les processus pour la concurrence entre applications du système;

la concurrence au sein d’une application: processus légers de la machine virtuelle (threads).

La programmation temps réel permet l’exécution concurrente d’actions spécifiées de façon séquentielle associées à des modèles d’arrivée (activations) déterministes et à des échéances temporelles.

En Java,

une extension a été spécifiée (JSR1): Real Time Specification for Java (RTSJ);

et implantée dans un paquetage: javax.realtime;

(4)

Spécification - RTSJ

Spécification de propriétés temporelles pour Java Historique des spécifications

1998: Appel à Spécification - JSR1 par JCP (Java Community Process) 2002: RTSJ approuvé par JCP

2003: Première implantation par Timesys (JTIME) 2005: RTSJ 1.0.1 (spec) ; JSR 282 (interaction java5, ) 2006: RTSJ 1.0.2 (spec) ; JSR 302 (safety critical) 2009: 1st Draft JSR282 (extensions JSR1)

Plateformes: RI (TimeSys); JamaicaVM (Aicas); Java RTS (Sun) ; Perc Pico (Aonix);

WebSphere Real Time (IBM) ; Jrate (sourceforge); OVM (Purdue); J9VM (IBM) ; aphélion (apogée).

à venir: RTSJ multiprocesseurs (Jeopard) / Implantations DRTSJ (JSR50) 4

(5)

Spécifications RTSJ

Apport de Java au Temps Réel

Choix de l’ordonnanceur et plusieurs types d’entités ordonnançables (RTT,AEH) EO: Propriétés temporelles: Paramètres d’activation, Paramètres

d’ordonnancement

Plus de contrôle: Interruptions Asynchrones, choix du Protocole de Synchronisation; choix du type de mémoire (Memory Parameters).

Analyse de Faisabilité

Détection de fautes temporelles: activations, dépassement de coût Détection de défaillances temporelles: dépassement d’échéances

JAVA (Write Once Run Anywhere) RTSJ (Write Once Carefully Run Anywhere

Maybe) 5

(6)

Caractéristiques des systemes temps réel

STR à contraintes strictes (temps réel dur): le non respect des contraintes temporelles peut conduire à des catastrophes (avionique)

Le standard DO-178B a été développé aux USA pour l’avionique (5 niveaux de conséquence en cas de faute. (a-catastrophique; b-sévère; c-majeur; d-mineur; e-sans effet).

Safety Critical: l’échec d’une exécution ou des fautes conduit à des pertes humaines (niveaux a,b,c).

Mission Critical: DO-178B (niveaux d et e). Systèmes de navigation, Système d’affichage (avionique)/

STR à contraintes relatives (temps réel souple): le non respect de contraintes temporelles est toléré, sans conséquence catastrophique (multimédia)

STR à contraintes mixtes composé de tâches temps réel dures et de tâches temps réel

souples. 6

(7)

Plateforme : Brique Lego NXT

2 microcontrôleurs

(faible consommation; toutes les fonctions sur une puce; programme embarqué; interface de communication)

microcontrôleur 32 bits ARM7 - 256ko de mémoire falsh - 64 ko de RAM (processeur principal)

microcontrôleur ATMEL AVR 8bits - 4ko mémoire flash - 512o RAM(gestion des périphériques - entrées/sorties)

Communication BlueTooth Port USB (12Mo/sec)

4 Ports d ‘entrée / 3 ports de sortie Ecran LC (100x64 pixels)

HautParleur (son 8bit - 8khz) 7

(8)

Plateforme : Brique Lego NXT

Servomoteur + tachymètre (capteur de rotation) contact

lumière couleur

distance (ultrason), son,

gyroscope température ...

8

(9)

RTSJ: Entités ordonnaNcables

Runnable

Thread

RealtimeThread

NoHeapRealtimeThread

Schedulable

AsyncEventHandler

BoundAsyncEventHandler

Diagramme de classes RTSJ

(10)

threads

(Pour commencer)

Un processus léger (thread) correspond à un fil d’exécution (une suite d’instruction en cours d’exécution). Il s’agit d’un processus créé et géré par la machine virtuelle Java.

Différents états possibles d'une thread

exécute son code cible (elle a accès au processeur) - running attend l'accès au processeur (mais pourrait sʼexécuter) - ready attend un événement particulier (pour pouvoir sʼexécuter) - wait

L'exécution de la cible peut libérer le processeur si elle exécute un yield() (demande explicite)

si elle exécute une méthode bloquante (sleep(), wait()...),

c'est l'ordonnanceur de la JVM qui répartit l'accès des threads au processeur (en fonction des éventuelles priorités).

10

(11)

threads(intro)

Ils sont composés par 3 entités bien distinctes:

l’objet qui contrôle le processus léger. Il est d’une classe dérivant de Thread.

l’objet cible qui représente le code à exécuter (la logique). La classe de cet objet implémente l’interface Runnable.

le fil d’exécution, c’est-à-dire la séquence d’instructions. C’est le code de la méthode run() de la cible.

Ne pas confondre Thread (le contrôleur) et Runnable (le contrôlé).

Au lancement d’un programme, la machine virtuelle possède un unique processus

léger qui exécute le main() de la classe appelée.

(12)

threads(interface)

12

static Thread currentThread() -> retourne l’objet de contrôle du thread en cours d’exécution

 void setName(String name)

 String getName()

 boolean isAlive()  int getPriority()

 void setPriority(int priority)  void run()

void start()

void join(long timeout)

static void sleep(long aMilliseconds)

static void yield() void interrupt() boolean isInterrupted()

(13)

Lejos-RT(commandes)

pour commencer

1. public class HelloWorld {

2. public static void main (String[] args) { 3. System.out.println("Hello World");

4. } 5. }

-> sortie par défaut sur l’écran LCD

+ le paquetage lejos.nxt pour utiliser la classe Button. Permet de temporiser l’affichage

1. import lejos.nxt.*;

2.  

3. public class HelloWorldSerge {

4. public static void main (String[] args) { 5. System.out.println("Hello World from Serge");

6. Button.waitForPress();

7. } 8. }

-> On presse un bouton quelconque pour sortir du programme

(14)

Lejos-RT(commandes)

14 vérification de la connexion de la brique

nxjbrowse -u (usb) -b (bluetooth) :utiliser usb Found NXT: NXT 00165305ACE4

-> ouverture d’une console (Browser): permet de lister les programme chargés dans la brique, d’exécuter des programmes et d‘en supprimer

compilation du programme HelloWorldSerge.java nxjc HelloWorldSerge.java

-> production de HelloWorldSerge.class link, upload (and run)

nxj HelloWorldSerge (nxj -r HelloWorldSerge) ->leJOS NXJ> Linking...

->leJOS NXJ> Uploading...

(15)

import lejos.nxt.*;

public class ThreadMain {

!

! public static void main(String[] args) throws Exception

! {

! ! Thread threadMain = Thread.currentThread();

! ! threadMain.setName("Thread Main");

! ! System.out.println(threadMain.getName());

! ! System.out.println(threadMain.isAlive());

! ! Button.waitForPress();

! }

}

--- import lejos.nxt.*;

public class ThreadSensor {

!

! public static void main(String[] args) throws Exception

! {

! ! Thread threadMain = Thread.currentThread();

! ! threadMain.setName("Thread Sensor");

! ! System.out.println(threadMain.getName());

! ! LCD.drawString("Battery: " + Battery.getVoltage(), 1, 0);

! ! TouchSensor touch = new TouchSensor(SensorPort.S1);

! ! UltrasonicSensor sonic = new UltrasonicSensor(SensorPort.S3);

! ! sonic.reset();

!! while (!touch.isPressed()) {

! ! LCD.drawInt(sonic.getDistance(), 0, 3);

! ! };

!! LCD.drawString("Finished", 3, 4);

! ! Button.waitForPress();

! }

}

threads (main)

(16)

import lejos.nxt.*;

import lejos.nxt.comm.*;

public class ThreadC1 extends Thread{

! public static final int NB_IT = 178000;

! public static long deb;

! public static long start;

! public static long end;

! public static long fin;

!

! public static void main(String[] args) {

! ! while (!RConsole.isOpen()){

RConsole.open();

}

! ! Thread t1 = new Thread(){

! ! public void run() {

! ! ! ! ! ! !

! ! ! ! start=System.currentTimeMillis();

! ! ! ! for(int j=0 ; j < NB_IT ; j++); // la boucle ne doit rien faire d'autre

! ! ! ! ! end=System.currentTimeMillis();

! ! ! ! ! RConsole.println("Debut : " + Long.toString(start-deb));

! ! ! ! ! RConsole.println("Duree : " + Long.toString(end-start));

! ! ! }

! ! };

! ! deb=System.currentTimeMillis();

! ! RConsole.println("t1 alive? : " + Boolean.toString(t1.isAlive()));

! ! t1.start();

! ! RConsole.println("t1 alive? : " + Boolean.toString(t1.isAlive()));

! ! try {

! ! ! t1.join(2000); // le main doit attendre la fin du thread fils

! ! }

! ! catch (InterruptedException ie) {

! ! };

fin=System.currentTimeMillis();

! ! RConsole.close();

Onethread

(création / start / jointure)

16 nxjc -r OneThreadC

nxjConsole

Console :

Console open

t1 alive? : false

t1 alive? : true

Debut (activation) : 7

Duree : 1004

Fin : 6

Console closed

écran LCD :

Console open

Console closed

(17)

Ordonnancement

17

2 4 6 7

5

7 t1

t2

t3

11

11 14

13

(18)

import lejos.nxt.*;

import lejos.nxt.comm.*;

public class TwoThreadC {

! public static final int NB_IT = 178000;

! public static long deb,start1,start2,end1,end2,fin;

!

! public static void main(String[] args) {

! ! while (!RConsole.isOpen()){

RConsole.open();

}

! ! Thread t1 = new Thread(){

! ! ! public void run() {

! ! ! ! start1=System.currentTimeMillis();

! ! ! ! for(int j=0 ; j < NB_IT ; j++); // la boucle ne doit rien faire d'autre

! ! ! ! end1=System.currentTimeMillis();

! ! ! ! RConsole.println("Debut : "+Thread.currentThread().getName()+":"+ Long.toString(start1-deb));

! ! ! ! RConsole.println("Duree : " +Thread.currentThread().getName()+":"+ Long.toString(end1-start1));

! !

! ! ! };

! ! };

! ! t1.setName("T1");

! ! RConsole.println("Priorite de T1:"+ Long.toString(t1.getPriority()));! !

! ! Thread t2 = new Thread(){!

! ! ! public void run() {

! ! ! ! start2=System.currentTimeMillis();

! ! ! ! for(int j=0 ; j < NB_IT ; j++); // la boucle ne doit rien faire d'autre

! ! ! ! end2=System.currentTimeMillis();

! ! ! ! RConsole.println("Debut : "+Thread.currentThread().getName()+":" + Long.toString(start2-deb));

! ! ! ! RConsole.println("Duree : " +Thread.currentThread().getName()+":" + Long.toString(end2-start2));

!

! ! ! };

! ! };!

! ! t2.setName("T2");

! ! RConsole.println("Priorite de T2:"+ Long.toString(t2.getPriority()));

! ! deb=System.currentTimeMillis();

! ! t1.start();

! ! t2.start();

! ! try {

! ! ! t1.join(2000);

! ! ! t2.join(2000);

! ! }

! ! catch (InterruptedException ie) {};

! ! RConsole.close();

! };

};

TWOthread

Priorités - (min/max/def)

18

nxjc -r TwoThreadC

nxjConsole

Console :

Console open

Priorite de T1:5

Priorite de T2:5

Debut : T1:0

Debut : T2:4

Duree : T1:2012

Duree : T2:2007

Console closed

(19)

import lejos.nxt.*;

import lejos.nxt.comm.*;

public class TwoThreadOrdoSp { public static final int NB_IT = 178000;

! public static long deb,start1,start2,end1,end2,fin;

!

! public static void main(String[] args) {

! ! while (!RConsole.isOpen()){

RConsole.open();

}

! ! Thread t1 = new Thread(){

! ! ! public void run() {

! ! ! ! start1=System.currentTimeMillis();

! ! ! ! for(int j=0 ; j < NB_IT ; j++);RConsole.println("T1: ut1");

! ! ! ! for(int j=0 ; j < NB_IT ; j++);RConsole.println("T1: ut2");

! ! ! ! for(int j=0 ; j < NB_IT ; j++);RConsole.println("T1: ut3");

end1=System.currentTimeMillis();

! ! ! ! RConsole.println("Debut : "+Thread.currentThread().getName()+":"+ Long.toString(start1-deb));

! ! ! ! RConsole.println("Duree : " +Thread.currentThread().getName()+":"+ Long.toString(end1-start1));

! !

! ! ! };

! ! };

! ! t1.setName("T1");

RConsole.println("Priorite de T1:"+ Long.toString(t1.getPriority()));!

! ! Thread t2 = new Thread(){

...idem pour t2 (t2= new Thread() et

surcharge de run() et exécution de 3 seconde (3boucles) ...

!

! ! t2.setName("T2");

RConsole.println("Priorite de T1:"+ Long.toString(t2.getPriority()));!

! ! deb=System.currentTimeMillis();

! ! t1.start();

! ! t2.start();

! ! try {

! ! ! t1.join(10000); //attention chaque thread s’exécute pendant 3secondes (2000 n est pas suffsant)

! ! ! t2.join(10000);

! ! }

! ! catch (InterruptedException ie) {};

! ! RConsole.close();

! };

};

TWOthread

Ordonnancement (memes Priorités)

nxjc -r TwoThreadOrdoSp nxjConsole

Console :

Console open

Priorite de T1:5

Priorite de T2:5

T2: ut1

T1: ut1

T2: ut2

T1: ut2

T2: ut3

T1: ut3

Debut : T2:4

Debut : T1:0

Duree : T2:6033

Duree : T1:6041

Console closed

(20)

import lejos.nxt.*;

import lejos.nxt.comm.*;

public class TwoThreadOrdoDp { public static final int NB_IT = 178000;

! public static long deb,start1,start2,end1,end2,fin;

!

! public static void main(String[] args) {

! ! while (!RConsole.isOpen()){

RConsole.open();

}

! ! Thread t1 = new Thread(){

! ! ! public void run() {

! ! ! ! start1=System.currentTimeMillis();

! ! ! ! for(int j=0 ; j < NB_IT ; j++);RConsole.println("T1: ut1");

! ! ! ! for(int j=0 ; j < NB_IT ; j++);RConsole.println("T1: ut2");

! ! ! ! for(int j=0 ; j < NB_IT ; j++);RConsole.println("T1: ut3");

end1=System.currentTimeMillis();

! ! ! ! RConsole.println("Debut : "+Thread.currentThread().getName()+":"+ Long.toString(start1-deb));

! ! ! ! RConsole.println("Duree : " +Thread.currentThread().getName()+":"+ Long.toString(end1-start1));

! !

! ! ! };

! ! };

! ! t1.setName("T1");

RConsole.println("Priorite de T1:"+ Long.toString(t1.getPriority()));!

! ! t1.setPriority(6);

! ! RConsole.println("Priorite de T2:"+ Long.toString(t1.getPriority()));

! ! Thread t2 = new Thread(){

...idem pour t2 (t2= new Thread() et

surcharge de run() et exécution de 3 seconde (3boucles) ...

!

! ! t2.setName("T2");

RConsole.println("Priorite de T1:"+ Long.toString(t2.getPriority()));!

! ! t2.setPriority(6);

! ! RConsole.println("Priorite de T2:"+ Long.toString(t2.getPriority()));

! ! deb=System.currentTimeMillis();

! ! t1.start();

! ! t2.start();

! ! try {

! ! ! t1.join(10000); //attention chaque thread s’exécute pendant 3secondes (2000 n est pas suffsant)

! ! ! t2.join(10000);

! ! }

! ! catch (InterruptedException ie) {};

! ! RConsole.close();

! };

};

TWOthread

Ordonnancement (Différentes Priorités)

20 nxjc -r TwoThreadOrdoDp nxjConsole:

Console open Priorite de T1 avant:5 Priorite de T1 apres:6 Priorite de T2 avant:5 Priorite de T2 apres:8 T2: ut1

T2: ut2

T2: ut3

Debut : T2:0

Duree : T2:3020

T1: ut1

T1: ut2

T1: ut3

Debut : T1:3026

Duree : T1:3017

Console closed

(21)

import lejos.nxt.*;

import lejos.nxt.comm.*;

public class TwoThreadOrdoPr { public static final int NB_IT = 178000;

! public static long deb,start1,start2,end1,end2,fin;

!

! public static void main(String[] args) {

! ! while (!RConsole.isOpen()){

RConsole.open();

}

! ! Thread t1 = new Thread(){

! ! ! public void run() {

! ! ! ! start1=System.currentTimeMillis();

! ! ! ! for(int j=0 ; j < NB_IT ; j++);RConsole.println("T1: ut1");

! ! ! ! for(int j=0 ; j < NB_IT ; j++);RConsole.println("T1: ut2");

! ! ! ! for(int j=0 ; j < NB_IT ; j++);RConsole.println("T1: ut3");

end1=System.currentTimeMillis();

! ! ! ! RConsole.println("Debut : "+Thread.currentThread().getName()+":"+ Long.toString(start1-deb));

! ! ! ! RConsole.println("Duree : " +Thread.currentThread().getName()+":"+ Long.toString(end1-start1));

! !

! ! ! };

! ! };

! ! t1.setName("T1");

RConsole.println("Priorite de T1 avant:"+ Long.toString(t1.getPriority()));!

! ! t1.setPriority(6);

! ! RConsole.println("Priorite de T1 après:"+ Long.toString(t1.getPriority()));

! ! Thread t2 = new Thread(){

...idem

! ! t2.setName("T2");

RConsole.println("Priorite de T2 avant:"+ Long.toString(t2.getPriority()));!

! ! t2.setPriority(6);

! ! RConsole.println("Priorite de T2 après:"+ Long.toString(t2.getPriority()));

! ! deb=System.currentTimeMillis();

! ! t1.start();

! ! try {

! ! ! Thread.sleep(1000);

! ! }

! ! catch (InterruptedException ie) {};

! ! t2.start();

! ! try {

! ! ! t1.join(10000);

! ! ! t2.join(10000);

! ! }

! ! catch (InterruptedException ie) {};

! ! t2.start();

! ! try {

TWOthread

Ordonnancement (Preemption)

21 nxjc -r TwoThreadOrdoDp nxjConsole:

Console open Priorite de T1 avant:5 Priorite de T1 apres:6 Priorite de T2 avant:5 Priorite de T2 apres:8 T2: ut1

T2: ut2

T2: ut3

Debut : T2:0

Duree : T2:3020

T1: ut1

T1: ut2

T1: ut3

Debut : T1:3026

Duree : T1:3017

Console closed

(22)

Caractéristiques des tâches temps réel

Date d’activation: ri. Lorsque toutes les activations sont simultanée (r1=r2=...=ri) on parle d’activation synchrone

Durée d’exécution (charge processeur): Ci

Période d’activation: Ti,TiMin: Durée fixe ou minimale entre les activations de deux instances successives.

Echéance ou Délai critique; Di: Temps alloué à la tâche pour terminer son exécution.

Echéance sur requête (Di=Ti) / Echéance contrainte (Di<=Ti)

Ci +

t0 ri ri + Ti

Réactivation Activation

ri + Di

Echéance

22

(23)

QQS Définitions

un ordonnanceur préemtif et non préemtif.

des tâches sont synchrones si leur activation est simultannée.

ordonnancement hors ligne: une séquence d’ordonnancement est générée, implantée dans une table et répétée à l’infini par un séquenceur.

ordonnancement en ligne: l’algorithme est implanté dans le noyau et exécuté à chaque

instant

(24)

ordonnaNcement FP/HPF

Rate Monotonic

17

2 4 6 7

5

7 t1

t2

t3

11

11

14

13

2 7 7

3 11 11

5 13 13

24

(25)

Algorithmes d’ordonnaNcement

Principaux algorithmes: Rate Monotonic, Deadline Monotonic, Earliest Deadline First, FIFO.

RTSJ: un ordonnanceur à priorités fixes est obligatoire: FP/HPF

-> classe PriorityScheduler (obligatoire) -> autre classes (optionnelles) EDFScheduler un minimum de 28 priorités

Prio > 10 threads temps réel / Prio < = 10 threads non temps réel

Scheduler Scheduler.getDefaultScheduler();

void Scheduler.setDefaultScheduler(Scheduler s);

String Scheduler.getPolicyName();

public static void main(String [] args){

Scheduler.setDefaultScheduler(PriorityScheduler.instance());

(26)

RTSJ: Entités ordonnaNcables

Runnable

Thread

RealtimeThread

NoHeapRealtimeThread

Schedulable

AsyncEventHandler

BoundAsyncEventHandler

Diagramme de classes RTSJ

26

(27)

Threads Temps Réel oneshot

classe RealTimeThread

Note: Thread oneshot. Quelle priorité par défaut ?

public static int MIN_PRIORITY = PriorityScheduler.instance().getMinPriority();

public static int MAX_PRIORITY = PriorityScheduler.instance().getMaxPriority();

import javax.realtime.*;

public class LaPlusSimple {

public static void main (String [] args){

RealtimeThread lps = new RealtimeThread(){

public void run () {

System.out.println ("hello from LaPlusSimple");

} };

lps.start();

}

}

(28)

Parametres d’ordonnncement

classe SchedulingParameters classe PriorityParameters

import javax.realtime.*;

public class PasTropDure {

public static void main (String [] args){

RealtimeThread ptd = new RealtimeThread(new PriorityParameters(prio)){

public void run () {

System.out.println ("hello from PasTropDure");

} };

lps.start();

} }

ImportanceParameters SchedulingParameters

PriorityParameters

28

(29)

Realtime Thread (Ordonnancement)

29

public class TwoRTTPreempt {

! public static final int NB_IT = 176500;

! public static long deb;

! public static long start1;

! public static long end1;

!

! public static void main(String[] args) {

! ! while (!RConsole.isOpen()){

RConsole.open();

}

!

! ! RealtimeThread t1 = new RealtimeThread(new PriorityParameters(15),new PeriodicParameters(

new RelativeTime(0,0), new RelativeTime(5000,0), new RelativeTime(2000,0),

new RelativeTime(5000,0), null, null)) {

! ! ! public void run() {! ! !

! ! ! ! ! ! int i=0;

! ! ! ! ! ! do{

! ! ! ! ! ! ! RConsole.println("Entre dans 1 !");

! ! ! ! ! ! ! start1=System.currentTimeMillis();

! ! ! ! ! ! ! RConsole.println("Delai de preemption : "+ Long.toString(start1-(deb+i*5000)) );

! ! ! ! ! ! ! for(int k=0 ; k < NB_IT ; k++) ;

! ! ! ! ! ! ! //for(int k=0 ; k < NB_IT ; k++)!! ! ! ! ! !

! ! ! ! ! ! ! end1=System.currentTimeMillis();

! ! ! ! ! ! ! RConsole.println("Debut 1 : " + Long.toString(start1-deb));

! ! ! ! ! ! ! RConsole.println("Duree 1 : " + Long.toString(end1-start1));! ! ! ! ! ! ! ! i++;

! ! ! ! ! ! ! RConsole.println("Fin de 1 *")! ! ! ! ! ! ! !

}while(waitForNextPeriod() && i<3);

! ! ! }

! ! };

! ! !

! ! ! !

! ! deb=System.currentTimeMillis();

! ! RConsole.println("Debut");

! ! t1.start();

! ! try {

! ! ! t1.join(20000);

! ! }

! ! catch (InterruptedException ie) {};

! ! RConsole.close();

! ! ! ! ! !

! }

nxjc -r OneRTTPeriodic

Console open

Debut

Entree dans 1 !

Delai de preemption : 4

Debut 1 : 4

Duree 1 : 1004

Fin de 1 *

Entree dans 1 !

Delai de preemption : 4

Debut 1 : 5004

Duree 1 : 1003

Fin de 1 *

Entree dans 1 !

Delai de preemption : 4

Debut 1 : 10004

Duree 1 : 1003

Fin de 1 *

Console closed

(30)

Parametres D’activation

classe ReleaseParameters classe PeriodicParameters classe SporadicParameters

PeriodicParameters(HighResolutionTime start, RelativeTime period,

RelativeTime cost, RelativeTime deadline,

AsyncEventHandler overrunHandler, AsyncEventHandler missHandler)

PeriodicParameters

ReleaseParameters

AperiodicParameters

SporadicParameters

SporadicParameters(RelativeTime minInterarrival,

RelativeTime cost, RelativeTime deadline,

AsyncEventHandler overrunHandler, AsyncEventHandler missHandler)

30

(31)

Realtime Thread Periodique

31

public class OneRTTPeriodic {

! public static final int NB_IT = 176500;

! public static long deb;

! public static long start1;

! public static long end1;

!

! public static void main(String[] args) {

! ! while (!RConsole.isOpen()){

RConsole.open();

}

!

! ! RealtimeThread t1 = new RealtimeThread(new PriorityParameters(15),new PeriodicParameters(

new RelativeTime(0,0), new RelativeTime(5000,0), new RelativeTime(2000,0),

new RelativeTime(5000,0), null, null)) {

! ! ! public void run() {! ! !

! ! ! ! ! ! int i=0;

! ! ! ! ! ! do{

! ! ! ! ! ! ! RConsole.println("Entre dans 1 !");

! ! ! ! ! ! ! start1=System.currentTimeMillis();

! ! ! ! ! ! ! RConsole.println("Delai de preemption : "+ Long.toString(start1-(deb+i*5000)) );

! ! ! ! ! ! ! for(int k=0 ; k < NB_IT ; k++) ;

! ! ! ! ! ! ! //for(int k=0 ; k < NB_IT ; k++)!! ! ! ! ! !

! ! ! ! ! ! ! end1=System.currentTimeMillis();

! ! ! ! ! ! ! RConsole.println("Debut 1 : " + Long.toString(start1-deb));

! ! ! ! ! ! ! RConsole.println("Duree 1 : " + Long.toString(end1-start1));! ! ! ! ! ! ! ! i++;

! ! ! ! ! ! ! RConsole.println("Fin de 1 *")! ! ! ! ! ! ! !

}while(waitForNextPeriod() && i<3);

! ! ! }

! ! };

! ! !

! ! ! !

! ! deb=System.currentTimeMillis();

! ! RConsole.println("Debut");

! ! t1.start();

! ! try {

! ! ! t1.join(20000);

! ! }

! ! catch (InterruptedException ie) {};

! ! RConsole.close();

! ! ! ! ! !

! }

nxjc -r OneRTTPeriodic

Console open

Debut

Entree dans 1 !

Delai de preemption : 4

Debut 1 : 4

Duree 1 : 1004

Fin de 1 *

Entree dans 1 !

Delai de preemption : 4

Debut 1 : 5004

Duree 1 : 1003

Fin de 1 *

Entree dans 1 !

Delai de preemption : 4

Debut 1 : 10004

Duree 1 : 1003

Fin de 1 *

Console closed

(32)

évenement Sporadique

import javax.realtime.*;

public class SimpleSporadic {

public static void main (String [] args){

AsyncEventHandler aeh=new AsyncEventHandler(

new PriorityParameters(20), new SporadicParameters(

new RelativeTime(4000,0), “période min”

new RelativeTime(1000,0), “coût”

new RelativeTime(2000,0), “échéance”

null, “overrunHandler”

null); “deadlineMissHandler”

null, null, null, true, null){

public void handleAsyncEvent(){

System.out.println("hello from SimpleSporadic");

} };

AsyncEvent ae = new AsyncEvent();

ae.addHandler(aeh);

ae.fire();

sleep(800);

ae.fire();

sleep(800);

ae.fire();

} }

Serge Midonnet

a(3) 4

a(0) ti

16 12

8 0

Ti (0) Ti (1) Ti(2)

a(1) a(2)

32

(33)

Synchronisations classes de moniteurs

import javax.realtime.*;

public class SimpleMonitor{

public static void main(String[] args){

java.lang.Object ressource = new java.lang.Object();

PriorityInheritance pip = PriorityInheritance.instance();

MonitorControl.setMonitorControl(ressource,pip);

PriorityCeilingEmulation pce = PriorityCeilingEmulation.instance(20);

MonitorControl.setMonitorControl(ressource,pce);

} }

MonitorControl

PriorityInheritance PriorityCeilingEmulation

(34)

inversion de priorité non bornée

libération de ressource

5

7

demande de ressource demande de ressource libération de ressourceaccès à la ressource

t3 Basse Priorité t2 Priorité Moyenne

t1 Priorité Haute

exécution normale utilisation de la ressource inversion de priorité

t1 t2 t3 t4 t5

t0

tau_1 subit l’interférence de tau_2 avec laquelle elle ne partage pas de ressource (ni directement ni indirectement).

Le résultat est l’impossibilité de borner le temps de blocage (calcul du facteur de blocage de tau_1).

34

(35)

invrsion de priorité non bornée

!"#$%&!'"()$(*%!'%!+,

- . / 0 11

)$23")$()$(%$&&'4%5$

+1(6%!'%!+,(734+$

8 11

8 11

8 11

0

)$23")$()$(%$&&'4%5$

+9(:3&&$(6%!'%!+, +-!;(6%!'%!+,(<'=$""$

+-!:(6%!'%!+,(<'=$""$

+-!>(6%!'%!+,(<'=$""$

?!@,%3+!'"()$(%$&&'4%5$

355A&(B(?3(%$&&'4%5$?!@,%3+!'"()$(%$&&'4%5$

$C,54+!'"("'%23?$ 4+!?!&3+!'"()$(?3(%$&&'4%5$

(36)

Priority inheritance protocol

Deux types de blocage:

Direct Blocking (blocage direct) Push-through Blocking (blocage indirect)

demande (SC1)

2 4 6 7

5

7

11

11

t3 Basse Priorité t2 Priorité Moyenne

t1 Priorité Haute

exécution normale utilisation de la ressource inversion de priorité utilisation de la ressource en priorité élevée instant d’Héritage accès (SC1) libération (SC1)demande (SC1)

36

(37)

Priority inheritance implantation

monitorControljavax.realtime.PriorityInheritance@7b0c1c t3 : debut de instance 0

t3 : instance 01sec thread3enter RES-1 t31sec

t1 : debut de instance 0 t1 : instance 01sec t32sec t33sec t34sec t35sec thread3leaves RES-1 thread1enter RES-1 t11sec t12sec t13sec t14sec t15sec thread1leaves RES-1 t1 : instance 01sec t1 : fin de instance 0 t2 : debut de instance 0 t2 : instance 01sec t2 : instance 02sec t2 : instance 03sec monitorControljavax.realtime.PriorityInheritance@13ee78

t3 : debut de instance 0 t3 : instance 01sec thread3enter RES-1 t31sec

t1 : debut de instance 0 t1 : instance 01sec t32sec t33sec

t2 : debut de instance 0 t2 : instance 01sec t2 : instance 02sec t2 : instance 03sec t2 : fin de instance 0 t34sec t35sec thread3leaves RES-1 thread1enter RES-1 t11sec t12sec t13sec t14sec t15sec thread1leaves RES-1

Sans PIP Avec PIP

(38)

interblocages

blocage ...

2 4 6 7

t1 Priorité Haute

demande RES1 demande RES2

7 t3 Basse Priorité

demande RES2 demande RES1

exécution normale utilisation de RES1 utilisation de RES2

38

(39)

Chaines de blocages

t3 Basse Priorité t2 Priorité Moyenne

t1 Priorité Haute

L(SC2)

D(SC2)

exécution normale utilisation de SC1 utilisation de SC2

D(SC1)

t3 t4 t5 t6 t7

t0 t1 t2 t8

(40)

Priority Ceiling emulation Propriété

à l'instant t1 tau_3 demande et obtient l'accès à SC1, elle hérite alors de la priorité plafond de la ressource (H).

à l'instant t2: tau_2 est activée mais ne peut pas s'exécuter car sa priorité est inférieure à celle de tau_3.

à l'instant t3: tau_1 veut s'exécuter mais sa priorité est égale à celle de tau_3.

à l'instant t4 tau_3 libère SC1 et tau_1 s'exécute. A l'instant t5 tau_1 accède à SC1 puis à l'instant t6 tau_1 accède à SC2.

2 4 6 7

5

7

11

t3 Basse Priorité t2 Priorité Moyenne

t1 Priorité Haute

exécution normale utilisation de SC1 inversion de priorité utilisation de la ressource SC2 t7

t3 t4 t5

t0 t1 t2 t6 t8 t9 t10

H H

40

Références

Documents relatifs

Modifier l’exécution de la thread temps réel dans la mémoire scope de 7000 octets ( LT1 ), en créant dans un premier temps un objet de type Integer , puis en définissant

Nous présentons dans cet article trois effets : un écho granulaire adaptatif, un ralenti/accéléré temporel sélectif et une robotisation adaptative, les trois étant implémentés

● Utilisation de 2 sondes linéaires complémentaires d'une séquence cible - Une sonde marquée en 3' par un marqueur fluorescent, qui émet une fluorescence verte. - Une sonde

Par notre travail, nous espérons ainsi avoir apporté quelques idées utiles à la communauté de la recherche en informatique musicale dans le domaine de l’interaction entre

Pour ces situations, on préférera un ordonnancement « Round Robin », où une tâche peut s'exécuter pendant une tranche de temps au bout de laquelle elle est préemptée et placée

• waitForNextPeriod suspend le thread courant jusqu’à l’occurrence de sa période suivante, à moins qu’il n’ait manqué son échéance, quand le tnread

Après avoir dressé un état de l’art sur la faisabilité théorique d’un système de tâches périodiques ordonnancé par un algorithme à priorités fixes préemptif, nous

L’ordonnancement d’un syst`eme mixte de tˆaches p´eriodiques temps r´eel dur et ap´e- riodiques temps r´eel souple soul`eve par cons´equent la probl´ematique de la minimisation