Programmation Système 21 mai 2003 Documents autorisés Durée : 2 heures
A - Problème de mémoire virtuelle
Dans cet exercice, la gestion de la mémoire virtuelle est réalisée à l’aide d’une table des pages par processus. Le nombre d’entrées dans cette table est limité à 8 et une entrée est composée d’un numéro de page physique et de 3 bits : bit1 = 1 : indique que la page physique correspondante est présente en
mémoire.
bit2 = 1 : indique que la page correspondante a été modifiée. bit3 = 1 : indique que la page correspondante a été accédée.
Question 1 : Recopiez et remplissez le tableau suivant lorsque les adresses virtuelles et physiques sont sur 8 bits, 16 bits ou 32 bits :
8 bits 16 bits 32 bits
Nombre de bits pour coder le numéro de page virtuelle Taille d’une page physique Taille maximum de mémoire physique du processus
Question 2 : Voici la table des pages d’un processus à un instant donné. Ce processus s’exécute en mode 8 bits.
bit de page présente 1 1 1 1 1 0 0 0
bit de page modifiée 0 0 0 1 1 0 0 0
Publicité
bit de page accédée 1 1 1 1 1 0 0 0
numéro de page physique
7 6 5 4 3 0 0 0
Donnez, lorsqu’elles existent, les adresses physiques correspondant aux 16 adresses virtuelles suivantes : 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF
Question 3 : Au cours de son exécution, un processus accède successivement aux numéros de pages suivants : 0, 1, 4, 2, 0, 1, 3, 0, 1, 4, 2, 3. Ce processus s’exécute seul sur la machine et il ne reste que 3 pages libres en mémoire physique. L’algorithme de libération des pages est de type « premier arrivé, premier enlevé » (FIFO). Donnez sous forme de tableau la suite des pages présentes en mémoire et calculez le nombre de défauts de pages.
Même question si il ne reste que 4 pages libres en mémoire physique.
Que peut-on constater de particulier ?
Question 4 :
Dans le cas d’un adressage sur 8 bits, une personne a remarqué qu’une entrée de la table des pages était codée sur moins de 8 bits et a proposé d’utiliser les bits libres pour coder le numéro de page physique. Expliquez en 3 lignes l’effet de cette possibilité. Est-ce réaliste ?
B – Problème de création de processus
Soit le fichier /user/toto contenant la chaîne de caractères : abcdefghijklmnopqrst
Publicité
On se propose d’étudier le programme suivant :
main() { int PID; int fd; char buffer[20];
fd = open("/user/toto", O_RDWR); read(fd, buffer, 10);
print(buffer);
PID = fork(); if (PID == 0) { read(fd, buffer, 5); print(buffer); } else { read(fd, buffer, 5); print(buffer); } }
Les fonctions open() et read() sont les appels systèmes vus en cours. La fonction print() affiche sur le terminal le contenu du buffer passé en paramètre. On remarque que comme le fichier est ouvert AVANT l'appel à la fonction fork(), les structures internes au noyau utilisées pour l'accès au fichier sont PARTAGEES par le processus père et le processus fils.
Question 1 : Donnez l'enchaînement des fonctions exécutées par le processus père et l'enchaînement des fonctions exécutées par le processus fils.
Question 2 : En exécutant plusieurs fois ce programme, on constate qu'il produit 2 affichages différents. Donnez ces 2 affichages.
Question 3 : Expliquez comment ces affichages sont produits et pourquoi ils sont différents Le programme précédent est modifié dans le but d'utiliser le début du fichier /usr/toto comme zone de communication entre les 2 processus. Le processus père sera en charge de lire des données sur un capteur et de les écrire au début du fichier, et le processus fils sera en charge de lire ces données en début de fichier puis de les traiter et les afficher. On sait que le traitement des données est plus long que l’acquisition des données, et que donc le processus fils ne trouvera pas 2 fois de suite les mêmes données dans le fichier.
Le programme devient :
main() { int PID; int fd;
Publicité
fd = open("/user/toto", O_RDWR);
read(fd, buffer, 10); print(buffer);
PID = fork(); if (PID == 0) { do { lseek(fd, 0, SEEK_SET); count = read(fd, buffer, 5); if (count == 5) { traiter_données(buffer); print(buffer); } } while (1) } else { ??????? } }
Question 4 : En prenant exemple sur la boucle de traitement du processus fils, écrire la boucle de code du processus père. Les données seront lues grâce à la fonction lire_capteur(buffer) qui lit 5 caractères et les place dans la variable buffer.
Question 5 : Le code ci dessus ne fonctionne pas bien. En effet, on constate que de temps en temps, le processus fils ne lit pas le début du fichier (caractères 0 à 4) mais lit les caractères 5 à 9 du fichier.
Expliquer comment cela est possible. Identifiez la ou les sections critiques. Proposez une solution à ce problème à l'aide de sémaphores que vous manipulerez avec les fonctions init(semaphore), P(semaphore), V(semaphore) vues en cours.
Question 6 : On souhaite maintenant modifier le programme ci dessus pour que les 2 boucles infinies s'arrêtent sur réception d'un signal SIG_USR1. Proposer les modifications nécessaires.