/ Exec \
soit modifie par les insłrucłions de la routine d’interruption. La commutation de taches ou "task-switching" corres-pond essentiellement a sauvegarder les registres de travail du mP puisqu'utilisśs par le programme en cours puis restau-rer ceux d'un autre programme a exścu-ter. C’est le role respectif, de la paire de fonctions Switch()/Dispatch() d'Exec (Commuter/Mettre a 1’ordre du jour ou Expśdie).
I--------------]
[Fxec() (cons)) Ivir. Switch() ] (vtr Dispalch()] [vir AcdTask()j
IW
Arbre
cTheritage
(vo:r «Apartś»)
_I_ _I_ _l_
/Exec68000\ /Exec68020fFPU\ /Exec68020+FPU+MMU\
Apartć
Celles-ci peuvent etre considśrśes comme des fonctions virtuelles, comme on l'a vu dans l article du mois de no-vembre 96 : "Les fonctions virtuelles avec C/C++", une table virtuelle (des fonctions declarees virtuelles) est initiali-see dans le constructeur et le principe en est une indirection. lei, Exec construit d’abord une bibliotheque, l’śquivalent de cette table Selon le type du mP (tests des instructions disponibles) fixe les pointeurs de fonctions de la table avec les routines Switch(). Dispatch(), Add-Task() correspondant au type du mP. Le noyau utilise ensuite une fonction en ap-pelant "son vecteur" dans la bibliothś-que. comme pour les fonctions virtuelles de C/C++. Ci-contre, l'arbre d'hśritage que l'on aurait pu construire a partir de
(•............... (.......................J [..................................1
(Exec() ] (Exec() ] [Exec()
[vir SDA. ) |vir SDA ] (vir. SDA ]
[----------------] [----------------------] [-----------------------------]
!
classes C++ :
Exec (classe de base), Exec68000, Exec68020, Exec68020+FPU et Exec68020+FPU+MMU.
(Voir figurę ci-contre)
Pour une implantation evolutive qui nous amśnera du mścanisme de corou-
tine a celui de micro-noyau pour du pseudo-parallelisme, nous avons besoin d'une listę (ou table) des programmes a executer et d’un "pointeur sur le cou-rant". Celui qui s’exścute sur le proces-seur. Chaque ślśment de cette listę sera appele descripteur de tache et devra re-fśrencer une pile utilisateur, celle du programme. On pourra au besoin sauvegar-der/restaurer les registres de travail du mP sur cette pile. Le choix d’utiliser un espace commun qui fonctionne comme une pile a śte fait pour le passage de paramśtres et surtout 1’appel de sous-programmes aussi bien en assembleur de la sśrie 680x0, qu'en langages śvo-lues comme Pascal ou C/C++.
Avec ce passage de tśmoin, nous avons, pour 1’instant, un noyau qui fonctionne de faęon cooperative; il est ne-cessaire qu’un programme passe expli-citement le proceseur ś un autre pro- ; gramme. Cette implantation est un peu diffśrente du mścanisme de coroutine, dans lequel c'est un sous-programme que l'on connait et que Ton appelle ex-plicitement par "son vecteur" contenant une adresse de retour prealablement sauvegardee.
Nous pouvons lui ajouter un meca- i nisme d’interruption pśriodique pour que la rśpartition du temps soit equitable en-vers chaque programme ou tache. Ce mecanisme se charge de la commuta- • tion du contexte et nous permet de ne plus faire explicitement la sauve-garde/restauration des registres du mP.
Toutefois cette commutation n’est pas, en pratique, aussi triviale : il nous faudra ajouter, dans le descripteur de tśche, un pointeur sur 1’indice courant dans la pile,
Iś ou sont stockes PC, SR, les registres du mP. Ainsi que d’autres amusements avec les informations des piles SSP et USP... Un tel noyau pourra fonctionner de faęon prśemptive.
Ouant a Exec, il a choisi, nous verrons aprśs pourquoi. de gśrer en plus d'un pointeur sur la tache courante (son descripteur) et d’une listę des taches pretes (a executer), une listę de tśches en at-tente. Nous avons donc deux listes et un pointeur.
Premierement, on trouvera dans la listę des taches en attente celles qui ont appele la fonction Wait (śvśnements) : c'est un appel explicite pour passer son tour lorsque les śvśnements attendus ne sont pas dśjś presents.
Deuxiemement. la listę des taches pretes est en fait une suitę ordonnee par priorite. Nous la nommons suitę et utili-serons le mot file plutót pour une listę, sans notion de priorite, ou l'on enfile a un bout et l on dśfile ś l’autre, par oppo- , sition a une pile. A la tache ślue, celle prścedemment en tete de suitę, sera af- j fectee un laps de temps. Une fois ce ! laps de temps ścoulś, Exec continuera a l'exścuter avec un nouveau laps de temps si c’est la seule disponible ou si elle est toujours la plus prioritaire. Exec est un noyau prśemptif avec priorite sta-tique. Certaines taches seront prioritai-res par rapport a d’autres, essentielle-ment celles du systeme ou la prioritś joue le róle de regulateur, a 1’instar d’un agent de police a un carrefour ou de vś-hicules prioritaires a un rond-point. Les tśches des utilisateurs seront au niveau de priorite 0. Etant donnś que la prioritś est statique (elle ne diminue pas au fur et a mesure que la tache s'exścute), c’est toujours la tśche avec la prioritś la plus ślevśe et prśte a s'exścuter qui sera choisie par Exec, simplement en enlevant le descripteur en tete de la listę taches pretes.
Toutefois, la plupart des taches sont en attentes d'śvśnements et bloquees dans la fonction Wait (masque d'śvś-nements) aprśs l’avoir appelśe, si un des evenement n’est pas deja prśsent. On devrait dire des taches de cette listę qu’elles sont endormies contrairement a celles de la suitę des taches pretes, en file "d'attente" d’execution.
Exercice 1:
Comment definir la priorite d'une tache? Quelques faits i) seule une tache qui n'effectue que du calcul ou "boucle", peut effondrer le systeme si nous aug-mentons assez sa priorite; au-dessus de celles des taches du systśme ii) Exec est a priorite statique, rien ne sert de donner une priorite elevee a une tache pour qu’elle s’exścute de faęon exclusive quand elle est souvent dans la listę des taches en attente; elle fait par exemple beaucoup de sorties a 1’ścran.
Dans ces cas, fixer la priorite du Shell a 1 par "ChangeTaskPri 1" ou s'execute le programme est une solution simple et effective pour accelerer Taffichage, et in-directement definir une priorite dynami-que de traitement pour les commandes lancees dans ce shell; sa tache va se trouver plus souvent ślue que celle lan-cśe dans des shells en prioritś 0.
Lancer la commande "dir ; all" dans deux shells et sur le mśme lecteur, vous voyez alors que dans le shell le plus prioritaire (ChangeTaskPri 1) les fichiers I apparaissent plus vite. Vous vous aper-cevez que cette tache passe parfois dans la listę des taches en attente puis-que, dans 1’autre shell, quelques fichiers apparaissent aussi.
Enfin, si un groupe de taches prśtes ś meme prioritś, celles-ci se rśpartissent śquitablement le mP. Ceci est du ś la fonction Enqueue() qui inserera une tache prete dans la suitę, apres toutes celles qui ont la mśme prioritś. Ainsi, Exec les elira tour a tour en choisissant une tache diffśrente en tete de suitę. Pour des prioritśs identiques, la fonction En-queue() s'applique bien a une file et cor-respond ś enfiler Men queue" de listę, de file. On nommera 1’opśration defiler celle qui prend en t§te de file.
Remarque 2: seules les Communications sont explicites, et pourront ś nouveau etre dślśguees a une couche logicielle supplśmentaire a Exec: 1’AmigaDOS.
Le meme principe de dślśgation du mścanisme d’interruption au micro-processeur s'applique pour la dśle-gation de la partie sauvegarde/-restauration du contexte au noyau C’est Exec, le noyau preemptif du systśme dexploitation qui s’en oc-cupe.
AmigaNews Fevrier 1997 Nc 98 57