PRINCIPLES OF OPERATING SYSTEMS L. BENTABET, Bishop s University, Winter 2007 Notes par Philippe Giabbanelli



Documents pareils
4. Outils pour la synchronisation F. Boyer, Laboratoire Lig

Instructions pour mettre à jour un HFFv2 v1.x.yy v2.0.00

Instructions Mozilla Thunderbird Page 1

Surveillance de Scripts LUA et de réception d EVENT. avec LoriotPro Extended & Broadcast Edition

Once the installation is complete, you can delete the temporary Zip files..

Utiliser une WebCam. Micro-ordinateurs, informations, idées, trucs et astuces

1 Architecture du cœur ARM Cortex M3. Le cœur ARM Cortex M3 sera présenté en classe à partir des éléments suivants :

Contents Windows

Exercices sur SQL server 2000

TABLE DES MATIERES A OBJET PROCEDURE DE CONNEXION

How to Login to Career Page

GAME CONTENTS CONTENU DU JEU OBJECT OF THE GAME BUT DU JEU

WEB page builder and server for SCADA applications usable from a WEB navigator

Windows Server Chapitre 1: Découvrir Windows Server 2008

Thank you for choosing the Mobile Broadband USB Stick. With your USB Stick, you can access a wireless network at high speed.

DAns un système multi-utilisateurs à temps partagé, plusieurs processus

Application Form/ Formulaire de demande

XtremWeb-HEP Interconnecting jobs over DG. Virtualization over DG. Oleg Lodygensky Laboratoire de l Accélérateur Linéaire

Package Contents. System Requirements. Before You Begin

Tutoriel de formation SurveyMonkey

VTP. LAN Switching and Wireless Chapitre 4

Systèmes d exploitation Gestion de processus

WiFi Security Camera Quick Start Guide. Guide de départ rapide Caméra de surveillance Wi-Fi (P5)

Principe de TrueCrypt. Créer un volume pour TrueCrypt

Lesson Plan Physical Descriptions. belle vieille grande petite grosse laide mignonne jolie. beau vieux grand petit gros laid mignon

Software and Hardware Datasheet / Fiche technique du logiciel et du matériel

Ordinateurs, Structure et Applications

Guide d'installation rapide TFM-560X YO.13

lundi 3 août 2009 Choose your language What is Document Connection for Mac? Communautés Numériques L informatique à la portée du Grand Public

LOGICIEL D'ADMINISTRATION POUR E4000 & G4000 MANAGEMENT SOFTWARE FOR E4000 & G4000

POLICY: FREE MILK PROGRAM CODE: CS-4

affichage en français Nom de l'employeur *: Lions Village of Greater Edmonton Society

Partie 7 : Gestion de la mémoire

Editing and managing Systems engineering processes at Snecma

MapReduce. Malo Jaffré, Pablo Rauzy. 16 avril 2010 ENS. Malo Jaffré, Pablo Rauzy (ENS) MapReduce 16 avril / 15

that the child(ren) was/were in need of protection under Part III of the Child and Family Services Act, and the court made an order on

Concept de machine virtuelle

4. Outils pour la synchronisation F. Boyer, Laboratoire Sardes

Gestion de mémoire secondaire F. Boyer, Laboratoire Sardes

Frequently Asked Questions

NOTICE INSTALLATION. ARCHANGE Simplex Office N&B/Couleur KONICA MINOLTA BUSINESS SOLUTIONS FRANCE

Contrôle d'accès Access control. Notice technique / Technical Manual

HAUTE DISPONIBILITÉ DE MACHINE VIRTUELLE AVEC HYPER-V 2012 R2 PARTIE CONFIGURATION OPENVPN SUR PFSENSE

DOCUMENTATION - FRANCAIS... 2

Outils d'analyse de la sécurité des réseaux. HADJALI Anis VESA Vlad

Développement logiciel pour le Cloud (TLC)

Vanilla : Virtual Box

IFT Systèmes d exploitation - TP n 1-20%

Guide d'installation et de configuration de Pervasive.SQL 7 dans un environnement réseau Microsoft Windows NT

Acronymes et abréviations. Acronymes / Abbréviations. Signification

Logitech Tablet Keyboard for Windows 8, Windows RT and Android 3.0+ Setup Guide Guide d installation

Temps Réel. Jérôme Pouiller Septembre 2011

IV- Comment fonctionne un ordinateur?

GIGABIT PCI DESKTOP ADAPTER DGE-530T. Quick Installation Guide+ Guide d installation+

DOCUMENTATION MODULE BLOCKCATEGORIESCUSTOM Module crée par Prestacrea - Version : 2.0

Threads. Threads. USTL routier 1

USB 598. Quick Start Guide (Windows) Guide de démarrage rapide (Windows) USB Modem. Modem USB.

HSCS 6.4 : mieux appréhender la gestion du stockage en environnement VMware et service de fichiers HNAS Laurent Bartoletti Product Marketing Manager

I>~I.J 4j1.bJ1UlJ ~..;W:i 1U

Exemple PLS avec SAS

Notes de cours : bases de données distribuées et repliquées

3615 SELFIE. HOW-TO / GUIDE D'UTILISATION

Notice Technique / Technical Manual

