Obligement - L'Amiga au maximum

Vendredi 24 novembre 2017 - 21:26  

Translate

En De Nl Nl
Es Pt It Nl


Rubriques

 · Accueil
 · A Propos
 · Articles
 · Galeries
 · Glossaire
 · Hit Parade
 · Liens
 · Liste jeux Amiga
 · Quizz
 · Téléchargements
 · Trucs et astuces


Articles

 · Actualité (récente)
 · Actualité (archive)
 · Comparatifs
 · Dossiers
 · Entrevues
 · Matériel (tests)
 · Matériel (bidouilles)
 · Points de vue
 · En pratique
 · Programmation
 · Reportages
 · Tests de jeux
 · Tests de logiciels
 · Tests de compilations
 · Articles divers

 · Articles in english
 · Articles in other languages


Twitter

Suivez-nous sur Twitter




Liens

 · Sites de téléchargements
 · Associations
 · Pages Personnelles
 · Moteurs de recherche
 · Pages de liens
 · Constructeurs matériels
 · Matériel
 · Autres sites de matériel
 · Réparateurs
 · Revendeurs
 · Presse et médias
 · Programmation
 · Développeurs logiciels
 · Logiciels
 · Développeurs de jeux
 · Jeux
 · Autres sites de jeux
 · Scène démo
 · Divers
 · Informatique générale


Jeux Amiga

0, A, B, C, D, E, F,
G, H, I, J, K, L, M,
N, O, P, Q, R, S, T,
U, V, W, X, Y, Z


Trucs et astuces

0, A, B, C, D, E, F,
G, H, I, J, K, L, M,
N, O, P, Q, R, S, T,
U, V, W, X, Y, Z


Glossaire

0, A, B, C, D, E, F,
G, H, I, J, K, L, M,
N, O, P, Q, R, S, T,
U, V, W, X, Y, Z


Partenaires

Annuaire Amiga

Amedia Computer

Relec

Hit Parade


Contact

David Brunet

Courriel

 


