From dbc10545f3c11d964e846e04ed0ebb144c3e57a4 Mon Sep 17 00:00:00 2001 From: Yorick Barbanneau Date: Fri, 19 Nov 2021 23:00:14 +0100 Subject: [PATCH] Add TD2 Report . --- rapports/td2/rapport.md | 152 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 152 insertions(+) diff --git a/rapports/td2/rapport.md b/rapports/td2/rapport.md index e69de29..255e8e9 100644 --- a/rapports/td2/rapport.md +++ b/rapports/td2/rapport.md @@ -0,0 +1,152 @@ +--- +title: systèmes d'exploitation, TD2 +documentclass: scrartcl +author: + - Juliette Lenoir + - Yorick Barbanneau +fontsize: 13pt +mainfont: DejaVu Serif +geometry: [top=1.5cm, bottom=3cm, left=3cm, right=3cm] +header-includes: + - \definecolor{liens}{HTML}{de6a66} +urlcolor: liens +linkstyle: bold +... + +## Bilan + +Après le premier niveau de TD effectué, alors que nous pensions pouvoir vaincre +le boss NachOS facilement (tel ceux des jeux *Ubisoft*), nous nous sommes en +fait retrouvé dans un *Dark Souls* like. Vous savez ce genre de jeux qui nous +donnent on a envie de casser manettes, clavier, écran, traiter le chat comme +dans les pubs des *Nuls* mais sur lequel on revient forcément. + +L'objectif de ce TD a été de permettre l'exécution de programme dans Nachos +avec plusieurs threads. + +Il s'est déroulé en 2 parties: + + * La première a été consacrée au multi-threading dans les programmes + utilisateurs. Nous avons permis aux programmes utilisateurs de manipuler d + es threads NachOS. + * La seconde a eu pour but d'implémenter la plusieurs threads par processus. + +Pour réaliser ces deux parties, nous avons utilisé deux appels système : + + * un pour créer des threads (`ThreadCreate`) + * un autre pour les détruire (`ThreadExit`) + +Les fonctions de base de la gestions de nos threads sont présente dans le +fichier `userthread.cc`, dans leurs définitions se font dans `usertread.h`, +comme demandé dans le sujet du TD. + +### Passage des paramètres depuis l'appel système + +L'appel système `ThreadCreate` prends deux paramètres: l'adresse de la fonction +à exécuter et l'adresse des paramètres de cette fonction. Cependant nous ne +pouvons passer qu'une seule valeur lors de du démarrage de notre Thread: + +```c +Thread->Start(void * funtion, void * arguments) +``` + +Nous avons choisi d'encapsuler l'adresse mémoire de la fonction et l'adresse +mémoire de ses arguments dans une structre `ThreadArgs_t`: + +```c +typedef struct { + int f; + int arg; + int stackAddr; +} ThreadArgs_t; +``` + +Celle-ci est effectuée dans le fichier d'entête `userthread.h`, nous parlerons +de `int stackAddr` un peu plus loin dans ce chapitre. + +La fonction `StartUserThread`, servant à initialiser les différents registres, +reçoit cette structure sous la forme d'un `(void*)`. Nos ne pouvons l'utiliser +tel quel, il nous faut donc la caster dans une variable de type `ThreadArgs_t`. + +Afin de ne pas perdre cette structure lors de la fin de notre fonction +`Do_ThreadCreate`, nous la positionnons sur le tas avec un `malloc` +(`userspace.cc` ligne 50). Afin de ne pas froisser *LealSanitizer* nous n'avons +pas oublié de libérer cette zone mémoire une fois devenueNouveau dossier inutile dans la +fonction `StartUserThread` (ligne 38-39). + +### Le comptage des thread. + +Comme nous l'avons compris, la classe `AddrSpace` représente un processus -- un +espace d'adressage. Côté noyau, tout n'est que Thread, dont certains partagent +un même espace d'adressage. Il nous a donc **semblé légitime d'implémenter le +comptage des Threads dans `AddrSpace`** via la variable publique `int thread` +(définie dans `addrspace.h` ligne 50). Celle-ci est initialisée à 1 lors de +l'instanciation: le `main` de notre programme compte lui aussi pour un thread. + +Une fois que nous savons combien de threads sont encore "en vie", il nous est +possible de terminer notre programme quand tous ses threads sont finis dans la +fonction `Do_ThreadExit` (fichier `usersthread.cc` ligne 88). + +### Gestion de la pile + +Comme l'a démontré notre programme de test (`/test/threadtest.c`), la première +version de notre gestion de threads était plus qu'imparfaite: elle les +conjuguait tous avec la même pile. Nous avons alors utilisé la classe `Bitmap` +afin de gérer les espaces de pile de nos différents threads. Sachant que nous +réservons 256 octets de pile par thread et que notre pile gérée par `AddrSpace` +a une taille de `UserStackSize`, nous pouvons en déduire le nombre de *"slots"* +disponibles. Il ne faut pas oublier que notre `main` a déjà une pile et done la +réserver a l'instanciation de notre `AddrSpace` (fichier `addrspace.cc` ligne +145). + +L'affectation d'un espace de pile se fait par la fonction `AllocateUserStack` +(fichier `addrspace.h` ligne 320). Elle est appelée par `Do_ThreadCreate` +**avant la création d'un nouveau thread** car si l'allocation echoue il faut +tout arrêter et retourner une erreur: la célèbre *Stack Overflow*. L'adresse +de pile de notre nouveau thread est encapsulée dans notre structure +`ThreadArgs_t` afin de la passer à `StartUserThread`. + +Nous avions au départ imaginé un autre mécanisme: faire attendre les threads +jusqu'à la libération d'une place. Petit problème cependant: que se +passera-t-il lorsqu'un programme fera une barrière? + +### Les points bonus + +Nous n'avons pas eu le temps d'aborder les points complémentaires. + +## Points délicats + +Plusieurs points ont été délicats lors de la réalisation de ce TD2. + +Tout comme le premier TD, Il nous a fallu tout d'abord comprendre comment les +éléments s'articulent entre eux. Cette étape nous a pris beaucoup de temps, +nous avons obtenu **un premier thread réellement fonctionnel il y a tout juste +deux semaines** -- après avoir tout repris de zéro. Nous avons passé une grosse +partie de notre temps à lire, comprendre et expérimenter le code avant de +pouvoir le modifier et le compléter. + +La création de notre premier thread a été pour nous le plus compliqué. En +effet, lors de cette implémentation, nous avons rencontré plusieurs erreurs de +segmentation car notre thread n'était pas à la bonne place dans la mémoire. Une +fois cette étape passée les choses ont été un peu plus simple. + +## Limitations + +Nous avons passé beaucoup de temps à comprendre comment tout les éléments +s'articule ente eux; nous avons perdu du temps au début de la partie 1. Par +manque de temps, nous n'avons pas pu réaliser la partie 3 Bonus. + +La terminaison de notre processus une fois tous les threads finis ne nous +convient pas (`Do_ThreadExit`), nous la trouvons bancale, une version plus +élégante devrait être possible (sûrement plus simple une fois le TD3 plus +avancé). + +## Tests + +Tous nos test se sont fait avec `test/threadtest.c`, nous avon adapté son code +en fonction de ce que nous voulions tester: + + * tester le fonctionnement d'un seul thread (Action I.7) + * tester le fonctionnement de plusieurs threads (Action II.1) + * tester la pile (Action II.3) + * l'utilisation de la classe `Bitmap` (Action II.4)