Toni Lazazzera Tmanco is expert partner from Anatole ( and distributes the solution AnatoleTEM

EN UNE PAGE PLAN STRATÉGIQUE

Rappels d architecture

Paxton. ins Net2 desktop reader USB

<Insert Picture Here> Solaris pour la base de donnés Oracle

Thank you for choosing the Mobile Broadband USB Stick. With your USB Stick, you can access a wireless network at high speed.

Restaurant Application Quick Reference Guide

Stratégie DataCenters Société Générale Enjeux, objectifs et rôle d un partenaire comme Data4

NOM ENTREPRISE. Document : Plan Qualité Spécifique du Projet / Project Specific Quality Plan

APPENDIX 2. Provisions to be included in the contract between the Provider and the. Holder

PARIS ROISSY CHARLES DE GAULLE

Règlement sur le télémarketing et les centres d'appel. Call Centres Telemarketing Sales Regulation

RAPID Prenez le contrôle sur vos données

DOCUMENTATION - FRANCAIS... 2

UML : Unified Modeling Language

SERVEUR DÉDIÉ DOCUMENTATION

REMBO Version 2.0. Mathrice 2004 DESCRIPTION MISE EN OEUVRE CONCLUSION.

AIDE FINANCIÈRE POUR ATHLÈTES FINANCIAL ASSISTANCE FOR ATHLETES

APPENDIX 6 BONUS RING FORMAT

Configuration du serveur ESX

VMware ESX : Installation. Hervé Chaudret RSI - Délégation Centre Poitou-Charentes

Le No.1 de l économie d énergie pour patinoires.

Mise en oeuvre TSM 6.1

On appelle variable condition une var qui peut être testée et

TP11 - Administration/Tuning

Forthcoming Database

THE EVOLUTION OF CONTENT CONSUMPTION ON MOBILE AND TABLETS

Supervision et infrastructure - Accès aux applications JAVA. Document FAQ. Page: 1 / 9 Dernière mise à jour: 15/04/12 16:14

Manuel de l Administrateur

Cheque Holding Policy Disclosure (Banks) Regulations. Règlement sur la communication de la politique de retenue de chèques (banques) CONSOLIDATION

TD2 Programmation concurrentielle

Guide d installation logicielle

Tutoriel déploiement Windows 7 via serveur Waik

Présentation du SC101

Dans une agence de location immobilière...

Manuel de l utilitaire Computer Setup (F10) HP Compaq Business Desktops Modèles d220 et d230

Compléter le formulaire «Demande de participation» et l envoyer aux bureaux de SGC* à l adresse suivante :

Transcription:

PRINCIPLES OF OPERATING SYSTEMS L. BENTABET, Bishop s University, Winter 2007 Notes par Philippe Giabbanelli I. Definitions and history 1) What is a Computer System? It is a set of users, system and applications, Operating System and resources. The OS (i.e. the kernel that is running all the time on the computer) controls the use of the hardware for the different applications, which are obviously used to solve some problems. The requirement depends on users and applications. Needs of users Convenience Monopolized by a single user Run multiple programs GUI for ease of use Resources utilisations is not an issue Example : Linux, windows, Mac OS, for PC. Efficiency Large, shared multi user systems OS designed to optimize the use of resources Fair amount of resources for every user Security and protection (on memory!) Efficiency Example : mainframe system, Unix/Irix/Vax. Trade-off Workstations connected through a network between Sharing of devices and Network efficiency and Example : Windows NT, Linux. convenience Nothing Embedded systems (input are sensors!). Needs of the system Only resources allocation. 2) Evolution of Operating Systems Mainframe Systems Batch Systems Rudimentary OS without concept of process but a job, composed of code+data+control information. No interaction with the user. Input : punched cards or magnetic tapes. Output : line printer. A batch is a set of jobs. The execution is sequential. Job 1 Job 2 Job 3 load OS job memory Multiprogram Several jobs in memory Batch Systems A job has the as long at it is not waiting for an I/O ; it is the management (scheduling). Magnetic disk Job 1 Job 2 Job 3 Job 4 Job Selection Virtual memory managment. OS Job 1 Job 2 Job 3 multiplexing

Timesharing Systems Interaction with the user Support multi-tasking The is multiplexed between the tasks For the scheduling of processes, switching is performed on I/O and with a timer. We say process instead of job. Desktop Systems Use of timesharing One user We focus more on convenience than efficiency Multiprocessors Systems Use of timesharing Reliability (fault tolerant) Economical bus 1 2 Memory n n processors : speed by k.n, where k < 1 depends on the cost of managements of the network. Two configurations : Symmetric (solaris 5) : all identical from the point of view of responsibility. User responsible for distributing to the. Asymmetric (solaris 4) : 1 master. The OS is responsible for dispatching, instead of user. Le switch entre les processus est rapide car on laisse toutes leurs données en mémoire. On gaspille ainsi de la mémoire en la laissant allouée à quelque chose qui ne l utilise pas, mais en revanche le switch devient très rapide puisqu on change uniquement les pointeurs. C est pour cela qu on arrive à un switch en millisecondes avec des timer extrêmement réduits. II. Computer Organization disks monitor (écran) printer keyboard mouse bus Disk Controller Graphics Adapter Memory USB Controller load R1, a load R2, b add R1, R2 store R3, a 1) Organization Translated into machine code 101. 011. 110. 3046 3050 3054 Execute the code located at this part of the memory Les registres du sont manipulés par l ALU (Arithmetic Logic Unit). IR est le Instruction Register, qui contient l instruction courant. PC (Program Counter) pointe vers la prochaine instruction. Il y a un autre registre DR (Data Register), utilisé lorsqu on veut sauver quelque chose en mémoire. a... R 1 R 2 R 3 PC 3050 IR load R1,a

2) Controllers Organization Similar to s. A controller is in charge (responsible) for the input/output devices ; it will transfer the data from the buffer to the input/output device (or vice versa). Controls the Input/Output operations between their own buffers and external devices. The communication controllers/ is done through the bus. At some points, the controller will need the bus; they will have to wait until the bus becomes free. Therefore, the controllers will execute concurrently with the (il y a une concurrence pour l accès au bus; sinon, on parlerait d exécution simultanée). Le device status a 2 bits importants : Busy et Done. Le code pour l erreur survenue est mis dans les bits restants. Le command register a 2 valeurs : input (external device buffer), ou output (buffer external device). Command register LOGIC CIRCUITS (control unit) Device Status Register BUFFER (internal memory) Busy Done Description 0 0 Idle (ready for use) 0 1 I/O finished 1 0 Working 1 1 Undefined (error) Example : Save f.out to the disk, and then load f.in from the disk. Save f.out - OS () checks if the device is idle (i.e. ready for use). - Copy partially the data from the memory to the buffer. Les données sont rarement copiées en totalité car le buffer a une taille limitée, même s il arrive maintenant jusqu à 16 Mo. - Set output in the command buffer. - Status of the device : working. Move data from the buffer to the disk. - Status of the device : finished. We tell it to the through the BUS. The controller sends interrupts to the ; the is stopped in what it was doing, it is an interruption. Load f.in - Check idle - Command register : input - Device : working - Copy from disk to buffer - Finished interrupts the Input 1 Output 1 Output 2 Input 2 Output 3 For each device, we have a queue (file d attente). These queues are all put together in a data structure called device status table, implemented in the OS. 3) Interrupts Mechanism read(x) y = x + 2 load R1, a load R2, b add R1, R2 store R3, c 1 2 1 will be waiting for the controller. 2 will be using the (i.e. running). 1 aura fini après le load R2, b. Il fait un interrupt : interrompt les processus. Pour intervertir, on sauvegarde le contenu (content/context) du, c est-àdire les registres, et on charge le nouveau processus. Il faut avoir un moyen d identifier le périphérique qui a envoyé l interrupt. Nous allons voir 2 moyens.

Le périphérique envoie un interrupt, qui n est qu un seul bit avec 0 ou 1. On fait un sondage linéaire (polling : check sequentialy) pour trouver le premier périphérique qui a comme statut finished. Cela nécessite de définir une séquence de recherche, et donc d assigner certaines priorités aux périphériques. Le périphérique inclus son identité dans l interrupt qu il envoit : vectored interrupt system, car c est un vecteur de bits. Ce système est illustré ci-dessous : Le périphérique 0 Finished? génère l interrupt n = 2 k entrées 0001. On utilise le vecteur de bits tout à 0 pour dire qu il n y a 2 k k Encoder pas d interrupt, donc les périphériques sont k sorties nommés à partir de 0 mais le code commence à 1. 4) I/O Handling (gestion des entrées/sorties) On cherche par exemple à exécuter la routine associée à read(x), demandé par le périphérique 1. Chaque périphérique a une routine propre, i.e. sa façon de fonctionner. La routine est stockée en mémoire, à un emplacement déterminé par l adresse [offset+binary code] ; l offset est déterminé par le système d exploitation, et le code binaire est donné par l API lorsque l utilisateur appelle une fonction. 100 101 Address 1 address 0 address 1 Routine for the device 1 Adresse de la routine pour le 0 Exemple : copy x du buffer vers la mémoire Dans l exemple ci-contre, l offset est 100. On donne le code binaire 0 : on regarde l adresse dans la table de pointeurs (map), on exécute la routine concernée. On peut alors finir l interrupt en chargeant la contexte sauvegardé et en le relançant. Notons que IRQ : priorité des interrupts. 5) DMA (Direct Memory Access) Le n est pas utilisé pour faire les transferts avec les périphériques. Au lieu de cela, on utilise le DMA. Le problème est que le travaille et a besoin d accès à la mémoire : le DMA et le entrent en compétition pour le bus. Dans certaines architectures, chacun a son bus (dual-bus architecture). microcontroller DMA Main Memory I/O device buffer Process 6) Hardware Protection Several processes and the OS are running concurrently All are sharing the hardware resources If there exist a fatal error in one process, we don t want it to disturb the execution of the other processes; we need to isolate it. Examples : Overwriting the data of other processes, involves the memory. Infinite loop, involves the. Multiple Input/Output operation of the same device, involves the devices. We need a protection mechanism implemented at hardware level to ensure that it cannot be broken.

