Examen 30 mai 2013. Vol de tâche. Système ENS L3 Info. Année 2012-2013



Documents pareils
Introduction à la programmation concurrente

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

Cours de Systèmes d Exploitation

Recherche dans un tableau

1/24. I passer d un problème exprimé en français à la réalisation d un. I expressions arithmétiques. I structures de contrôle (tests, boucles)

Problèmes liés à la concurrence

Exclusion Mutuelle. Arnaud Labourel Courriel : arnaud.labourel@lif.univ-mrs.fr. Université de Provence. 9 février 2011

Classes et Objets en Ocaml.

Cours de Programmation 2

Suivant les langages de programmation, modules plus avancés : modules imbriqués modules paramétrés par des modules (foncteurs)

Conventions d écriture et outils de mise au point

Table des matières PRESENTATION DU LANGAGE DS2 ET DE SES APPLICATIONS. Introduction

Cours d Algorithmique-Programmation 2 e partie (IAP2): programmation 24 octobre 2007impérative 1 / 44 et. structures de données simples

Les processus légers : threads. Système L3, /31

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

J2SE Threads, 1ère partie Principe Cycle de vie Création Synchronisation

modules & compilation

TP3 : Manipulation et implantation de systèmes de fichiers 1

Exercices INF5171 : série #3 (Automne 2012)

# let rec concat l1 l2 = match l1 with [] -> l2 x::l 1 -> x::(concat l 1 l2);; val concat : a list -> a list -> a list = <fun>

Les arbres binaires de recherche

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

INTRODUCTION AUX SYSTEMES D EXPLOITATION. TD2 Exclusion mutuelle / Sémaphores

Licence Bio Informatique Année Premiers pas. Exercice 1 Hello World parce qu il faut bien commencer par quelque chose...

Prénom : Matricule : Sigle et titre du cours Groupe Trimestre INF1101 Algorithmes et structures de données Tous H2004. Loc Jeudi 29/4/2004

Utilisation d objets : String et ArrayList


IN Cours 1. 1 Informatique, calculateurs. 2 Un premier programme en C

Génie Logiciel avec Ada. 4 février 2013

TD2/TME2 : Ordonnanceur et Threads (POSIX et fair)

Les structures de données. Rajae El Ouazzani

KL5121. Pour activer des sorties en fonction de la position d'un codeur

Threads. Threads. USTL routier 1

Synchro et Threads Java TM

OCL - Object Constraint Language

INITIATION AU LANGAGE C SUR PIC DE MICROSHIP

1-Introduction 2. 2-Installation de JBPM 3. 2-JBPM en action.7

Programme Compte bancaire (code)

Programmation C++ (débutant)/instructions for, while et do...while

Arbres binaires de recherche

STAGE IREM 0- Premiers pas en Python

Plateforme PAYZEN. Définition de Web-services

Cours 2: Exclusion Mutuelle entre processus (lourds, ou légers -- threads)

Info0604 Programmation multi-threadée. Cours 5. Programmation multi-threadée en Java

Cours de Génie Logiciel

Définition des Webservices Ordre de paiement par . Version 1.0

EPREUVE OPTIONNELLE d INFORMATIQUE CORRIGE

Cette application développée en C# va récupérer un certain nombre d informations en ligne fournies par la ville de Paris :

Éléments d informatique Cours 3 La programmation structurée en langage C L instruction de contrôle if

Rappel. Analyse de Données Structurées - Cours 12. Un langage avec des déclaration locales. Exemple d'un programme

03/04/2007. Tâche 1 Tâche 2 Tâche 3. Système Unix. Time sharing

Analyse de sécurité de logiciels système par typage statique

Introduction à la Programmation Parallèle: MPI

//////////////////////////////////////////////////////////////////// Administration bases de données

Ensimag 1ère année Algorithmique 1 Examen 2ième session 24 juin Algorithmique 1

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

Info0101 Intro. à l'algorithmique et à la programmation. Cours 3. Le langage Java

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

Utilitaires méconnus de StrataFrame

