# Entrées-sorties dans un système à mémoire virtuelle

Gérard Baudet, Jean Ferrié, Claude Kaiser, Jacques Mossière

► To cite this version:

Gérard Baudet, Jean Ferrié, Claude Kaiser, Jacques Mossière. Entrées-sorties dans un système à mémoire virtuelle. [Rapport de recherche] IRIA-RR-011, IRIA. 1973, pp.18. hal-04715939

HAL Id: hal-04715939

https://inria.hal.science/hal-04715939v1

Submitted on 1 Oct 2024

HAL is a multi-disciplinary open access
archive for the deposit and dissemination of sci-
entific research documents, whether they are pub-
lished or not. The documents may come from
teaching and research institutions in France or
abroad, or from public or private research centers.

L'archive ouverte pluridisciplinaire HAL, est
destinée au dépôt et à la diffusion de documents
scientifiques de niveau recherche, publiés ou non,
émanant des établissements d'enseignement et de
recherche français ou étrangers, des laboratoires
publics ou privés.

<figure><img src="image_1.png" /></figure>

Distributed under a Creative Commons Attribution 4.0 International License
RIA
laboria

laboratoire de recherche
en informatique
et automatique

# Entrées-sorties
dans un système
à mémoire virtuelle

G. Baudet, J. Ferrié

C. Kaiser, J. Mossière

18p

Institut de Recherche
d'Informatique
et d'Automatique

Domaine de Voluceau
Rocquencourt
78150 - Le Chesnay
Tél. 954.90.20

Rapport de Recherche n° 11

mars 1973
ENTRÉES-SORTIES DANS UN SYSTÈME A MÉMOIRE VIRTUELLE

G. Baudet, Jean Ferrié, C. Kaiser, J. Mossière

ABSTRACT : Input/Output in a Virtual Memory System

This paper presents an analysis of the relations between virtual memory, file
system, and peripheral devices, in a paged virtual memory system.

Input/Output is considered in the form of information transfers between
files, located in core or secondary storage, and peripheral devices. The I/O
functions rely on mechanisms provided by the system :

- coupling, which defines the contents of the virtual memory in terms
of file pages,

- process synchronizing primitives

The paper gives a complete description of an I/O subsystem, which handles
communications with a card reader, printers and the operator's console.
Some performance measurements are included.

RÉSUMÉ : Entrées-sorties dans un système à mémoire virtuelle*

Les relations entre la mémoire virtuelle, les fichiers et les périphériques
sont présentés dans le cadre d'un système à mémoire virtuelle paginée.

Les entrées-sorties considérées sont des transferts de fichiers (sur
disque ou mémoire centrale) vers des périphériques ou inversement. Ils sont
réalisés de manière à tirer le plus grand parti possible des mécanismes
existants à savoir :

- le *couplage*, opération de définition de la mémoire virtuelle,

- la *gestion des processus* et, les primitives de synchronisation.

L'article décrit complètement un sous-ensemble du système d'entrée-sortie
permettant de gérer lecteurs de cartes, imprimantes et console de l'opérateur.

Les problèmes de performances y sont présentés à partir d'une expérience
de fonctionnement.
# 1. Introduction

Nous décrivons dans cet article la gestion des périphériques du système ESOPE, système implanté à l'IRIA sur un calculateur CII 10070. Nous allons préciser en premier lieu la nature des périphériques mis en jeu, ainsi que les échanges d'informations effectivement gérés.

La caractéristique première d'ESOPE est d'être un système conversationnel, disposant d'une gestion de fichiers sur disques à têtes fixes ; en conséquence, l'accès le plus courant se fait par l'intermédiaire de téléimprimeurs. Si ces organes sont bien adaptés à la manipulation de petites quantités d'information (par exemple édition conversationnelle), il est peu raisonnable de les utiliser pour l'entrée ou la sortie de gros fichiers : c'est notre première motivation pour la mise en place d'un système d'entrées-sorties. De plus, par souci d'efficacité, on ajoute au système un travail de fond (exploitation par train de travaux) qui a besoin lui aussi de périphériques classiques. Le système d'entrées-sorties (SES) est donc conçu comme une extension au système conversationnel, et non comme un système capable d'accepter de gros travaux de gestion.

## En résumé :

Le SES gère les périphériques classiques (imprimantes, lecteur de cartes, bandes magnétiques, disques à têtes mobiles) ; les seuls transferts pris en compte sont les échanges entre un périphérique et un fichier sur disques à têtes fixes.

## La conception du système repose sur les trois idées suivantes :

1) la réalisation de la partie conversationnelle d'ESOPE a imposé le développement de mécanismes appropriés (gestion des processus, des fichiers, allocation de ressources). Pour la réalisation du SES, il faut autant que possible tirer parti des mécanismes existants.

2) le SES doit être efficace. Nous entendons par là que la structure globale du SES doit permettre d'exploiter au mieux le matériel (si deux transferts peuvent se dérouler en parallélisme réel, il n'y a pas de raison de s'en priver) ; l'amélioration des performances par optimisation locale du code objet ne doit venir qu'en second lieu.