Dual Execution Mode. A bit is added to the : the mode bit. It defines 2 modes of execution : - User mode (1). It is a user program that is running : execution of behalf of the user. It cannot execute instructions that may harm the system. - Monitor mode (2), or supervisor mode, done on behalf of the OS. Instructions may harm the system, but we hope that they won t because they are written in the OS. Example : cin<<, fopen, User Mode (bit = 1) fopen : trap (call to the OS) finished OS User Program Abnormal Termination Le switch du mode utilisateur au mode superviseur se fait en générant une interrupt (aussi dit trap). En pratique, cette interrupt est générée par l API, lors de l appel d une fonction. Toute action qui peut bloquer le système doit être faite en passant par une fonction de l API, comme l ouverture d un fichier. Si le programme tente de communiquer directement avec le matériel, celui-ci verra que le mode bit est toujours à 1, et que l accès est interdit ; il fera une interrupt et l OS fermera le programme. I/O protection. I/O routines must execute in supervisor mode. L API se charge de faire la correspondance lors de l appel : elle change le mode et trouve le n à utiliser dans la table de pointeurs. Si les paramètres à passer sont trop gros, on les sauve dans le user space et on place juste un pointeur dans le ; sinon on fait un passage direct dans les registres. System Call n (user) API Va à l adresse offset+n de la routine Switch bit mode 0 OS Hardware Check the mode bit : it is 1. Generates an interrupt to create a fatal error. Switch bit mode 1 Exécution de la routine Si on arrive à mettre notre adresse dans l espace de l OS, et que cette adresse pointe vers notre programme, alors on met notre bit mode à 0 de façon permanente, et on exécute tout le programme en mode supervisor : tout le mécanisme de sécurité tombe à l eau. Il faut donc une protection de la mémoire. Memory Protection. We add 2 registers to the : base register (smallest address of the process), limit register (range of addresses allocated) ; they can be accessed only in supervisor mode. OS 0 Base value Base + limit Process 1 Process 2 Process 3 256000 300040 420540 880000 address >= yes < no Trap to OS for fatal error yes Access OK En pratique, la mémoire est fragmentée, ce n est pas un bloc continu. Utilise le MMU (Memory Mamagnment Unit). Protection. Si un processus est en exécution dans une boucle infini, il ne va pas rendre le : on protège donc le avec un timer qui génère un interrupt tous les t. Le timer est un compteur qui va de n à 0, branché sur l horloge interne (déclenchement sur front). t est une variable gérée par l OS (voir scheduling).

7) The storage structure Main Memory. The only media that the can access through address is the main memory. A program must be in main memory in order to be executed. This memory is volatile. Access are done at the hardware level, using machine instructions (e.g. load, store, ). R/W RAM Cache Memory Controllers Registers Managed at hardware level I/O Mapped Memory Les contrôleurs ont des adresses et peuvent être accédés par load et store. Il y a une plage d adresses contrôleurs. We use high speed memory (cache memory) to hold recently used data. If the data is in the cache, we use the cache; otherwise it is in the RAM, and we copy it to the cache, and then we use it. It increases the performances of the system. We try to place 80% of the data needed in cache instead of the RAM. Since the cache memory is small, we need a data replacement policy. On fait passer un des blocs du Cache (full) RAM cache dans la RAM, par exemple «remove the least recently used block». Après, on copie et on utilise le bloc We need this block demandé par le processeur. Time neighbourhood : data used non only once; several access to the memory are expected. Location/space neighbourhood : we move some blocks of data instead of only 1 or 2 bytes. Secondary Storage. Magnetic disks, non volatile, accessed through the OS. Magnetic Disk Cache load update Main Memory (RAM) Main Memory (RAM) load Update when we move the block Cache Cache load update registers Dans la situation de deux processeurs utilisant la même mémoire, on établit une communication entre les deux caches. III. OS Structure 1) OS Components Process = Running program + ressources ( time, files, messages). Process creation, deletion, suspension (operation d I/O ou à cause du timer : demande de resources non encore disponibles), resumption by the OS. Interprocess communication and synchronization (partage de variables). Memory Manager. Allocate memory to processes, and keep track of it (e.g. use of limit + base registers), and deallocate. File Manager. Mapping between the logical files and the secondary storage (où le fichier n est pas un bloc continu mais fragmenté). Manipulation of files and directories. Protection :, I/O, Memory. Interfacing : On lit une commande. L OS test la validité: si non, message d erreur ; sinon trigger OS call.

2) System Calls : interface between processes and OS Routines implemented in run-time library indirect Processes OS Direct Call : fork(), read(), write(). Norme POSIX. Readfile(), write() : win32api (windows). Read, write : POSIX or win32api Use of registers to pass parameters Load x OS call 13 x Routine B Use x On met les paramètres dans les registres et on appelle la routine, qui va aller les chercher. Use of memory to pass parameters x Parameters Load x OS call 13 x Read x Load param Use of the stack (linux) Calling process : push OS process : pop 3) Useful OS calls Process Controlling A new command Shell process Valid? Create new process. Fork(), exec sur la commande. Terminate the process : exit(). On a deux modes : wait() pour une exécution en foreground, ou rien si on veut du background. File Management (POSIX) Tous les périphériques d entrées/sorties sont considérées comme des fichiers dans la norme POSIX : open() retourne un fid, close(), read(), write(), lseek(), fcntl() envoie une requête spécifique comme «don t block the calling process.» 4) Device Managment // user program cout >> «x?» ; cin << x ; Stdio.h Write(deviceId, ). deviceid est un entier identifiant le périphérique : disque dur en 3, floppy en 2 (major number), puis numéro : 1 er disque dur (numéro mineur 1), 2 nd disque dur (numéro min. 2), etc. L utilisateur appelle des fonctions de la bibliothèque, qui font des appels au noyau. L OS fait le lien entre l appel et le driver, et le lance en mode superviseur. Read(deviceId, ) Device dependant drivers (they are outside of the kernel, as we do nowadays to keep the kernel as small as possible). OS call to the kernel. Switch in supervisor mode. Check value of the decice Id (switch) Call the routine which knows how to write to the right device. This routine is responsible for error handling. Rappelons qu en POSIX, tout périphérique est vu comme un fichier. Quand on fait un cout, le périphérique est l écran : WONLY (write only) ; quand on fait un cin, c est le clavier : RONLY (read only).