NIVEAU D'INTERVENTION DE LA PROGRAMMATION CONCURRENTE

Architecture des ordinateurs TD1 - Portes logiques et premiers circuits

3. SPÉCIFICATIONS DU LOGICIEL. de l'expression des besoins à la conception. Spécifications fonctionnelles Analyse fonctionnelle et méthodes

Cours de Programmation en Langage Synchrone SIGNAL. Bernard HOUSSAIS IRISA. Équipe ESPRESSO

INITIATION AU LANGAGE JAVA

Gestion distribuée (par sockets) de banque en Java

INTRODUCTION À LA PROGRAMMATION CONCURRENTE

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

Cours d introduction à l informatique. Partie 2 : Comment écrire un algorithme? Qu est-ce qu une variable? Expressions et instructions

Argument-fetching dataflow machine de G.R. Gao et J.B. Dennis (McGill, 1988) = machine dataflow sans flux de données

Processus! programme. DIMA, Systèmes Centralisés (Ph. Mauran) " Processus = suite d'actions = suite d'états obtenus = trace

TD2 Programmation concurrentielle

TP n 2 Concepts de la programmation Objets Master 1 mention IL, semestre 2 Le type Abstrait Pile

Présentation du PL/SQL

INF6500 : Structures des ordinateurs. Sylvain Martel - INF6500 1

Cours 1 : La compilation

Exceptions. 1 Entrées/sorties. Objectif. Manipuler les exceptions ;

Corrigé des TD 1 à 5

M2-Images. Rendu Temps Réel - OpenGL 4 et compute shaders. J.C. Iehl. December 18, 2013

Plan. Exemple: Application bancaire. Introduction. OCL Object Constraint Language Le langage de contraintes d'uml

Plan du cours. Historique du langage Nouveautés de Java 7

Java Licence Professionnelle CISII,

Programmation système en C/C++

LES TYPES DE DONNÉES DU LANGAGE PASCAL

Mise en œuvre des serveurs d application

Introduction au langage C

Canevas théoriques du projet sur le poker Partie A

Un ordonnanceur stupide

Introduction : les processus. Introduction : les threads. Plan

École Polytechnique de Montréal. Département de Génie Informatique et Génie Logiciel. Cours INF2610. Contrôle périodique.

Cours Bases de données 2ème année IUT

Langage C. Patrick Corde. 22 juin Patrick Corde ( Patrick.Corde@idris.fr ) Langage C 22 juin / 289

Simulation d un système de paiement par carte bancaire

Algorithmique et Programmation, IMA

Langage et Concepts de ProgrammationOrientée-Objet 1 / 40

Genie Logiciel Avancé Projet :Gestion d une chaîne hotelier low cost

Chapitre 1 : La gestion dynamique de la mémoire

length : A N add : Z Z Z (n 1, n 2 ) n 1 + n 2

Cours d initiation à la programmation en C++ Johann Cuenin

modèles génériques applicables à la synthèse de contrôleurs discrets pour l Internet des Objets

Modélisation des interfaces matériel/logiciel

Transcription:

Système ENS L3 Info. Année 2012-2013 Examen 30 mai 2013 L énoncé est composé de 5 pages. Cette épreuve est prévue pour une durée de 2h. Les notes de cours et de TDs sont autorisées. Vol de tâche Le but de cet exercice est de réaliser une bibliothèque OCaml qui permet d exécuter des tâches indépantes en parallèle en utilisant un ensemble de threads borné. Les tâches seront des fonctions OCaml avec l argument sur lequel elles doivent être appliquées. Cette bibliothèque devra respecter l interface suivante : module type Pool = sig val nb_threads : int val start : ( a -> b) -> a -> unit val run : ( a -> b) -> a -> unit La valeur nb_threads contient le nombre de threads qui vont exécuter les tâches en parallèle. La fonction start f x crée les nb_threads threads et demande le calcule de f x. Enfin, run f x ajoute la nouvelle tâche f x. Question 1. Écrire une première implantation de l interface Pool qui va contenir un ensemble de tâche à exécuter et les nb_threads threads qui iront y chercher du travail a exécuter. Pour représenter l ensemble de tâche, vous pouvez par exemple utiliser le module Queue d OCaml. Ainsi, cette implantation pourra commencer de la façon suivante : module Pool (Config: sig val n: int ) = struct let nb_threads = Config.n let tasks = Queue.create () L ordre d exécution des tâches n a pas d importance. On ne cherche pas à déterminer l arrêt du programme lorsqu il y a plus lorsqu il n y a plus de tâches à exécuter. On supposera que la mémoire est séquentiellement consistante. Dans l implantation précédente, il peut y avoir beaucoup de conflits lors de l accès à la queue partagée. Pour réduire les conflits, chaque thread peut avoir un ensemble de tâches à exécuter et lorsque cet ensemble est vide, il va chercher à voler une tâche à un autre ensemble. Question 2. Indiquer précisément les modifications à faire à l implantation précédente pour réaliser du vol de tâche. 1

Considérons que les ensembles de tâches sont représentés par des queues à double entrées dont l interface est la suivante : module type DEQueue = sig type a t val create: unit -> a t val push_bottom: a -> a t -> unit val pop_bottom: a t -> a option val pop_top: a t -> a option Chaque thread ajoute et retire par les tâches par le bas de la queue et vole des tâches dans les autres ensembles par le haut des autres queues. Une implantation correcte pour ces queues à double entrées est donnée ci-dessous. Elle commence par l implantation de tableaux circulaires : module CircularArray = struct type a t = { content : a array; capacity : int; } let create n init = { content = Array.create n init; capacity = n; } let get t i = t.content.(i mod t.capacity) let put t i v = t.content.(i mod t.capacity) <- v let resize t bottom top = let new_t = create (t.capacity lsl 1) (get t bottom) in for i = top to bottom do put new_t i (get t i) done; new_t Les tableaux sont implantés par un enregistrement qui contient le tableaux (content), la taille du tableau (capacity). Les fonctions get et put permettent de lire et écrire dans le tableau modulairement. La fonction resize crée un tableau deux fois plus grand que le tabeau passé en argument et qui contient les valeurs comprisent entre top et bottom. Les queues sont implantés avec des tableaux circulaires et les indices top et bottom qui représentent les deux bouts de la queue. Plus précisement, bottom contient l indice du premier emplacement vide dans le tableau et la taille de la queue est donnée par la différence bottom - top (la valeur de bottom est supperrieur à la valeur de top lorsque la queue est non vide). Comme nous utilisont des tableaux circulaires, la valeur de top ne sera jamais décrémentée. module DEQueue_seq : DEQueue = struct 2

type a t = { mutable queue: a CircularArray.t; top : int ref; bottom : int ref; mutex: Mutex.t; } let create () = { queue = CircularArray.create (1 lsl 4) (Obj.magic None); top = ref 0; bottom = ref 0; mutex = Mutex.create (); } let atomic f q = Mutex.lock q.mutex; let v = f q in Mutex.unlock q.mutex; v let push_bottom v q = if q.queue.circulararray.capacity - 1 <= size then q.queue <- CircularArray.resize q.queue old_bottom old_top; CircularArray.put q.queue old_bottom v; q.bottom := old_bottom + 1 let push_bottom v q = atomic (push_bottom v) q let pop_bottom q = let new_bottom = old_bottom - 1 in q.bottom := new_bottom; let new_top = old_top + 1 in if size - 1 < 0 then begin q.bottom := old_top; None else begin let v = CircularArray.get q.queue new_bottom in if size - 1 > 0 then begin Some v else begin q.top := new_top; q.bottom := new_top; Some v 3