3) le SES doit être aussi indépendant que possible du reste du système et avoir un interface bien défini. Il ne s'agit pas ici d'un voeu, mais d'une exigence, car la réalisation du système conversationnel a effectivement précédé celle du système d'entrées-sorties.

En conséquence, l'article est articulé comme suit : après un rappel des outils disponibles dans ESOPE, on montre comment ils ont pu être utilisés dans le SES ; les principes généraux de réalisation sont illustrés par la description d'un sous ensemble gérant un lecteur de cartes et deux imprimantes. Enfin, on développe en conclusion une évaluation du modèle proposé et ses possibilités d'extension.
## 2. Les outils disponibles

Nous rappelons dans ce paragraphe les mécanismes de base du système ESOPE ([1],[2],[3]).

### 2.1 Mémoire virtuelle et couplage

Nous appelons mémoire virtuelle l'ensemble des adresses que peut générer le mécanisme de calcul d'adresse de l'unité centrale. Dans le 10070, cette mémoire virtuelle est divisée en 256 pages de 512 mots ; la transformation adresse virtuelle-adresse réelle se fait par l'intermédiaire de la mémoire topographique.

<figure><img src="image_2.png" /></figure>

On définit l'information contenue en mémoire virtuelle par une application de cette mémoire virtuelle dans l'espace des fichiers. Pour cela, les fichiers sont découpés en articles de même taille que les pages virtuelles et tout article de fichier ne possède à un instant donné qu'un seul support qui est soit une page de mémoire principale, soit une page de mémoire secondaire.

Ainsi, l'application

* topographie : mémoire virtuelle → support physique
est obtenue par le produit de deux applications :

* couplage : mémoire virtuelle → fichier

* implantation de fichier : fichier → support physique

De ces deux applications, l'une, le couplage est mise à la disposition du programmeur qui peut ainsi composer à partir des fichiers sa mémoire virtuelle, l'autre est définie par le système. Par ailleurs, la mémoire topographique est utilisée pour accélérer l'accès à l'information lorsque le support d'un article couplé à une page virtuelle est une page de mémoire centrale.

Dans ces conditions, le chemin d'accès à l'information est le suivant :
<figure><img src="image_3.png" /></figure>

Nous remarquons :

1) qu'un couplage n'entraîne aucun transfert d'information, mais simplement la mise à jour d'une table du système.

2) que le transfert d'information de la mémoire secondaire vers la mémoire principale n'intervient qu'après un déroutement pour défaut de page.

3) que la notion de transfert entre fichier et mémoire virtuelle n'a pas de sens : la mémoire virtuelle n'a pas de support, ce n'est qu'un moyen d'accès aux fichiers (et c'est le seul).

## 2.2 Gestion des processus

Nous appelons *processus* un programme en cours d'exécution. Le système ESOPE est écrit sous la forme d'une famille de processus parallèles dont la coopération est réglée par l'emploi de sémaphores et des primitives P et V de synchronisation. L'implantation des primitives P et V inclut l'allocation de l'unité centrale.

## 2.3 Allocation des ressources

On distingue deux catégories de processus :

- les processus qui s'exécutent sans topographie en mémoire physique, et en général en mode maître. Leur code est résident.

- les processus qui utilisent la mémoire virtuelle. Leur code est chargé sur la base de la page à la demande. On utilise pour détecter les défauts de page les dispositifs de protection virtuelle de la 10070, qui ne fonctionnent qu'en mode esclave ; tout processus utilisant la topographie s'exécute donc en mode esclave.

Les processus virtuels sont regroupés en classes ou usagers (la plupart des usagers correspondent à un client conversant avec le système à l'aide d'un téléimprimeur).

Les différentes ressources (mémoire virtuelle, mémoire centrale, unité centrale) sont allouées à l'usager plutôt qu'au processus. L'unité centrale est allouée par priorité aux processus physiques prêts à s'exécuter.
## 2.4 Insuffisance des mécanismes précédents

Dans la version purement conversationnelle d'ESOPE, les pages de mémoire sont soit résidentes, et elles sont alors fixées une fois pour toutes au démarrage du système (et en général non accessibles par l'intermédiaire de la mémoire topographique), soit non-résidentes, c'est-à-dire que leur contenu peut êtrevidé sur disque pour les besoins de l'allocation de ressources.

Lors de l'implantation du SES, si l'on désire utiliser pour l'accès aux fichiers les facilités offertes par la mémoire virtuelle, il va falloir résoudre le problème de l'emplacement des tampons : si on les place dans la zone résidente, comment va-t-on y accéder à partir d'une mémoire virtuelle ? Si on les place en mémoire virtuelle, comment va-t-on les immobiliser en mémoire centrale pendant la durée des transferts ?

## 3. Schéma de réalisation du SES :

En plus des entrées-sorties proprement dites, nous avons à faire face à des problèmes :