P 1 5) Interprocess Communication Les processus doivent partager certaines données, et des problèmes de synchronisation se posent. Pr 1 update use Exemple : un processus produit des données et un autre les utilise. Information to share x y retrieve update Pipe ID Pr 2 P 1 P 1 P 2 P 1 base : 1000 P 1 limit : 1000 P 2 base : 1900 P 2 limit : 2100 Copy of the info L implémentation la plus courante consiste à autoriser le partage de mémoire dans le mappage des adresses des processus. On peut aussi utiliser des pipes (se gère comme des fichiers avec write et read dans le pipeid) ; par contre ils entrainent un grand nombre de context switching : time consuming! 6) OS Organization MSDOS a été conçu pour fournir le plus de services dans le moins possibles d espaces. Il adoptait une architecture en couches, mais ne la faisait pas respecter : une application peut accéder directement au matériel (c.f. flèches rouges). Il y a donc de graves problèmes de protection. Ceci se comprend car la 1 ère version était implémentée dans le processeur 8088 qui n avait pas de mode bit. Application programs Resident Program (toujours en mémoire) Drivers Hardware Les anciennes versions d UNIX adoptaient aussi une structure en couche, mais la faisaient respecter. Le problème était que tout était dans le noyau, il n y avait aucun module : on parle d une structure monolithique, difficile à débuguer. De plus, chaque fois qu on a un nouveau driver, il faut recompiler le noyau ce qui fait augmenter ça taille et prend du temps. Le fonctionnement, lui, est rapide car peu de calls. The users Using system programs System Call Interface Kernel memory manager /file manager drivers Hardware Dans le micronoyau (Micro Kernel), on veut garder le noyau aussi petit que possible : la gestion de la mémoire, du, les communications et les drivers sont en dehors du noyau. La structure en couche doit être respectée, mais le nombre d appels est plus important. On va de l user space (programme) dans le monitor space (noyau) à l user space (prendre les drivers) : 2 context switches. Ainsi, la 1 ère version de Windows NT (pour les serveurs) utilisait ce système et était plus lente que Windows 95 (paradoxe). Le système est plus stable, portable et facile à débuguer en conservant un petit noyau certifié (Linux). La dernière architecture est celle à modules. L OS est fait d un micro kernel et d un ensemble de modules chargeables dynamiquement (runtime : quand on les appelle), et/ou au démarrage. Si un module est dans le noyau, on l exécute en mode superviseur. C est l architecture de certains Solaris où on peut choisir ses modules.

IV. Process Managment 1) Déroulement général et relations père-fils A process is all what a program needs in order to be executed : text segment (program code), program counter (address of the next instruction), data segment (global data defined within the program), stack (memory ressource allocated to thje process in order to save temporary variables such as return addresses), heap (memory that is allocated dynamically). Just created new In memory, waiting for the admitted complete ready waiting timer Only one process scheduled running Request I/O or waiting for event terminated Deallocation. The OS will release the process ressources. There is a need for an efficient identification of each process, to know exactly its state, what it is using and what it s requiring. We use the PCB (Process Control Block) : an OS data structure that identifies each process in the system (i.e. chaque processus a son PCB). It is updated on change of state. It contains : - Process State - Process ID (integer) - PC and all the registers from the. This is not updated during the execution. - scheduling information : priority, address of the next process. - Memory Information. Everything related to the mapping, e.g. base and limit registers. - Accounting information (used time, time limit, ) for real time application where there is a time deadline. - List of files that are opened by this process, stored as a set of file identifiers (fid). Head Tail La file contient les PCB, chacun ayant l adresse du PCB suivant. Une valeur spéciale signifie «end of the tail». Le scheduling est en charge de la migration des processus entre les files d attentes (queues). Il peut y avoir plusieurs ready queue, dépendantes des priorités ; de même, il y a plusieurs waiting queue car une pour chaque périphérique sollicitée. Ready et waiting ne sont pas deux files mais plutôt deux familles de files. Chaque file est généralement implémentée par une liste chaînée (linked list). Lorsqu un parent fait un fork, le parent ou (exclusif) le fils doit aller dans la ready queue. Quand le segment de temps alloué à un programme vient à expiration et qu on manque de mémoire, on met le processus dans le disque et on le rechargera quand on aura de la place ; on fait ça quand ils ont une basse priorité, ce qu on nomme le medium term scheduler. Celui ci-contre est le short time scheduler, car il est invoqué souvent. The parent goes to the ready queue Create new process finished Fork a child The child execute. Ready queue I/O queue Swap out Disk Request I/O no : swap in to the disk finish Time slice expires Is there enough place in memory to store the process back in the ready queue? yes Ready queue

P 0 interrupt Save PCB 0 resume Save PCB 0 interrupt Copy of PCB 1 Copy of PCB 1 resume P 1 Context Switching Idle Idle Il faut généralement minimiser les context switching car ils utilisent le. Sur certains systèmes, le context switching est supporté par le matériel : - Machines de Sun Microsystem, où le a plusieurs ensembles de registres et chaque PCB a son propre ensemble. - Une instruction spécifique de bas niveau, au lieu d une pléiade de copy et load. Les processus sont organisés sous forme d arbre, basé sur une relation parent-fils. Le processus faisant le fork est le parent, et celui en résultant est le fils. Le fils peut partager tout ou une partie des ressources du parent, ou avoir de nouvelles ressources allouées par l OS. La définition de l OS doit permettre ces 3 possibilités (policy). L exécution peut se faire en foreground (on ne détache pas le processus, on attend qu il ait fini avant de reprendre la main) : parent will wait for child termination. L exécution peut aussi se faire en background : les processus sont en concurrences, considérés comme au même niveau, et c est au scheduler de s en charger (execute concurrently). Shell > ls Parent process Child process that will execute the command ls Execution 1. P 0 is running. Fork() P 1 2. P 1 is ready 3. P 0 goes in waiting 4. P 1 starts executing 5. P 0 waits for P 1 to resume execution (ready list) Fork() éxecute une copie des données du parent. Fork() + execv charge un nouveau programme avec ses propres données dans l address space du fils. pid = fork() my pid is 214 (le parent, car il a exécute l instruction) scheduler printf(«my pid is %d\n»,pid) ; my pid is 0 (le fils, car il n a pas fait pid = fork()!) Le scheduler décide de l ordre de l exécution. Ainsi, dans l exemple précédent, l ordre des messages est indéterminé. Pour terminer un processus, exit() l arrête et l OS désalloue les ressources, ou avec abord() le parent va terminer le processus fils. Si le processus parent termine, soit tous les fils s arrêtent, soit on tente de régler le problème en mettant un nouveau parent à la racine de l arbre. 2) I/O Burst Cycles A process is bound if it spends most of its time using the (i.e. process uses the a lot). Example : a program that calculates primes numbers; we do not need interaction with the user. It is most often in the running state, and does not have to wait for any input or access to devices. A process is I/O bound if it spends most of its time in access read/write. It is most often in waiting state. A well balanced program alternates between bound and I/O bound. bound I/O bound Une importante invocation du scheduler se fait sur front haut, lorsqu un processus a fini son attente et demande à nouveau un accès au