let pop_bottom q = atomic pop_bottom q let pop_top q = let new_top = old_top + 1 in if size <= 0 then None else let r = CircularArray.get q.queue old_top in q.top := new_top; Some r let pop_top q = atomic pop_top q Cette implantation est correcte car chaque fonction de DEQueue_seq qui modifie une même queue est exécutée en exclusion mutuelle grâce au mutex associé à chaque queue. En utilisant l hypothèse que les vols dans la queue sont fait par le haut et que les opérations faites par le thread associé à la queue sont fait par le bas, le nombre de synchronisations peut être réduit. Question 3. Expliquer le principe d une implantation efficace. Question 4. Réaliser cette implantation. Vous pouvez supposer qu il existe une fonction atomic_set: a ref -> a -> unit qui réalise une affectation de façon atomique et une fonction compare_and_set: a ref -> a -> a -> bool telle que compare_and_set x old_v new_v réalise l affection x := new_v si la valeur de la référence x n a pas été modifiée depuis la dernière fois où elle valait old_v. Question 5 (optionnel). Détecter la fin du traitement de toutes les tâches. Modélisation d un verrou et d écritures concurrentes Le but de cet exercice est de modéliser le mécanisme de verrou ou Mutex d Unix. Vous êtes libre d effectuer cette modélisation en Lustre ou sous forme de systèmes de transition composés en parallèle ou en utilisant le langage de Cubicle. Pour simplifier la modélisation, on considère que le seul type de données nécessaire est le type bool. Le rôle d un verrou est d assurer qu une portion de code s exécute en section critique, c està-dire qu au plus un processus exécute cette section à un instant donné. (* creation/initialisation du verrou *) let m = Mutex.create() in 4

(* un process P1 *) Mutex.lock(m); (* partie P1.critique *) en exclusion mutuelle *) Mutex.unlock(m) Un modèle simple de verrou est un composant à deux entrées : lock, unlock correspondant chacun à l exécution de Mutex.lock(m) et Mutex.unlock(m). Ce système produit une sortie ok avec la convention qu il est présent (ou vrai) lorsque Mutex.lock(m) a réussi, absent (faux) sinon. Question 6. Proposer un modèle de verrou. Dans le cas de Lustre, la signature sera : node mutex(lock, unlock: bool) returns (ok: bool) On considère maintenant deux processus P 1 et P 2 pouvant être exécutés en parallèle. Chacun a accès au verrou partagé m. Du point de vue de la modélisation, P 1 et P 2 produisent respectivement des sorties (c est-à-dire des requêtes) lock1, unlock1 et ont en entrée ok1 pour P 1 ; des sorties lock2, unlock2 et l entrée ok2 pour P 2. node P1(ok1:bool) returns (lock1, unlock1: bool) node P2(ok2:bool) returns (lock2, unlock2: bool) Ces deux processus écrivent dans une mémoire partagée. Une mémoire peut être modélisée par un processus non déterministe qui choisit, de manière interne, de servir une écriture plutôt qu une autre. Le système principal peut être modélisé par la mise en parallèle de quatre processus : node main(oracle:bool) returns (ok1, ok2: bool) var lock1, unlock1, lock2, unlock2, lock, unlock: bool; let (lock1, unlock1) = P1(ok1); (lock2, unlock2) = P2(ok2); (ok1, ok2) = mutex(lock, unlock); (lock, unlock) = memoire(oracle, lock1, lock2, unlock1, unlock2); L oracle est un signal booléen non déterministe pour modéliser le choix interne pour l écriture mémoire. Dans un premier temps, on fait l hypothèse que P 1 et P 2 sont exécutés sur une machine monoprocesseur, c est-à-dire où une seule instruction peut être effectué à un instant donné. Question 7. Comment peut-on exprimer cette hypothèse sur les entrées/sorties lock1, unlock1, ok1, lock2, unlock2, ok2 (sous forme d une propriété booléenne invariante)? Question 8. Proposer une modélisation de la mémoire, par exemple, sous la forme d une définition du noeud memoire, sous cette hypothèse d exécution. Question 9. Proposer une modélisation de la mémoire dans le cas général. Question 10. Quelle est la propriété de sûreté (c est-à-dire vraie à chaque instant) que doivent respecter les sorties ok1 et ok2 pour se convaincre que l implémentation du verrou est correcte? 5