- de synchronisation car les différents organes d'entrée-sortie peuvent fonctionner en parallèle,

- d'accès aux fichiers car les transferts pris en compte par le SES ont toujours pour source ou pour destination un fichier sur disques,

- d'allocation de ressources car les unités d'échange trouvent leurs commandes et leurs données en mémoire centrale ; il faut donc y charger les pages d'informations à transférer.

### 3.1 Problèmes de synchronisation. Le schéma Producteur-consommateur ([4])

Le schéma connu sous le nom de "producteur-consommateur" permet de programmer efficacement la coopération de deux processus évoluant avec des vitesses quelconques. Nous l'avons utilisé systématiquement.

Considérons deux processus cycliques, le producteur P et le consommateur C qui se communiquent des messages par l'intermédiaire d'une zone de mémoire commune. Plus précisément :

• le producteur exécute une phase de calcul, puis dépose un message dans un tampon et recommence le cycle,

• le consommateur prélève un message dans un tampon, le consomme et recommence le cycle,

• on suppose que les messages ont une taille fixe et que la zone de mémoire commune a une capacité fixe de N tampons.

La solution doit répondre aux contraintes suivantes :

1) le producteur ne peut pas placer un message si tous les tampons sont pleins ; il doit attendre

2) le consommateur ne peut pas prélever un message si tous les tampons sont vides ; il doit également attendre

3) si le producteur est en attente pour tampon plein, il doit être prévenu dès que cette condition cesse d'être vraie. Il en est de même pour le consommateur et la condition tampon vide.

En utilisant 2 sémaphores, l'algorithme des deux processus s'écrit (en supposant en outre que les tampons sont chainés circulairement, et consommés dans l'ordre de production)
sémaphore n-plein = 0, n-vide = N ;
integer tête, queue = 0 ;

Producteur

A : Produire un message
P(n-vide) ;
tampon (queue) := message ;
queue := queue + 1 modulo N ;
V(n-plein) ;
goto A ;

Consommateur

B : P(n-plein) ;
message := tampon (tête) ;
tête := tête + 1 modulo N ;
V(n-vide) ;
consommer le message ;
goto B ;

Notons que, dans la pratique, la programmation se complique : les deux
processus coopèrent pendant un temps fini et il faut programmer l'arrêt
.et éventuellement la destruction) des deux processus.

3.2 Accès aux fichiers :

Tous les transferts que nous considérons ici font intervenir à une
extrémité des accès à un fichier sur RAD. A priori, deux solutions sont
envisageables :

1) soit développer un mécanisme d'accès ad hoc, en demandant directement les entrées-sorties au module de gestion des disques,

2) soit utiliser, comme n'importe quel autre usager, le mécanisme
du couplage.

Nous avons rejeté immédiatement la première solution, qui conduit
à des modifications du système conversationnel (en plus de la création
de nouveaux mécanismes). Examinons les contraintes apportées par la
seconde :

Comme les sous-programmes chargés de lire les articles de
fichier en utilisant le couplage doivent s'exécuter en virtuel et
en mode esclave, c'est-à-dire être inclus dans un usager d'ESOPE ,
comme l'autre extrémité du transfert fait intervenir des unités
d'échange ne connaissant que des adresses physiques, nous devons mettre
en place un mécanisme de communication entre la mémoire virtuelle et la
mémoire physique.

3.3 Collage de pages virtuelles

Dans la version d'ESOPE ne comprenant que des usagers conversation-
nels, à une page de mémoire virtuelle ne correspond aucun support. Par
l'opération de couplage on peut lui faire correspondre un article de
fichier qui possède un support (qui peut être indifféremment une page de
disque ou une page de mémoire centrale, l'allocation de ressources fixant
les transitions de l'une à l'autre).

L'immobilisation de pages de fichier en mémoire centrale imposant une
modification de l'allocation de ressources, nous avons préféré la
solution suivante :

la mémoire virtuelle est partagée en 3 zones délimitées par deux
repères MIN et MAX

O MIN MAX 255

Les pages virtuelles comprises entre MIN et MAX sont couplables et les
articles couplés transitent entre la mémoire centrale et la mémoire
secondaire.

Les autres pages sont ou bien inaccessibles, ou bien *collées* à des
pages physiques (c'est-à-dire qu'une page virtuelle de numéro inférieur
à MIN ou supérieur à MAX a effectivement comme support une page de
mémoire physique). Deux primitives particulières, allouer-tampon et libérer-tampon, permettent le collage et le décollage des pages virtuelles ; la fixation des bornes MIN et MAX par le processus premier évite un emploi abusif de ces primitives.

Avec ce mécanisme, le passage d'un article de fichier (a, f) de son support à une page physique se programme très simplement en mémoire virtuelle :

soit $PV1, PV2$ ($MIN \leq PV1 \leq MAX < PV2$) 2 pages virtuelles

coupler ($PV1$, a, f) ;
allouer-tampon ($PV2$)
recopier $PV1$ dans $PV2$ ;