3) Scheduling Mechanism and Criteria Généralement, le scheduler est invoqué dans 4 cas : - terminaison d un processus - switch de l état running à waiting - switch de l état running à l état ready - switch de l état waiting à l état ready Dans les vieux systèmes, on invoquait le scheduler juste sur les 2 premières situations : non-preemptive scheduling. Windows 3.x par exemple. Les systèmes d exploitations modernes utilisent ces 4 situations, on parle de preemptive scheduling. Les critères ont de gros impacts sur les performances du système. Maximiser l usage du (minimiser le idle time). Context Switch : Maximiser le throughput (nombre de processus terminés par Switch to supervisor mode. unités de temps, par exemples 30 processus à la seconde). Save PCB 1 (free registers) Minimiser le turn around (temps total nécessaire pour exécuter Load dispatcher un processus, i.e. celui passé en ready/waiting/running). Select a process from ready list Minimiser le temps de réponse (entre création et 1 ère exécution) Switch to user mode Minimiser le temps d attente (passé dans la waiting queue) Load PCB 2 into the Tous les critères ne peuvent être satisfaisants en même temps. En général, on n en cherche qu un. dispatcher loader Scheduler Select a process from P 1 invoked Scheduler the ready queue P 2 4) Scheduling Policy : First Come, First Served (FCFS) Processus Burst Time Rappel : le Burst Time est le temps nécessaire à un processus P 1 24 pour exécuter sa partie s il dispose d un plein accès au. P 2 3 P 3 3 : P 1 P 2 P 3 Average Waiting Time : 0 pour process 1 24 27 30 24 pour process 2 Moyenne 17 23 pour Process 3 Average Response Time : (0 + 24 + 27)/3 = 17. Pareil que le temps d attente car non-preemptive (une seule exécution pour chaque processus). Average Turn Around Time : On suppose que tous les processus ont été créées au même temps T = 0. On a alors (24 + 27 + 30)/3 = 27. Si on inverse l ordre d arrivée des processus, on a : Average Waiting Time (0+3+6)/3 = 3 Average Turn Around Time : (3+6+30)/3 = 13 C est donc un système très sensible à l ordre. On remarque de meilleurs performances en exécutant les plus courts processus d abord, d où l idée de l algorithme que nous allons voir maintenant. 5) Scheduling Policy : Shortest Job First (SJF) Chaque processus est associé avec le prochain burst time. Comme on ne le connaît pas, on fait une prédiction à partir des précédents. En général, on ne conserve que les 10 dernières valeurs (on affirme que le comportement sera le même que dans une période de temps récente). On peut prendre la médiane ou la moyenne. Pour l implémentation, il suffit de faire un tableau de taille 10 et l ajout en (i++)%10 ; d abord on lance FCFS le temps de recueillir assez de valeurs pour les prédictions, puis on passe en SJF. SJF réduit le average waiting time. C est une méthode non-preemptive.

6) Scheduling Policy : Shortest Remaining Time First Si un processus P j entre dans la ready queue avec un burst time t j < temps restant t i du processus courant, alors on switch pour lancer P j. Si un nouveau processus peut-être fini plus vite, on le lancera lui. Process Arrival Time Predicted Burst Time P 1 0 8 P 2 1 4 P 3 2 9 P 4 3 5 0 Chart : P 1 P 2 P 4 P 1 P 3 1 5 10 17 26 Average Waiting Time : [0 + (10 1) + (1 1) + (5 3) + (17 2)]/4 = 6,5 -----P 1 ------- ---P 2 --- ---P 4 --- ---P 3 --- Pour chaque processus, on regarde le temps qu il a passé à attendre; on divise par le nombre de processus. Cet algorithme minimise le temps d attente moyen. SJF sur le même exemple donne 7,75. Par contre, SJF fait moins de context switching : dans notre calcul du temps d attente moyen, on considère les changements de contexte comme négligeables alors que par grands nombres ils commencent à coûter. 7) Première étude comparative Imaginons que l on ait les trois applications suivantes lancées en même temps : - (1) traitement de texte - (2) jeu 3D - (3) calcul des nombres premiers SJF va donner une grosse priorité au jeu 3D car le burst time est très bas : un jeu 3D s arrête très fréquemment pour les entrées/sorties (souris, clavier) et fait rarement un moment de calcul pur. En revanche, le calcul des nombres premiers sera pénalisé par SJF alors qu il faudrait peut être allouer plus. Par conséquent, SJF donne davantage de priorité aux processus I/O bound qu à ceux bound. L ordre d exécution sera 213. Si on souhaite allouer au processus qui a le plus besoin de ressources en calcul, on prend la politique longest job first (on remarque au passage qu elle n optimise aucun de nos critères). 8) Principles of Priority scheduling Un nombre entier est associé à chaque processus. Cela peut représenter la priorité de façon croissante ou décroissante, cela dépend du système. On le détermine de deux façons : - Externe. Dépend juste de la nature du processus : OS, interaction, real time (temps limite auquel l exécution doit avoir été faite), batch (aucune intéraction). - Interne. On prend des critères comme le nombre de requêtes pour la mémoire, le nombre de fichiers, ou la moyenne (I/O time)/( time). Le scheduling peut se faire de deux façons : - Pre-emptive. Un nouveau processus dans la ready queue avec une plus grande priorité que celui du va dégager celui du. - Non-preemptive : je suis dans le, j y reste jusqu au bout. Les processus avec une priorité basses risquent de souffrir de starvation ( mort de faim ) car ils ne vont jamais accéder aux ressources qu ils demandent. La solution fournie par la plupart des O/S est de faire une priorité dynamique, qui va changer durant l exécution : c est l aging. La priorité des processus augmente avec le temps, pour être certain qu ils passent un jour. Sous Linux, on parle de crédits au lieu de priorités, mais ils sont aussi mis à jour de façon dynamique. SJF est une politique de priorité où on calcule la priorité sur la base du temps nécessaire pour la prochaine exécution (un critère interne).

