Programmation multitâches & OS temps réel  1.0
[TD-3] Classes pour la gestion du temps

Classe Chrono

La classe Chrono implémente les fonctionnalités de mesures de temps d’un chronomètre. À sa création, l’objet Chrono initialise son temps de démarrage au temps courant mais on peut réinitialiser cette valeur par la méthode restart(). L’appel de stop() fixe la valeur de stopTime au temps courant. Si le chronomètre est activé (stop() n’a pas été appelé après la création ou un appel à restart()), l’appel de lap() renvoie le temps courant (en millisecondes) écoulé depuis le (re)démarrage du chronomètre ; si le chronomètre est désactivé (stop() a été appelé sans qu’il y ait eu un appel à restart()), l’appel de lap() renvoie le temps (en millisecondes) écoulé entre le (re)démarrage du chronomètre et l’appel à stop(). L’interface est définie par ‎la figure 1.

Implémentez la classe Chrono en C++ en utilisant la fonction Posix clock_gettime().
Testez votre classe par exemple en utilisant votre propre montre.‎

Figure 1 : Spécification de la classe Chrono.

Classe Timer

L’objectif est de programmer une classe Timer qui encapsule les fonctionnalités d’un timer Posix. La classe Timer ‎doit implémenter l’interface définie par la figure 2. Cette classe est abstraite puisque l’opération callback() ne peut être implémentée : elle doit être implémentée pour un timer spécifique dérivant de la classe Timer. ‎

Figure 2 : Spécification des classes Timer.

Pour chaque élément de classe de la figure 2, expliquez pourquoi il est public, privé ou protégé.
Expliquez quelle est l’utilité de la méthode de classe (statique) call_callback().
Spécifiez quelles opérations doivent être définies comme vituelles.
Implémentez le code des classes Timer et PeriodicTimer en C++ .
Testez-la en implémentant une classe dérivée CountDown imprimant à l’écran un compte à rebours à 1 Hz depuis un nombre n jusqu’à 0.‎‎

Calibration en temps d’une boucle

La figure 3 propose une architecture orientée objets pour refaire l’exercice du ‎TD-1 :

Figure 3 : Spécification des classes Looper, Calibrator et CpuLoop.
  • Calibrator dérive de ‎PeriodicTimer et implémente une méthode callback() lui permettant de mesurer les paramètres a et b de l’équation l(t)=a×t+bl est le nombre de boucles effectuées par la méthode Looper::runLoop() pendant le ‎temps t.
  • Cette mesure doit s’effectuer dans le constructeur de Calibrator et utiliser les méthodes getSample() et stopLoop() d'un objet Looper. Normalement, il ne doit y avoir qu’une seule instance de Calibrator dans votre programme, utilisé par tous les objets de type CpuLoop.
  • Calibrator::nLoops() est la ‎méthode qui convertit son paramètre duration_ms en nombre de boucles grâce à l(t).
  • CpuLoop::runTime(duration_ms : double) fait appel à Calibrator::nLoops() puis appelle la méthode runLoop héritée de Looper. Chaque instance de CpuLoop est utilisable par une seule tâche dont on veut contrôler le temps d’exécution.

Faites un programme analogue à celui du TD-1 en implémentant et en testant les classes de la figure 3.‎