La primitive allouer-tampon fournit de plus le numéro de la page physique effectivement collée à la page virtuelle ; on peut utiliser ce numéro pour adresser la page à partir d'un processus s'exécutant en adresses physiques.

### 3.4 Structure générale du Système d'Entrée-Sortie.

Pour chaque transfert fichier→ périphérique, on désire tout d'abord utiliser le parallélisme entre le disque et le périphérique : 2 processus coopéreront donc à sa réalisation : l'un, le *facteur* est attaché au disque, l'autre, le *pilote* au périphérique ; la *coopération* entre les deux processus suit le schéma producteur consommateur.

Le processus attaché au disque s'exécute en virtuel et en mode esclave, de façon à pouvoir exécuter des primitives de fichier et des couplages ; le processus attaché au périphérique doit s'exécuter en mode maître pour pouvoir employer les instructions privilégiées d'entrée-sortie et donc en adresses physiques. La communication de données d'un processus à l'autre se fait par l'intermédiaire de pages virtuelles collées par le facteur : le *pilote* trouve les adresses physiques de ces pages dans une table située à des adresses physiques et virtuelles fixes (les pages 0 et 1 de chaque usager sont collées une fois pour toutes).

Quand un *pilote* a lancé une entrée-sortie (SIO), il se bloque derrière un sémaphore SSIO en attendant la fin du transfert; il sera réveillé par un $V(SSIO)$ exécuté dans le traitement de l'interruption d'entrée-sortie.

Signalons enfin la présence de deux processus supplémentaires, s'exécutant en mode maître et en physique.

1) le processus de gestion de la console de l'opérateur, ou *servant*. Ce processus est activé soit par l'interruption du panneau de commande, soit par un *pilote* demandant une intervention de l'opérateur (erreur de transfert, fin de papier,...). Le *pilote* attend la fin de l'intervention bloqué derrière un sémaphore SOP : le *servant* exécute un $V(SOP)$ en conséquence d'une commande introduite par l'opérateur.

2) le processus "chien de garde" destiné à protéger le système contre certaines erreurs (interruption non envoyée par le périphérique ou perdue par le système). Pour cela, on note à chaque lancement d'entrée-sortie l'heure correspondante. Le processus chien de garde, activé périodiquement vérifie qu'une entrée-sortie n'a pas été "lancée depuis trop longtemps" ; s'il en trouve une, il la termine (HIO) et force un $V(SSIO)$, avec un message d'erreur en direction du *pilote*.

**Nota** : Pour économiser la place occupée par les tables de description des mémoires virtuelles, on regroupe l'ensemble des facteurs dans une seule
mémoire virtuelle, celle d'un usager chargé des entrées-sorties.

# 4. Description d'un sous-système d'entrée-sortie

## 4.1 Généralités

Nous décrivons dans ce paragraphe de façon un peu plus détaillée la gestion du lecteur de cartes et des imprimantes. Par souci d'allègement, nous avons rejeté en annexe les algorithmes des processus d'entrée-sortie.

Pour homogénéiser la programmation, nous avons introduit diverses variables booléennes définissant l'état d'un périphérique, ou plutôt du couple facteur-pilote. Ce sont :

- ACTIF : le facteur et le pilote coopèrent au transfert d'un fichier

- AVORT : cet état est transitoire, l'opérateur force un arrêt prématuré du transfert ; cet arrêt ne peut pas être instantané car les processus doivent réinitialiser leurs données

- VERROU : le facteur et le pilote du périphérique sont bloqués ou vont l'être dès la fin du transfert en cours. Le blocage, demandé par l'opérateur, subsiste jusqu'à ce que ce dernier demande le déblocage

- ATTEND : le pilote a détecté une anomalie et l'a signalée à l'opérateur dont il attend la réponse.

Des informations supplémentaires sont associées à chaque périphérique et en particulier :

- une zone REPONSE contient des informations fournies par les instructions d'entrée-sortie.

- une zone HSIO contient l'heure à laquelle a été déclenchée l'entrée-sortie en cours. (si le périphérique est au repos, HSIO est égal à 0)

## 4.2 Gestion du lecteur de cartes

La lecture des cartes est déclenchée par l'opérateur (par l'intermédiaire du processus servant) ; la lecture est terminée soit à la rencontre d'une carte !FIN, soit lorsque l'opérateur décide d'avorter le transfert.

Dans le schéma producteur-consommateur, le pilote est le producteur, le facteur le consommateur.