9) Round-Robin (RR) Scheduling Politique bonne pour l intéractivité : on se focalise sur le temps de réponse. RR a été développé pour les systèmes à partage de temps (timesharing). La ready queue est circulaire sur le principe FIFO (premier entré, premier servi). Si un processus est scheduled (i.e. qu il utilise le ), on démarre un timer. Notons bien que c est la première fois qu on utilise un timer dans nos politiques de gestion. Après un temps t (time quantum), généralement 10ms t 100ms, le processus en cours est interrompu. Tous les t le timer envoie un interrupt, et le processus arrêté va dans la queue de la file d attente (à la fin). Le processus de tête est alors lancé. Process Burst Time Chart ( t = 20ms) : P 1 53 P 2 17 P 1 P 2 P 3 P 4 P 1 P 3 P 4 P 1 P 3 P 3 68 P 4 24 0 20 37 57 77 97 117 121 134 154 Timer reset Average Waiting Time : P 1 (0+77-20+121-97) P 2 (20-0) P 3 (33-0+97-57+134-117) Average Response Time : P 1 0 P 2 20 P 3 37 P 4 57 (très bas) RR fait beaucoup de context swtiching, par exemple davantage que SJF. On peut vouloir prendre en compte le temps nécessaire pour faire le changement de contexte quand on dessine la charge. Il faut en tout cas savoir qu à peu prêt 10% du temps est passé à faire des changements de contextes. Si t augmente il y a moins de context swtiching, mais cela ne sert alors plus à grand chose (si t est trop haut c est équivalent à la méthode FCFS). Avec les nouveaux processeurs, t est en ms et un changement de contexte peut se faire en µs. 10) Comparaison des performances Nom de la méthode Average Waiting Time Average Turn Around Time Average Response Time FCFS - - - SJF + + - RR - - + FCFS n est bon nul part (naïf). SJF est bon pour les processus bound. RR est bon pour les processus I/O bound (i.e. interactif). La solution retenue dans la réalité n est pas une méthode mais plusieurs : on utilise plusieurs files d attentes avec chacun son scheduler correspondant à une méthode. 11) Multi-level queues La ready queue est divisée en plusieurs sous-queues. Par exemple : Les processus intéractifs (I/O bound, small burst time) ont besoin d un bon temps de réponse. C est la Foreground Queue, gérée par Round Robin. Les autres processus ( bound, large burst time) sont dans la background queue, gérée SJF. Foreground (Round Robin) Background (SJF) Mechanism for queue scheduling Remarques : dans ce modèle les processus ne sont pas autorisés à passer d une file à l autre, c est peu flexible. En réalité, les processus sautent entre les queues et il faut savoir à quelle queue un processus est associée (dans windows 16 ou 32 queues). La solution la plus élaborée est le multi-level feedback queues: on peut aller up et down dans les files d attentes, et on a un point d entrée à la création du processus. Pour gérer les priorités des queues, il serait stupide de faire passer tout le foreground avant par exemple (problème de starvation). On fait un RR mixé avec les priorités.

12) Multi-level feedback queues Un processus peut bouger entre les files. Une Multi-Level Feedback Queues (MFQ) se caractérise par : - le nombre de files - le scheduling policy pour chaque file (la façon de les gérer : round robin, SJF, ) - quand un processus peut aller en haut ou en bas dans la hiérarchie - dans quelle file un processus entre lorsqu il a besoin du Par exemple, la configuration suivant défini de façon complète une MFQ : - On a 3 files Q 0, Q 1, Q 2. Q 0 : RR ( t = 8), Q 1 : RR ( t = 16), Q 2 : FCFS. - Un processus ne va jamais en haut. - Un processus va en bas : Q 0 Q 1 s il n a pas été terminé après t = 8 Q 1 Q 2 s il n a pas été terminé après t = 16 - les processus entrent tous dans Q 0 Q 0 ( t = 8) Q 1 ( t = 16) Q 2 (FCFS) Les processus interactifs vont rester dans Q 0 voire Q 1 car ils ne sont pas longs. Les processus non-interactifs vont aller dans Q 3. On met des priorités entre les files, comme Q 0 > Q 1 > Q 2 afin de gérer l accès au. On a toujours les deux gestions possibles : preemptive (relâcher le pour un autre processus : problème de starvation) et non-preemptive (le processus dans le se finira). C P U Processes Arrival Time Burst Time P 1 0 31 P 2 1 5 P 3 2 9 P 4 3 10 P 5 4 6 P 6 5 17 P 1 (from Q 0 ) 0 8 13 21 P 5 (termine) P 2 (termine) P 6 (from Q 0 ) P 3 (from Q 0 ) P 1 (from Q 1 ) P 4 (from Q 0 ) P 3 (from Q 1 ) 29 35 43 59 60 V. Processes Synchronization 1) Exemple de problème : Bounded Buffer Des processus coopératifs doivent partager des données, donc il y a un besoin de synchronisation. Un exemple classique est celui du Bounded Buffer. Un objet produit des données pendant qu un autre veut les retirer, le tout par l intermédiaire d un tableau de taille n. Producer Buffer add in out Consumer Problème : count est une variable partagée. The producer : while(1){ while(count==n} // wait // produce item buffer[in] = item ; in = (in+1)%n ; count++ ; } The consumer : while(1){ while(count==0} // wait // grab an item item = buffer[out] ; out = (out+1)%n ; count-- ; } Soit count = 5. Le producer et le consumer vont exécuter count++ et count de façon concurrente. Quelle est la nouvelle valeur de count? Cela peut-être aussi bien 4, 5 ou 6. Comme ce ne sont pas des instructions atomiques, il est possible qu elles soient interrompues. Incrément et décrément se fait avec : Incrémenter : R 1 = count Décrémenter : R 2 = count R 1 = R 1 + 1 R 2 = R 2 1 count = R 1 count = R 2

Détaillons ce qui peut se produire lors de l exécution du programme pour comprendre l importance d avoir des instructions atomiques (qui ne peuvent pas être interrompues par timer ou quoi que ce soit) : 1. P 1 R 1 = count [ 5 ] 2. P 1 R 1 = R 1 + 1 [ 6 ] timer interrupt 3. P 2 R 2 = count [ 5 ] 4. P 2 R 2 = R 2 1 [ 4 ] timer interrupt 5. P 1 count = R 1 [ 6 ] timer interrupt 6. P 2 count = R 2 [ 4 ] On arrive à count = 4, et on voit qu avec des interrupts au timer différentes alors le résultat serait différent. 2) Solutions matérielles Pour synchroniser, un bloque un des processus si l autre est en train d utiliser une variable partagée ; on parle de Critical Section pour désigner la partie du code où un programme manipule des variables partagées. Un seul processus peut-être dans sa Critical Section à un moment donné. S il y a partage de variables sans synchronisation, on parle de race condition : les processus se font la course. La première idée et d activer et désactiver les interruptions avec un bit dans le. Cela donnerait : Disable interrupts Disable interrupts Sauf si on veut donner des Count ++ // critical section Count -- // critical section priorités, les solutions de Enable interrupts Enable interrupts synchro. sont symétriques Cependant, s il y a une boucle infinie dans la critical section, alors le n est plus protégé, on crash. L alternative est test and set instruction. Soit TS(m) avec m un emplacement mémoire, ou TS(R,m) avec R un registre et m un emplacement. On ajoute cette instruction, qui consiste à faire 3 opérations : Load R with the content of m Test the content of R (i.e. return it) Set m = true Ce qui est capital c est que ceci est géré comme une seule instruction, elle est atomique. Un exemple : R m false R false m true Exemple : Before executing TS(r,m) while(true){ While(TS(lock)) // these two lines disable interrupt P1.yield() // critical section } lock = false ; // put lock back to false After executing TS(r,m) La Critical Section est comme une pièce fermée et le lock en est la clé : on la demande, on rentre et on ferme derrière soit ; on rend la clé en ressortant. Trace : P1 lock false P1 TS(lock) true P1 enter the critical section Timer interrupt P2 TS(lock) true P2 lock true P2 yield() // relâche le et on passe en ready queue P1 lock false P1 CS exécutée Il y autant de critical sections que de variables partagées : ici, il y en a 2 puisque le lock en lui-même est une variable partagée. Ainsi créer des solutions à des problèmes de synchronisation peut faire intervenir d autres CS.