Dossier : Voyage au centre de la ROM Amiga (Exec, multitâche, messages et allocation mémoire)
(Article écrit par Stéphane Mayère et extrait d'A-News (Amiga News) - février 1990)


Séquence introduction

On va essayer de voir ensemble l'architecture interne de l'Amiga : le noyau qui comprend les bibliothèques de routines, la gestion des coprocesseurs spécialisés. Autrement dit, accrochez-vous à vos bretelles, on va décoller !

Séquence Exec...ution

La grande force de l'Amiga réside dans sa modularité et dans l'interconnexion entre les différents composants du système : duraille et molaille... euh je veux dire matériel et logiciel : ces deux éléments se combinent de plusieurs manières de façon à donner le maximum de performance. Par exemple, la machine possède un coprocesseur spécial : le Copper, qui est capable de se synchroniser de lui-même sur la position du spot d'affichage sans avoir besoin d'accéder au bus ou au processeur principal : le 68000. Le Copper peut donc transférer des données d'un ou plusieurs registres ou encore causer une interruption au 68000 que traitera Exec, le coeur multitâche de l'Amiga.

Ceci fait du Copper un outil puissant, qui de plus n'interfère pas sur le processeur principal. Il est utilisé par la bibliothèque de routines graphiques (graphics.library) pour des changements d'affichage (voir les listes Copper de ceux qui vous apprennent l'assembleur) et également par les périphériques audio pour la manipulation des canaux audios en temps réel. On peut utiliser le Copper pour les opérations en temps réel ou très rapides du fait qu'il est calé sur l'affichage qui est garanti à 50 Hz : le processeur d'affichage démarre du haut de l'écran 50 fois par seconde.

La manière dont l'Amiga gère les communications avec ses périphériques est un autre bon exemple de l'union matériel/logiciel. Les signaux qui passent entre l'Amiga et les périphériques sont gérés par des interruptions. De plus, les périphériques ne dérangent pas le système ou n'apparaissent pas tant que l'information véhiculée n'a pas à être communiquée. Exec travaille avec un système complet de communications gérées par interruptions qui lui permettent de diriger un système de "processes" commode, avec des priorités, des attentes...

Le noyau multitâche d'Exec forme le centre du système : c'est un ensemble de routines qui est à la base du reste du logiciel qu'on trouve dans la ROM. Les développeurs ont essayé d'optimiser Exec au niveau place, performance, facilité d'usage ainsi qu'au niveau création et gestion des listes qui sont les composants de base d'Exec. Toutes les autres parties de la bibliothèque Exec sont basées sur les listes et par conséquent, permettent de bonnes performances sans faire d'accès au système situé en amont.

Exec est le point de départ de tous les autres composants de la ROM, principalement parce qu'elle contrôle les tâches et les interruptions. Chaque composant de la ROM a été conçu de manière à rester indépendant le plus possible ; les programmeurs peuvent choisir quelles bibliothèques utiliser, mais en même temps, ces composants doivent le plus possible partager des ressources et une interface commune. Au niveau du programmeur le système doit être considéré comme un tout.

Séquence présentation

Le diagramme représente les composants de la ROM et leur inter-relations.

ROM

Tout d'abord, on en a déjà parlé, il y a Exec. Exec est destiné à gérer l'environnement et les ressources de l'Amiga pour les différentes tâches qui peuvent résider simultanément en mémoire, avec chaque tâche libre d'envoyer des requêtes au système à n'importe quel moment. Exec fournit également une interface commune entre les applications et différents mécanismes de la ROM. Pratiquement tout le code qui est exécuté dans la machine est au plus bas niveau du système une tâche. Chaque tâche a son propre environnement ; en d'autres termes, chaque tâche paraît contrôler toute la machine sauf pour la mémoire. En effet, Exec n'autorise pas les allocations mémoires directes. Par contre, elle gère la mémoire disponible et fournit des routines qui vont permettre à une application de s'allouer un bloc de mémoire et de le gérer de l'intérieur comme bon lui semble. Enfin, Exec fournit toutes les routines qui permettent un accès uniforme à toutes les bibliothèques et périphériques de l'Amiga.

Un périphérique est un système d'entrées/sorties qui utilise des tâches pour avoir accès à certaines parties du matériel. Par exemple, en utilisant le timer.device, on peut recevoir une interruption ou bien être réveillé d'un état d'attente ("wait state") après une certaine période que l'on spécifie. En utilisant le périphérique console, qui est décrit plus loin, une application peut recevoir des entrées et écrire du texte en sortie de la manière la plus simple comme si elle était connectée sur un simple terminal d'ordinateur.

Une bibliothèque est un ensemble de routines qui résident en ROM, ou qui sont chargées d'après un disque. Ces routines n'ont pas d'adresses fixes, et sont appelées de façon indirecte. Les applications, par conséquent, n'ont pas besoin de connaître l'adresse absolue d'une routine en bibliothèque quand on compile un programme. Plus fort encore : à part pour l'adresse qui contient le pointeur vers la base de données d'Exec, il n'y a pas besoin de connaître aucune adresse absolue dans tout le système.

La bibliothèque graphique (Graphics Support Library), un autre composant important de la ROM, fournit une interface entre le programmeur et les composants graphiques matériels de l'Amiga. Le matériel graphique est extrêmement complexe, mais les routines graphiques éliminent la plus grande partie de cette complexité en transformant des requêtes de rendu des images en écriture systématique dans les registres des composants graphiques. Ces routines servent aussi à la programmation des coprocesseurs spécialisés de l'Amiga. Les programmes peuvent utiliser simplement la bibliothèque graphique pour tracer des lignes et remplir des surfaces ou bien pour exécuter des actions plus complexes telles que accroître l'accès systématique aux composants matériel comme les coprocesseurs et le Copper. Un programme reconnaît les routines graphiques comme des offsets dans une table et doit accéder à la bibliothèque pour pouvoir lire la table.

Intuition est un autre exemple de bibliothèque. C'est un ensemble de routines qui gèrent et fournissent un accès plus convivial aux fonctionnalités multitâches d'Exec, et permettent une interaction plus facile avec les programmes. Intuition utilise la bibliothèque graphique pour créer des environnements graphiques dans lesquels plusieurs applications peuvent coexister.

Séquence axxion (multitâche)

Chaque unité d'exécution (excepté le programme utilisé par le coprocesseur) reçoit son propre environnement ; en fait, tout se passe comme si cet environnement était une machine complète. La tâche reçoit ses propres accès aux registres, ses propres piles, ses propres caractéristiques de process (priorité, status...) et peut également accéder aux systèmes d'entrées/sorties de la machine comme l'affichage graphique et les unités disques, sans avoir à s'occuper des autres tâches qui peuvent avoir besoin d'accéder aux mêmes ressources du système au même moment. Les tâches sont très simples. Ce sont les composants élémentaires exécutables sous Exec. Tout est construit autour des tâches, des programmes les plus simples aux processes systèmes de l'AmigaDOS.

S'ils le désirent, les programmeurs peuvent ignorer la plupart des capacités multitâches de l'Amiga. Si on écrit un programme simple, on n'a pas besoin de s'occuper des autres programmes qui peuvent se partager la mémoire et les ressources matériel. La seule contrainte pour qu'un programme soit parfaitement compatible avec l'environnement multitâche est la suivante : il faut toujours penser à abandonner le contrôle du processeur et des ressources le plus tôt possible, afin que les autres tâches puissent y accéder.

Par exemple, quand on attend un événement utilisateur comme la frappe d'une touche, il est conseillé d'utiliser la fonction Wait() qui fournit un moyen commode de rester en attente tout en laissant les autres programmes tourner jusqu'à ce que l'événement souhaité soit réalisé. Parce que l'Amiga n'a qu'un microprocesseur (68000), et que les tâches se partagent le temps processeur, il n'y a qu'une seule tâche qui puisse être active à la fois. Chaque tâche a un numéro de priorité, qui est un indicateur de son importance. Ces numéros vont de -128 à 127 ; la plupart des tâches tournent avec une priorité moyenne de 0.

La tâche qui a la plus haute priorité prend la main à chaque fois qu'elle le peut, même si ça doit entraîner une interruption du travail de la tâche de plus bas niveau : elle n'aura pas d'état d'attente. Si deux tâches ont la même priorité, et sont prêtes à tourner au même moment, elles se partagent le microprocesseur (c'est le "time-slicing") par tranche de temps de 64 millisecondes. Quand une tâche a terminé son travail et entre en hibernation temporaire, elle abandonne le contrôle de système et appelle la fonction Exec Wait() vue plus haut. L'appel à la fonction inclut des instructions décrivant l'événement qui devra réveiller la tâche.

Séquence d'événement pour ouvrir une tâche :
  • Initialiser un bloc de contrôle de tâche.
    • Allouer une pile à la tâche.
    • Initialiser les variables de pile (SPUpper, SPLower et SPRegister). Attention aux "stack overflow".
    • Initialiser la priorité (optionnel).
    • Donner un nom à la tâche.
  • Créer un port (optionnel) avec CreatPort().
  • Ajouter la tâche au système avec AddTask().
Ceci est un exemple de séquence d'événements nécessaires à l'ouverture et au démarrage d'une tâche. Normalement, l'appel à la fonction est généré par un événement extérieur, annoncé par l'arrivée d'un message ou d'un signal. Quand une tâche "attend", la prochaine tâche d'égale priorité commence à tourner. Quand toutes les tâches de plus haute priorité sont en attente, les tâches de plus basse priorité sont autorisées à prendre la main. Cette mise en hibernation et réveil des tâches est appelé "task switching" et est géré par Exec.

Séquence communications (messages et signaux)

Les tâches communiquent entre elles grâce à des messages et des signaux. Le signal, la plus simple forme de communication interne, est représenté physiquement par 1 bit dans un mot de 32 bits (appelé le "signal-bits word").

Chaque tâche reçoit 32 bits de signaux (donc codables sur un seul mot). Quelques bits de poids faible sont réservés par le système. L'argument de la fonction Wait() est un longword de 32 bits avec un codage des bits correspondant aux signaux que la tâche peut recevoir. Quand une tâche appelle Wait(), cela signifie pour Exec que la tâche attend l'apparition d'un ou de plusieurs des événements qu'elle est susceptible de recevoir. Quand la tâche "se réveille", la fonction Wait() renvoie un argument. Cet argument est un longword avec les bits de signaux qui ont été envoyés à la tâche pour la réveiller.

Avec la fonction AllocSignal(), la tâche oblige ses bits de signaux à identifier les types d'informations qui sont transmis. La tâche peut également attacher un signal à un message qu'elle envoie au système de façon à identifier la réponse de façon claire quand elle arrivera. De plus, les tâches peuvent rendre leurs signaux accessibles aux autres tâches, comme variable globale d'un programme gérant plusieurs tâches ou bien comme information dans un message transitant dans la structure de communication de l'Amiga. Les tâches peuvent communiquer avec une autre en utilisant les signaux, ou la fonction Exec Signal.

Les tâches peuvent aussi utiliser des messages à travers des ports de communication. Chaque tâche connaît les canaux des autres tâches grâce à une variable globale prédéclarée ou grâce à des noms de ports prédéfinis. Il y a plusieurs routines Exec permettant la gestion des ports. Une tâche crée un port en appelant la routine CreatePort() et peut également assigner un nom au port créé. A ce moment, les autres tâches peuvent retrouver le canal à l'aide de la fonction FindPort(). La fonction CreatePort() alloue et initialise de la mémoire ainsi qu'un bit de signal pour le canal nouvellement créé. L'appel à AddPort() va alors installer le nouveau port dans le système.

PutMsg() envoie un message vers une tâche via son port de communication. Une fois que le message est envoyé, on peut choisir entre une réponse immédiate (synchronous I/O) ou différée (asynchronous I/O). Une tâche reçoit des messages en utilisant GetMsg() qui renvoie l'adresse du message ou 0 si aucun message n'a été envoyé.

Séquence allocation (...de mémoire)

Plusieurs routines d'Exec et d'Intuition servent à la gestion de la mémoire RAM (allocation et désallocation).

Les fonctions de base sont les routines Exec AllocMem() et FreeMem(). On utilise AllocMem() pour savoir quel type de mémoire on veut et en quelle quantité (adresse de poids fort ou faible, initialisation à zéro ou non...). FreeMem() restaure la portion d'espace mémoire à son état original.

D'autres routines d'Exec servant à l'allocation permettent de contrôler soi-même la mémoire. D'abord, on s'alloue de la mémoire avec AllocMem(), puis on peut gérer l'intérieur de ce bloc comme on le souhaite à l'aide des routines Allocate() et Deallocate().

Les tâches peuvent utiliser les capacités de gestion de listes d'Exec pour allouer de la mémoire de façon telle que la mémoire soit automatiquement libérée dès la fin de l'exécution de la tâche. Pour faire cela, on peut allouer un bloc mémoire avec un appel à la routine AllocEntry(), puis attacher le bloc de mémoire retourné par AllocEntry() à la zone MemList dans les données du bloc de contrôle de la tâche.

Intuition fournit deux routines de gestion de la mémoire : AllocRemember() et FreeRemember(). Chaque appel à AllocRemember() ajoute de la mémoire à une liste existante de la tâche appelante. Un appel simple à FreeRemember() libère toute la mémoire allouée par des appels à AllocRemember().


[Retour en haut] / [Retour aux articles] [Article suivant]