Le pilote, qui doit arrêter la lecture sur une carte !FIN, ne peut utiliser le chaînage de commandes et doit être activé après chaque lecture de cartes (en conséquence d'une interruption fin de transfert ou erreur de transmission).

Le facteur, qui est activé chaque fois que le pilote a rempli un tampon d'une page, est chargé de gérer les fichiers lus. Pour cela, tout paquet de cartes introduit au lecteur doit être précédé d'une carte de commande indiquant le nom du fichier et le nom du client propriétaire ; une option particulière permet la transmission du fichier au travail de fond.

**Remarque** : pour limiter les conséquences d'erreurs de manipulation dues à l'opérateur, on a décidé que le lecteur ne détruirait jamais de fichier et ne pourrait qu'en créer de nouveaux.
## 4.3 Gestion des Imprimantes

Les demandes d'impression de fichier sont déposées dans un fichier spécial, la boite aux lettres. Deux processus facteurs, les imprimeurs, y prennent ces demandes qu'ils traitent en relation avec deux pilotes d'imprimante.

<figure><img src="image_4.png" /></figure>

valeurs initiales des sémaphores : SPRODPERIPH 1 = SPRODPERIPH 2 = N ;
SCONSPERIPH 1 = SCONSPERIPH 2 = 0 ;
SIMP = SSIO 1 = SSIO 2 = 0 ;

La boite aux lettres est organisée en tampon circulaire ; l'exclusion mutuelle de son accès est assurée par sémaphore. Quand un usager trouve la boite aux lettres pleine, on lui renvoie un message d'erreur (pour ne pas bloquer un usager conversationnel pendant un temps qui peut être très
long).

Pour la réalisation du transfert, le facteur joue le rôle du producteur, le pilote du consommateur. Pour diminuer le nombre d'interventions du pilote et alléger ainsi la charge de l'unité centrale, on décide d'utiliser systématiquement le chaînage de commandes pour obtenir le transfert de plusieurs lignes avec une seule instruction SIO. En conséquence :

- chaque tampon contient n lignes et le programme canal correspondant.

- la dernière commande, et elle seule, génère une interruption "fin de transfert" qui provoque le réveil du pilote bloqué derrière un sémaphore,

- en cas d'erreur de transmission, on demande dans chaque commande l'arrêt immédiat du transfert et une interruption de "fin anormale" qui réveille le pilote.

**Remarque** : pour simplifier le premier organigramme donné en annexe, nous supposons que les interruptions "fin de transfert" et "fin anormale", qui sont toutes deux demandées dans la dernière commande, sont exclusives l'une de l'autre, (ce qui n'est pas le cas dans la 10070).

## Conclusion

Les performances du SES d'ESOPE peuvent être évaluées sous l'angle des entrées-sorties seules ou en fonction de l'augmentation du temps de réponse aux utilisateurs conversationnels.

Les résultats ci-dessous, comparant ESOPE à d'autres systèmes d'exploitation du CII 10070, prouvent largement l'efficacité des mécanismes généraux employés :

<table><thead><tr><th></th><th>BPM vide</th><th>BPM chargé</th><th>SIRIS 7 vide</th><th>ESOPE vide</th><th>ESOPE chargé</th></tr></thead><tbody><tr><td>Entrée d'un fichier de 2800 cartes</td><td>2mn 24s + 1mn</td><td>2mn 30s + 1 mn</td><td>2mn 18 s + ?</td><td>2 mn 16s</td><td>2 mn 16 s</td></tr><tr><td>Impression du même fichier</td><td>5mn 11s</td><td></td><td>4mn 09 s</td><td>4 mn 02 s</td><td></td></tr></tbody></table>

**Nota** : Les temps indiqués pour BPM et SIRIS 7 sont décomposés en temps d'entrée des cartes dans la zone des symbionts (2 mn environ) et en temps de transfert du symbiont vers le fichier (1 mn environ). ESOPE n'a pas de zone symbiont intermédiaire.

Le temps de réponse du système aux utilisateurs conversationnels, mesuré assez grossièrement avec une charge moyenne (de 4 à 10 usagers), augmente sensiblement (de 1,1 s à 1,4 s en moyenne) lorsque le SES fonctionne sans arrêt.

L'étude du temps de réponse sera reprise avec un simulateur de charge fournissant des conditions d'expérience reproductibles. Nous essaions de l'améliorer par les modifications suivantes :

- changement de la priorité de l'usager SES (actuellement le plus prioritaire).

- limitation du nombre de pages physiques occupées par le SES : les
pages libérées par un usager sont rendues au système (listes des pages libres ou quasi libres) qui les chaîne en queue de liste pour faciliter la récupération en mémoire centrale des pages fréquemment utilisées (3). Comme la probabilité de récupération des pages du SES est négligeable, on peut au contraire les mettre en tête de liste, ce qui entrainera leur réutilisation plus rapide, par le SES éventuellement, et limitera le nombre de pages physiques occupées par des fichiers en entrée ou en sortie.

Le modèle que nous avons décrit, utilisable sans changement pour toute unité de liaison simple, se complète de deux manières :

- étude d'un pilote pouvant prendre en compte certaines actions, rebobinage, positionnement de bras, pendant le transfert d'information (cas de plusieurs bandes ou disques par unité de liaison),

- étude d'une procédure qui chez chaque usager remplit un rôle analogue au facteur et qui, une fois l'allocation de périphérique résolue, sert d'intermédiaire entre le pilote et la mémoire virtuelle de l'usager (et non un fichier). Cette procédure permet de traiter de gros fichiers sur bande ou sur disque amovible sans avoir à les ranger sur les disques à tête fixes.

L'emploi systématique des mécanismes présentés s'est révélé très rentable globalement et a de plus facilité considérablement la conception et la mise au point du système.

## Bibliographie

[1] Présentation générale du système ESOPE

[2] Notion d'espace virtuel dans le système ESOPE

[3] Allocation de ressources dans le système ESOPE
C. BETOURNE, J. BOULENGER, J. FERRIE, C. KAISER, S. KRAKOWIAK et J. MOSSIERE.
Congrès d'Informatique de l'AFCET, Paris, Septembre 1970

[4] Synchronization of communicating processes
A. N. HABERMANN, communications of the ACM, Mars 1972.

[5] CII 10070 - Manuel de Référence.

[6] Entrées-Sorties d'ESOPE et usager PTT
G. BAUDET, J. FERRIE, C. KAISER et J. MOSSIERE
Note de travail IRIA, ESOPE/A/021, 1972.
# Annexe

## Programmation des périphériques

Nous donnons ici, en pseudo-algol, la description algorithmique des processus pilote et facteur associés au lecteur et aux imprimantes, ainsi que les programmes d'interruption correspondants.

### I - Lecteur de cartes.

#### A - Le Pilote du lecteur :

LECTEUR : P(SPILLECT) ;
          PILACT(I) := true ; // Commentaire n° 1 //
          n := 0 ; // n est l'indice du tampon courant //
TAMPON : P(SPRODPERIPH(I)) ; // Sémaphore de production, initialisé à N //
          FIN(n) := false ; NOMBRE(n) := 0 ; // Commentaire n° 2 //
          l := 0 ; // l est l'indice de la ligne courante //
LIGNE : P(SAVORT(I)) ; // Commentaire n° 3 //
          if AVORT (I) then
              begin // Transfert avorté par l'opérateur //
                  V(SAVORT(I)) ;
                  goto FIN ;
              end ;
          P(SMUTEX) ; // Commentaire n° 4 //
          SIO(Periph n° I, LIGNE(1)) ;
          if "OK" then
              begin // Le lecteur n'est pas en état de marche //
                  V(SMUTEX) ;
                  ATTEND(I) := true ;
                  V(SAVORT(I)) ; // Commentaire n° 3 //
                  message à l'opérateur ;
                  P(SOP(I)) ; // Le pilote attend l'opérateur //
                  goto LIGNE ;
              end ;
          HSIO(I) := PENDULE ;
          V(SMUTEX) ; V(SAVORT(I)) ; // Commentaire n° 3 et 4 //
          if "manuel" then message à l'opérateur ;
          P(SSIO(I)) ; // Commentaire n° 5 //
          P(SAVORT(I)) ;
          if AVORT(I) then
              begin
                  V(SAVORT(I)) ;
                  goto FIN ;
              end ;
          if "erreur de transmission" then
              begin
                  ATTEND(I) := true ;
                  V(SAVORT(I)) ;
                  message à l'opérateur ;
                  P(SOP(I)) ;
                  if AVORT(I) then goto FIN ;
                  if REPONSE(I) = "reprendre" then goto LIGNE ;
              end
          else
              V(SAVORT(I)) ;
          if LIGNE(1) = "carte !FIN" then goto FIN ;
NOMBRE(n) := NOMBRE(n) + 1;
if "tampon plein" then
    begin
        V(SCONSPERIPH(I)); // Sémaphore de consommation //
        n := n + 1 modulo N;
        goto TAMPON;
    end;
1 := 1 + 1; goto LIGNE;
FIN:
    PILACT(I) := false; // Commentaire n° 1 //
    FIN(n) := true;
    V(SCONSPERIPH(I));
    goto LECTEUR; // Retour à la position de référence //

## Commentaires :

1. Le pilote se place sous la surveillance du chien de garde dès qu'il est lancé et s'en retire dès que la dernière carte est lue (PILACT est une variable globale).

2. Chaque tampon m ($0 \le m \le N-1$), fourni par le pilote au facteur, contient en plus des images des cartes lues :

* Un indicateur, FIN(m), mis à "vrai" lorsque le tampon correspondant est le dernier (le dialogue producteur-consommateur est alors terminé),

* Un compteur, NOMBRE(m), indiquant le nombre de cartes lues dont l'image se trouve dans le tampon correspondant.

3. Cette section critique est nécessaire pour que le servant ne puisse pas avorter le transfert entre le test de l'AVORT par le pilote et le lancement du SIO. D'autre part, dans le cas d'un refus du SIO l'AVORT ne doit pas être positionné avant que l'indicateur ATTEND ne le soit (le pilote resterait bloqué derrière SOP(I)).

4. Cette section critique est réalisée par masquage contre toutes les interruptions, et a pour but de rendre indivisible le lancement du SIO et la mise à l'heure de HSIO(I) ; si l'interruption de fin de transfert arrivait, en effet, entre ces deux actions, sans que la séquence d'instructions ne soit masquée, le contenu de HSIO(I) ne serait pas "homogène" (voir le commentaire n° 5).

5. Traitement d'une interruption en provenance du lecteur :

IT d'E/S
pour le lecteur → P(SMUTEX);
AIO;
REPONSE(I) := "indicateurs fournis par le AIO";
HSIO(I) := O;
V(SSIO(I));
V(SMUTEX);

## B - Facteur du lecteur :

LECTEUR: P(SLECTEUR);
if VERROU(I) then
    begin // Le lecteur est verrouillé //
        P(SBLOC(I)); V(SBLOC(I)); // Commentaire n° 2 //
    end;
    allocation des pages-collées;
    V(SPILLECT); // Lancement du pilote //
    ETAT := O;
n := 0; // variable locale à ce processus //
TAMPON : P(SCONSPERIPH(I)); // Sémaphore de consom-
mation, initialisé à 0 //

1 := 0;

for i := NOMBRE(n) step - 1 until 1 do
begin

if AVORT(I) then
  begin
    if ETAT = 1 then RAZ-du-fichier-en-cours ;
    while not FIN(n) do
      begin // Consommation de tous les
      V(SPRODPERIPH(I)) ; // tampons, sauf
                            // le dernier
      n := n + 1 modulo N ;
      P(SCONSPERIPH(I)) ;
      end ;
    ETAT := 2 ;
    goto FIN ;
  end ;

if LIGNE(1) = "Carte de commande" then
  begin

if ETAT = 1 then catalogage -du-fichier-en-cours
  else ETAT := 1 ;
  analyse ;
  if "erreur" then
    begin
      message-à-l'opérateur ;
      ETAT := 2 ;
    end
  else création-d'un-fichier-de-travail ;
end

else
if ETAT = 1 then rangement (LIGNE(1))
else

if ETAT = 2 then
  begin // Il n'y a pas de carte de
          // commande
  message-à-l'opérateur ;
  ETAT := 2 ;
end ;

l := l + 1 ;
end ;

// En sortant de la boucle for toutes les lignes du
tampon courant ont été traitées //

if not FIN(n) then
  begin // Ce n'est pas le dernier tampon //
  V(SPRODPERIPH(I)) ;
  n := n + 1 modulo N ;
  goto TAMPON ;
end ;

FIN : V(SPRODPERIPH(I)) ; // Libération du dernier tampon//
if ETAT = 1 then catalogage -du-fichier-en-cours ;
Libération-des-pages-collées ;
P(SAVORT(I)) ;
ACTIF(I) := AVORT(I) := false ;
V(SAVORT(I)) ;
goto LECTEUR ; // Retour à la position de référence//
## Commentaires :

1. Dans ce schéma ETAT est une variable entière qui a pour significations :

0 - La ligne courante doit être une carte de commande.

1 - Il y a un fichier créé : la ligne courante doit y être rangée si ce n'est pas une carte de commande.

2 - Il n'y a pas de fichier créé (carte de commande erronée ou absente) : la ligne courante n'est pas rangée tant que ce n'est pas une carte de commande.

2. La variable VERROU(I) est utilisée pour contrôler le verrouillage du périphérique I et le sémaphore SBLOC(I) pour bloquer le facteur associé à ce périphérique lorsque le verrouillage a été demandé par l'opérateur au servant. Les actions effectuées par le servant sont les suivantes (SBLOC(I) a pour valeur initiale 1) :

```
VERROU : if VERROU(I) then "erreur" ; DEVERROU : if VERROU(I) then "erreur" ;
P(SBLOC(I)) ; VERROU(I) := true ; VERROU(I) := false ;
V(SBLOC(I)) ;
```

## II - Imprimante

### A - Facteur de l'Imprimante

```
IMPRIMEUR : P(SIMP) ;
           if VERROU (I) then
               begin
                   V(SIMP) ; // indique que le message n'est pas consommé //
                   P(SBLOC(I)) ; // voir le commentaire n° 2 du lecteur //
                   V(SBLOC(I)) ;
                   goto IMPRIMEUR ;
               end ;

ACTIF(i) := true ;
           P(SMUTEXBAL) ; // SMUTEXBAL protège la boite au lettre //
           prendre un message dans la boite aux lettres ;
           V(SMUTEXBAL) ;
           ouvrir le fichier à imprimer ;
           coupler son premier article ;
           allouer-tampon ; // colle N pages en mémoire pour servir de tampons //
           PILACT(I) := true ; // désormais le pilote est actif pour le chien de garde //
           n := m := -1 ; // indices de tampon courant //

B : P(SPRODPERIPH(I)) ; // sémaphore de production initialisé à N //
                          n := n + 1 modulo N ;

if AVORT (I) then
               begin
                   FIN(n) := true ; // commentaire n° 1 //
                   goto B1
               end ;

préparer un tampon ; // commentaire n° 1 //
                   FIN(n) := if fin-de-fichier then true else false ;

B1 : V(SCONSPERIPH(I)) ; // active une phase de consommation //
                          if ¬ FIN(n) then goto B ;
                          P(SFIN(I)) ; // commentaire n° 2 //
```
libérer-tampon ; // restitue les pages collées //
fermer le fichier à imprimer ;
P(SAVORT(I)) ;
ATTEND(I)) := ACTIF(I) := AVORT(I) := PILACT(I) := false ;
V(SAVORT(I)) ;
goto IMPRIMEUR ;

## Commentaires :

1. Le tampon n ($0 \le n \le N-1$) fourni par le facteur au pilote contient toute l'information dont le pilote a besoin

- un booléen FIN(n) pour signaler que ce tampon est le dernier du fichier imprimé

- une suite de commandes formant le programme canal

- une suite de lignes à imprimer.

2. Le dialogue producteur-consommateur se produit normalement tant qu'il reste des lignes à imprimer. Quand il n'y en a plus, l'imprimeur attend que le pilote ait fini d'utiliser les derniers tampons avant de détruire ceux-ci.

Cette attente est contrôlée par SFIN(I)(valeur initiale 0)

Les pages collées sont rendues au moniteur, ce qui permet de n'im-mobiliser de la mémoire que s'il y a effectivement impression.

## B - Pilote de l'Imprimante

L0 : P(SCONSPERIPH(I)) ; // active phase de consommation //
m := m + 1 modulo N ;
commande := première commande du tampon ;

L1 : P(SAVORT(I)) ;
    if AVORT(I) then
        begin // commentaire n° 1 //
            V(SAVORT(I)) ;
            goto L3
        end ;
    P(SMUTEX) ;
    SIO (Périph n° I, commande) ;
    if "OK" then
        begin // commentaire n° 2 //
            V(SMUTEX) ;
            ATTEND(I) := true ;
            V(SAVORT(I)) ;
            message-opérateur ; // imprimante non opérationnelle //
            P(SOP(I)) ;
            goto L1
        end ;
    HSIO(I) := PENDULE ; // commentaire n° 3 //
    //
    V(SMUTEX) ;
    V(SAVORT(I)) ;
    if "manuel" then message-opérateur ;

L2 : P(SSIO(I)) ; // commentaire n° 6 //
P(SAVORT(I)) ;
    if AVORT(I) then
        begin // transfert avertié par l'opérateur //
            V(SAVORT(I)) ;
            goto L3
        end ;
```pascal
if fin-anormale then // commentaire n° 4
  begin
    ATTEND(I) := true;
    V(SAVORT(I));
    message-opérateur; // imprimante en erreur
    P(SOP(I));
    if AVORT(I) then goto L3;
    if REPONSE(I) = "reprendre" then
      begin // reprise de l'entrée-sortie
        TIO (Périph. n° I);
        commande := commande-en-cours;
      end
    else
      begin // on ignore l'erreur et on continue
        TIO (Périph. n° I);
        commande := commande-en-cours + 1;
      end;
    goto L1;
  end;
// on traite ici le cas de la fin de transfert des 1 lignes
V(SAVORT(I));
```

L3: if FIN(m) then V(SFIN(I)); // commentaire n° 5
V(SPRODPERIPH(I)); // active phase de production du facteur
 goto L0;

## Commentaires :

1. Si l'opérateur a avorté la sortie du fichier, alors l'opération d'entrée-sortie est sautée et le pilote consomme "à vide" les tampons pleins qui lui ont éventuellement été fournis par le facteur ; il se repositionne ensuite à son état de référence derrière le sémaphore SCONSPERIPH(I).

2. L'imprimante se trouve à l'état non opérationnel. Un message est passé à l'opérateur qui pourra ou relancer le transfert ou l'avorter.

3. Le transfert a été accepté. HSIO(I) est remis à l'heure pour permettre au processus chien de garde de contrôler périodiquement si l'interruption de fin de transfert n'a pas été perdue. Lorsque le chien de garde détecte le mode manuel il remet HSIO(I) à l'heure.

4. Une erreur s'est produite, au cours de l'impression d'une ligne entraînant du même coup l'arrêt de l'imprimante. Le pilote signale l'erreur à l'opérateur qui peut :

- soit avorter la sortie du fichier

- soit continuer à partir du point où en était resté le transfert

- soit reprendre la ligne défectueuse en cours d'impression.

5. Dans le cas où le tampon traité est le dernier, le pilote réveille le facteur par la primitive V(SFIN(I)).

6. Le programme d'interruption est identique à celui du lecteur. Une seule interruption est envoyée lorsque toutes les lignes du tampon ont été imprimées.

## Remarque :

Pour plus de détails sur les instructions d'entrée-sortie du 10070 et sur la programmation du SES, on pourra se reporter aux références [5] et [6].