La dernière possibilité est l instruction machine swap, qui peut remplacer le TS. On a swap(m 1,m 2 ) qui échange les contenus des emplacements mémoire. On prend m 2 pour le lock partagé et m 1 pour le lock local (pour chaque processus on a un m 1 ). Cela nous donne la gestion suivante : Processus P 1 : boolean key1 = true ; // local key While(true){ Key 1 = true; do{ swap(key 1, lock) }while(key 1 = true) // critical section lock = false; } Trace : P 1 is executing. Key 1 = true Key 2 = false Lock = true Timer interrupt P 2 is executing Key 2 = true Lock = true Timer interrupt P 1 exits the critical section, puts lock to false Timer interrupt Key 2 = false, enter the critical section P 2 // ces deux lignes sont à la place du yield 3) Solution logicielle : sémaphore Un sémaphore S (aussi dit mutex, ou mutual exclusion) est une variable de type entier accessible uniquement par deux opérations atomiques : acquire (a lock : wait instruction) noté P(s), et release V(s) : Modèle pour acquire Implémentation de la boucle While(s 0){ ; } // busy wait loop while(s 0){ s-- ; // atomique EnableInterrupt() ; // des interrupts sont autorisés dans la boucle DisableInterrupt() ; } L instruction release, notée V(S) est uniquement s++. On la nomme signal instruction. Un exemple : Semaphore mutex = 1 ; P 1 : while(true){ P 2 : while(true){ Acquire(mutex); // mutex.p() Acquire(mutex); // critical section // critical section Release(mutex); // mutex.v() Release(mutex); } } Si l on écrit le code dans un ordre différent, on fait des priorités. Par exemple, A s éxécutera avant B : Semaphore mutex = 0 ; P 1 : A P 2 : Acquire(mutex) Release(mutex) B Si les processus s attendent l un l autre, il y a blocage (deadlock). C est le problème le plus classique lorsqu on veut gérer la concurrence. Le problème devient encore plus compliqué lorsqu il y a deux classes, chacune écrite par un programmeur différent. On ne peut pas savoir qui met quoi dans quel ordre.

Semaphore s = 1, q = 1 ; P 1 : Acquire(s) P 2 : Acquire(q) Acquire(q) Acquire(s) // critical section // critical section Release(s) Release(q) Release(q) Release(s) Dans cette configuration là, la seule solution est d utiliser un AND qui fait l opération d acquisition simultanément sur plusieurs sémaphores. Ainsi, chaque programmeur n a pas à se soucier de l ordre dans lequel son collègue a écrit sa classe. Si s2{0, 1} alors on parle de sémaphore binaire. Si s2n, c est un counting semaphore. L implémentation est exactement la meme. La difference en terme d application est que plusieurs personnes peuvent avoir accès à la section critique, alors que le binaire n en autorise qu une. Exemple : Producer Buffer add in out Consumer Le buffer est une critical section pour lequel on utilise un sémaphore binaire. On utilise aussi un counting semaphore count pour le nombre d objets en buffer. If(count==0) BlockConsumer() // semaphore empty Else if(count == n) BlockProducer() // semaphore full Semaphore mutex = 1 ; Semaphore full = 0 ; Semaphore empty = n ; // le buffer est libre // counting semaphore : au départ aucune cellule n est pleine // un autre counting semaphore Producer : while(true){ Consumer : while(true){ Produce nextitem Acquire Full Acquire empty // n 1 Acquire mutex Acquire mutex Consume item Add NextItem to buffer Release mutex Release Mutex Release Empty Release Full } } Un problème classique est celui des philosophes qui dînent, pour illustrer les deadlock. On a 5 philosophes et 5 baguettes. Chaque philosophe a besoin de deux baguettes pour manger ses nouilles, puis il les repose pour qu un autre les utilise, et pendant ce temps-là il pense. Le but est de synchroniser Les philosophes sont des processus, les baguettes des sémaphores et les nouilles la critical section. Chaque philosophe a une baguette à sa gauche et une à sa droite. La table est un cercle. Ainsi le philosophe 1 a accès aux baguettes 1 et 2, le philosophe 2 aux baguettes 2 et 3,, le philosophe 5 aux baguettes 5 et 1. Le code pour résoudre le problème est le suivant : While(true){ AND(acquire(chopstick[i]),chopstick[(i+1)%5])) ; // eat Release(chopstick[i]); Release(chopstick[(i+1)%5]); // think }

Le problème des readers/writers : on a un fichier qui est une ressource, accédée par certains processus en lecture et en écriture. On autorise plusieurs readers à accéder le fichier, mais s il y a un processus en train d écrire dans le fichier alors personne ne doit pouvoir y accéder. On a donc deux situations : plusieurs readers ou un seul writer. Mettons en place une 1 ère approche par sémaphores. On a deux types de processus, chacun avec son code: Semaphore write_block = 1 ; // initially we are not doing any block at all int read_count = 0; // count how many readers we have Writer : while(true){ Reader : while(true){ acquire(write_block) read_count++; // write to the file if(read_count == 1) acquire(write_block); release(write_block) // read from the file } read_count--; if(read_count==0) release(write_block); } On veut savoir si ce qu on a écrit est bon. Est-ce que toutes les variables partagées sont correctement gérées? Non : read_count est une variable partagée entre les readers, et il faut aussi la synchroniser! On définit un nouveau sémaphore, ce qui entraîne quelques modifications sur le code du reader : Semaphore mutex = 1 ; while(true){ acquire(mutex) ; read_count++ ; if(read_count == 1) acquire(write_block) ; release(mutex); // read from the file acquire(mutex); read_count--; if(read_count == 0) release(write_block); release(mutex); } Faisons une trace de l exécution. Arrivent R 1, R 2, W 1, R 3. R 1 : read_count = 1, write_block = 0, read <timer> R 2 : read_count = 2, read <timer> W 1 : write_block is 0 so we are blocked <timer> R 3 : read_count = 3, read <timer> R 1 : finished, read_count = 2 R 2 : finished, read_count = 1 R 3 : finished, read_count = 0 W 1 : write! On voit qu un writer doit attendre tous les readers, ce qui n est pas génial On va utiliser des monitors plutôt. 4) Solution logicielle : monitor Un monitor est implémenté comme un Abstract Data Type pour lequel sont définies des données privées et des méthodes publiques. Les processus font appels aux méthodes du monitor. Un monitor n autorise qu un seul processus à un moment donné, i.e. plusieurs processus ne peuvent pas exécuter une ou différentes méthodes du monitor à un moment donné ; on parle de Mutual Exclusion Principle. Exemple : monitor shared count { int count ; public entry increment(){ count++ ; } public entry decrement(){ count-- ; } } Les variables de condition sont un type de données qui apparaît seulement dans les monitors. On peut y accéder par trois opérations : - wait (équivalent de Acquire). On suspend le processus qui appelle, et on le met dans une file associée avec la variable de condition. On relâche le monitor. On attend un signal call (on est dans le wait state est un autre processus va nous faire revenir en ready grâce à son signal). - Signal (équivalent de Release). On reprend uniquement un processus de la file associée ; s il n y a aucun processus en attente, alors il n y a pas d effet (différence importante avec release). - Queue. Retourne vrai s il y a au moins un processus en attente, et faux sinon.

Exemple : soit A dans P 1 et B dans P 2 tel que A s exécute avant B, en utilisant des variables de condition. Condition okgo ; P1 : A P2 : okgo.wait() Okgo.signal() B Cependant, il y a un problème ici. On part du principe que P 2 s exécute d abord, il se met en attente, A est fait et va libérer P 2. Cependant, si P 1 exécute en premier, alors il va finir et P 2 va se mettre en attente pour un signal qui ne viendra jamais De même, analysons la solution suivante au problème readers/writers : monitor readerwriter_1 { int numberofreaders = 0; int numberofwriters = 0; boolean busy = FALSE; public: startread() { while(numberofwriters!= 0) ; numberofreaders++; }; finishread() { numberofreaders--; }; startwrite() { numberofwriters++; while(busy (numberofreaders > 0)) ; busy = TRUE; }; finishwrite() { numberofwriters--; busy = FALSE; }; }; Analyse sur la séquence R 1 R 2 W 1 R 3 R 1 : numberofreader = 1, read R 2 : numberofreader = 2, read W 1 : numberofwriters = 1, wait R 3 : wait R 1 : done, numberofreader = 1 R 2 : done, numberofreader = 0 W 1 : writes, numberofwriters = 0 R 3 : numberofreader = 1, numberofreader = 0 C est mieux dans le sens où le writer n a pas à attendre tous les readers Cependant, cette solution est théoriquement fausse car un seul processus peut exécuter dans le monitor. Ainsi, quand W 1 est dans le while loop et puisque cette boucle est dans le monitor alors on a un deadlock. monitor readerwriter_2 { int numberofreaders = 0; boolean busy = FALSE; condition oktoread, oktowrite; public: startread() { if(busy (oktowrite.queue()) oktoread.wait(); numberofreaders++; oktoread.signal(); }; finishread() { numberofreaders--; if(numberofreaders == 0) oktowrite.signal(); }; startwrite() { if((numberofreaders!= 0) busy) oktowrite.wait(); busy = TRUE; }; finishwrite() { busy = FALSE; if(oktoread.queue()) oktoread.signal() else oktowrite.signal() }; }; On utilise donc la solution améliorée ci-contre. Regardons son fonctionnement sur R 1 R 2 W 1 R 3 : R 1. if(busy oktowrite.queue()) est false. NbReader = 1. OkToRead.signal() sans effet. READ R 2. NbReader = 2. READ W 1. NbReader 0, waiting queue of oktowrite, invoke scheduler. R 3. oktowrite() est vrai, waiting queue de oktoread R 1. FINISH READ. NbReader = 1. R 2. FINISH READ. NbReader = 0. Signal the writer W1. W 1. busy = true. WRITE. On entre dans finishwrite(), busy = false, signal the reader R 3. R 3. READ. On entre dans finishread(). nbreader = -1. Que se passe-t-il lorsque R 2 appelle oktowrite.signal()? Il y a deux possibilités d implémentations : - On fait un context switch, R 2 va dans la waiting queue et W 1 passe à l exécution. Il y a un context-switch lorsque W 1 termine, R 2 exécute et termine immédiatement, re-context switch. La condition «nombre de readers à 0» peut ne pas être vrai indéfiniment : un changement de contexte immédiatement nous permet de certifier que la condition qu on veut signaler est toujours vraie. C est la méthode «signal et wait», qui a besoin de plus de context switches. - R 2 termine et passe en terminated state. On fait un context switch à W 1. La condition n est pas re-testée comme c était un if, mais entre temps le nombre de readers peut être différent de 0. Solution est plus rapide mais plus risqué. Méthode signal & continue. Utiliser un while, pas if.

VI. Memory Managment 1) Les différents moments où faire la liaison Le programme de l utilisateur doit passer par plusieurs étapes avant l exécution. L objectif est de comprendre comment les adresses sont transformées durant ces étapes. Les adresses des variables pointent sur des adresses physiques : c est l address binding. Un programme dans le disque peut-être chargé plusieurs fois en mémoire (dû au swap par exemple) et ainsi une même donnée peut se retrouver à des endroits différents lors de chaque chargement, puisqu on a un Random Access Memory. Le but de l address binding est de s assurer que les adresses dans le programme correspondent aux adresses physiques : le address binding peut se passer lors de chacune des étapes. Dans les systèmes d exploitations modernes, on préfère repousser l address binding jusqu au moment de l exécution, ce qui nécessite un support matériel (contrairement aux 2 étapes précédentes). Compile Time 1 Load Time 2 Execution Time 3 In Memory Executable Address Binding at Compile Time. Il faut connaître les emplacements mémoires où le programme va être chargé, sinon il est impossible d écrire une adresse physique. Dès qu on change d emplacement, il faut recompiler le programme. Exemple : int gvax ; 1000 // starting address int proc1(int arg){ 1008 entry proc_a gvar = 7 ; put_record(gvar) ; 1220 load R 1, 7 } 1224 store R 1, 3004 // address de la variable Physical Address = Relative Address C est le type de liaison utilisé dans MS-DOS pour les exécutables.com servant à faire les commandes. Code Source Compilateur Relocatable Object Code Linker Load Module Loader 1228 call 2334 // address de la routine 2334 entry put_record 3004 [gvar space] relative addresses Object Modules Static System Library Dynamic Linking (Runtime Libraries) Le chargement du programme se fera ici à partir de l emplacement mémoire 1000 : il n y a pas le choix. Address Binding at Load Time. L emplacement mémoire d où on charge est inconnu. On génère des relocatable code lors de la compilation. Dans l adresse relative, on affirme que le programme commence à 0000. On aura donc store R 1 2004, call 1334, etc. On parle ici d un espace d adresse logique (logical address space), qui démarre donc à 0. Lorsque le programme est chargé, on met à jour l adresse relative (en utilisant une base address : on l ajoute) et on obtient le physical address space (les adresses réelles). Address Binding at Execution Time. Les programmes peuvent bouger d un endroit à un autre dans la mémoire, donc on fait la liaison au dernier moment : lors de l exécution ; comme on l a vu, il faut un support matériel. Les programmes bougent en mémoire afin de garantir une utilisation optimale. Mettons qu à un temps t 1 le programme P 2 termine. Il n y a pas de bloc continue de plus de 30 Ko, ce qui peut être gênant : on choisit de faire bouger le nouvel espace libre à la fin, et on réduit la fragmentation. Il faut alors qu on décale tous les autres programmes Ainsi, bouger les programmes en mémoire intervient lorsqu on veut réduire la fragmentation. P 1 (110K) P 2 (20K) P 3 (75K) P 4 (80K) Free (32K)