FR 2684467 A1 19930604 FR 9115107 A 19911129 PROCEDE POUR LE TEST ET, EVENTUELLEMENT, LA VALIDATION DES PRIMITIVES D'UN EXECUTIF TEMPS REEL. La présente invention concerne un procédé pour le test et, éventuellement, la validation des primitives d'un exécutif temps réel, c'est-à-dire d'un dispositif logiciel, matériel et/ou microprogrammé, apte à exécuter plusieurs tâches sur un processeur conçu pour n'exécuter qu'une seule tâche à la fois. Elle intéresse, d'une part, les entreprises qui conçoivent et développent des exécutifs temps réel tels que des constructeurs de calculateurs et de microprocesseurs, des constructeurs de compilateurs de langage temps réel, des producteurs de systèmes informatiques ou des industriels développant des applications temps réel avec leur propre exécutif et, d'autre part, des industriels développant des applications temps réel notamment dans les domaines suivants: aéronautique, spatial, nucléaire, ferroviaire, médical, robotique, etc Dans le premier cas, ces entreprises ont besoin de valider leur produit avant de le commercialiser Dans le deuxième cas, ces entreprises ont besoin d'évaluer et de vérifier le fonctionnement des exécutifs proposés sur le 2 - marché afin de choisir le plus adapté à leurs besoins et le plus digne de confiance. On rappelle que chaque tâche d'un exécutif temps réel est assimilable à un flot d'instructions autonomes ("thread of control") qui s'exécute sur le processeur en utilisant l'ensemble des ressources de la machine nécessaires à son exécution: registres, mémoires, périphériques, temps d'exécution, Les tâches sont, a priori, indépendantes Elles peuvent se synchroniser, communiquer ou s'exclure selon des mécanismes offerts par l'exécutif Lorsque les tâches sont implantées sur un seul processeur physique, elles s'exécutent en fait en pseudo-parallélisme car le processeur ne peut exécuter qu'une instruction à la fois. Il y a synchronisation de deux tâches A et B, lorsque la tâche A attend (pour poursuivre son exécution) que la tâche B la libère d'o une idée d'ordre d'exécution des tâches les unes par rapport aux autres Le schéma type est celui du Producteur/Consommateur o la tâche consommatrice attend (pour consommer) que la tâche productrice ait produit. Il y a communication entre deux tâches A et B, lorsque la tâche A utilise des données créées par la tâche B Le schéma type est aussi celui du Producteur/Consommateur o la tâche consommatrice attend (pour consommer) ce que la tâche productrice a produit. Il y a exclusion entre deux tâches A et B, lorsque la tâche A n'est pas autorisée à utiliser une ressource en même temps que la tâche B Par conséquent, la tâche A doit attendre que la tâche B n'utilise plus la ressource pour pouvoir l'utiliser à son tour. 3 - Une tâche peut être placée dans différents états, tels que, par exemple: L'état "tâche morte" (connue de l'application mais qui n'a pas d'attache avec son contexte de lancement): Lors d'une anomalie grave, une ou des tâches peuvent ne plus pouvoir s'exécuter Elles sont alors placées dans l'état "morte" et ne sont plus gérées. L'état "tâche dormante" Dans cet état, qui est celui d'une tâche ayant terminée son exécution ou venant d'être initialisée, la tâche possède tous les paramètres pour démarrer son application. L'état "tâche éligible" dans lequel la tâche est en attente de ressource processeur et peut s'exécuter dès que l'ordonnanceur décide de lui attribuer un processeur. L'état "tâche élue" qui est le fait d'une tâche qui a obtenu la possession du processeur en passant de l'état "éligible" à l'état "élue". L'état "tâche suspendue" qui est le fait d'une tâche élue rencontrant une condition non satisfaite, cette tâche passant à l'état éligible quand cette condition se trouve remplie. A ce dernier titre, elle peut être en attente d'un événement si elle a sous-traité une opération à une autre tâche du système et attend que celle-ci soit terminée. Elle peut être en attente d'une ressource, au sens général, si elle a besoin pour poursuivre son exécution d'une unité matérielle ou logicielle qui n'est pas disponible. Il apparaît donc que les différentes tâches d'un exécutif ne sont pas, en général, complètement indépendantes et 4 - ont besoin, par moment, de se synchroniser, de se communiquer des données et d'accéder à des ressources non partageables. Ainsi, par exemple, une tâche peut être préemptée au profit d'une autre tâche suivant les critères choisis pour l'ordonnancement Si la tâche rencontre, au cours de son exécution, une primitive de suspension inconditionnelle ou une condition non satisfaite la concernant, notamment sur délai, sur écriture dans une boîte aux lettres pleine, sur lecture dans une boîte aux lettres vide, ou sur événement, elle abandonne le processeur au profit d'une autre tâche. Pour tenir compte de ces particularités et pour permettre un tel déroulement, l'exécutif offre (au programmeur) un ensemble de primitives de synchronisation, de communication et de partage des ressources L'utilisation de ces primitives aux seuls endroits nécessaires de l'application multitâche, permet aux différentes tâches de s'exécuter de façon asynchrone les unes des autres. C'est dans cet asynchronisme que se pose le problème de la validation des applications temps réel et, par voie de conséquence, celui de la validation des exécutifs eux- mêmes. En effet, contrairement à un déroulement synchrone, un programme ayant un déroulement asynchrone par le biais des tâches qui le composent, passe par un nombre non dénombrable d'états (au moins d'un point de vue humain) et, par conséquent, la preuve de la cohérence de ces états ne peut être établie. Ceci tient notamment au fait que lors de la réalisation d'un programme, à chaque point du programme, le programmeur maîtrise l'état dans lequel il se trouve et détermine l'état suivant en fonction de l'instruction qui sera exécutée Ce raisonnement est appliqué de la première à la dernière instruction du programme en fixant les données d'entrée du programme et permet donc de prédire les résultats attendus. L'état du programme est grosso modo représenté par la valeur de chacune de ses variables à un instant donné et à un emplacement donné (respectivement désignés par l'horloge interne et par le compteur d'instructions). Lorsque le programme possède plusieurs tâches, le raisonnement peut être appliqué à chacune des tâches à condition que les changements de tâches soient maîtrisés par le programmeur dans l'espace et dans le temps Si cette condition n'est plus remplie, le programmeur n'est plus capable de déterminer l'enchaînement exact des états de son programme. Le programme est alors qualifié non-déterministe (passant par un nombre infini d'états). En fait, on maîtrise habituellement les changements de tâches quand ils ont lieu en des points privilégiés du programme, typiquement lors de l'appel de primitive de l'exécutif L'exécutif est alors réputé "non préemptif". Il s'avère que la plupart des exécutifs temps réel sont préemptifs et ne permettent pas de maîtriser ces changements, et que l'approche que le programmeur utilise pour valider un logiciel déterministe n'est que partiellement applicable à la validation d'un logiciel non déterministe. L'invention a donc plus particulièrement pour but la mise au point d'une solution qui permette de résoudre ces problèmes. 6 - A cet effet, l'invention part de la constatation que tous les exécutifs temps réel n'offrent pas le même jeu de primitives, que les mécanismes qu'ils proposent pour réaliser des synchronisations, des communications, etc diffèrent, mais que tous permettent une exécution concurrente de tâches coopérantes. Elle propose à cet effet, d'une façon générale, un procédé pour le test des primitives d'un exécutif temps réel permettant d'exécuter plusieurs tâches en parallèle sur un processeur conçu pour n'exécuter qu'une seule tâche à la fois, chaque tâche utilisant l'ensemble des ressources de la machine nécessaires à son exécution, et ce, grâce à un ensemble de primitives de synchronisation et de partage des ressources qui permettent aux différentes tâches de s'exécuter, de façon asynchrone. Selon l'invention, ce procédé est caractérisé en ce qu'il consiste à mettre en oeuvre une pluralité de tâches coopérantes, à savoir: un ensemble de tâches concurrentes, bâties sur un même modèle et qui ne diffèrent les unes des autres que par leur contexte statique (désignation, priorité), chacune de ces tâches concurrentes pouvant effectuer une suite d'actions de deux types, déterminées aléatoirement, à savoir: des actions engendrant une progression dans le déroulement de la tâche et des actions consistant en des attentes; une tâche conductrice qui organise la mise en oeuvre des tâches concurrentes et qui règle plus particulièrement le lancement des tâches concurrentes, qui active leur déroulement et qui détecte leur achèvement; et une tâche serveur de ressource interne, telle qu'un distributeur de nombres aléatoires. 7 - Ladite mise en oeuvre comportant: la détermination des priorités respectives des tâches, de manière à répartir leur activité dans le temps et à créer un maximum de cas différents de préemption, une phase préalable comportant: une initialisation de l'horloge temps réel, le lancement de la tâche conducteur, la création de l'ensemble des objets temps réel nécessaires, le lancement des tâches serveur, une succession de phases opératoires, au cours de chacune desquelles la tâche conductrice fait concourir les tâches concurrentes selon un même parcours, cette phase comportant: le choix aléatoire d'un mode de lancement des tâches concurrentes, parmi différents modes de lancements préétablis, le lancement des tâches concurrentes selon le mode de lancement choisi, au moyen de primitives choisies aléatoirement, dans un ordre choisi au hasard, chacune des tâches, une fois lancée, tirant au hasard les susdites actions, la libération des tâches concurrentes, de leur condition d'attente, soit par un épuisement des délais qui les bloquent, soit par un tirage aléatoire de numéros d'événements publics ou privés qui libèrent les tâches concurrentes en attente de ces événements, la détection de l'arrivée de chacune des tâches concurrentes en fin de parcours, la prise en compte et la mémorisation de paramètres caractéristiques de la phase opératoire qui vient de se dérouler, 8 - la modification de l'ordre dans lequel les tâches opératoires vont être relancées au cours de la phase opératoire suivante, le lancement de la phase opératoire suivante, l'analyse des susdits paramètres pendant le déroulement des susdites phases opératoires et/ou à l'achèvement de celles-ci. Selon ce procédé, les phases opératoires ne se répètent jamais et doivent aboutir L'exécution perpétuelle de ces phases opératoires tient lieu de validation Le non- enchainement des courses signifie une anomalie. L'une des particularités du procédé précédemment décrit consiste en ce que, dans un contexte temps réel préemptif, il permet de tester d'un seul coup un maximum de primitives, en fournissant un résultat très simple à vérifier. Il s'agit là d'un avantage particulièrement important, et ce, pour les raisons suivantes: Une première raison résulte du fait que si les primitives d'un exécutif sont testées une par une ou par groupe indissociable, le test est édulcoré car il ne crée aucune situation délicate à l'intérieur de l'exécutif Il se contente de vérifier la bonne passation des arguments et le bon fonctionnement procédural des primitives lors d'un déroulement quasi-séquentiel De ce fait, il s'assimile à un test unitaire du type de celui qui a été déjà réalisé par le fournisseur de l'exécutif. Une deuxième raison consiste en ce que l'application finale, par opposition à l'application de test, utilise un sous-ensemble de primitives plus important que dans un test unitaire sans qu'il soit toujours possible de déterminer à l'avance quels seront ses choix. 9 - Grâce au fait qu'il permet de tester l'ensemble des primitives de l'exécutif dans la même application, le procédé selon l'invention couvre les conditions d'utilisation de l'exécutif par l'application finale. Dans le cas o ces tests sont positifs, on obtient donc une garantie de bon fonctionnement Ce résultat va bien au-delà de celui obtenu par un test d'intégration qui ne teste l'exécutif que dans les conditions d'utilisation propres à une seule application. L'invention sera mieux comprise à la lecture de la description ci-après qui décrit un mode de mise en oeuvre du procédé de test, ainsi que des éléments de programmation utilisés pour la validation des boîtes aux lettres et de l'exécutif temps réel d'un calculateur de la SERIE 7000 développé par la Demanderesse, cet exemple étant illustré par les dessins annexés dans lesquels: Les figures 1 à 4 sont des représentations graphiques montrant les progressions des tâches concurrentes au cours d'une même phase opératoire, à savoir: juste avant la phase opératoire (figure 1), au début de la phase opératoire (figure 2), au milieu de la phase opératoire (figure 3) et à la fin de la phase opératoire (figure 4). Il convient de rappeler tout d'abord qu'un exécutif est dit temps réel, lorsqu'il peut garantir un temps de réponse à l'arrivée d'un événement extérieur périodique (synchrone) ou apériodique (asynchrone), grâce à la connaissance du temps qui s'écoule et qui est mesuré par une horloge, et à des priorités affectées aux différentes tâches, et au caractère préemptif ou non de l'exécutif. Lorsque deux tâches sont de priorités différentes, un exécutif non préemptif favorise l'exécution de la tâche la plus prioritaire Un exécutif préemptif s'assure, - quant à lui, à tout moment, que la tâche la plus prioritaire parmi les tâches exécutables, s'exécute effectivement Lorsqu'une tâche de priorité plus élevée voit sa condition d'attente disparaître, elle préempte la tâche en cours d'exécution pour s'exécuter à son tour. Le procédé selon l'invention propose de tester les primitives d'un exécutif temps réel en faisant concourir un ensemble de tâches coopérantes dites tâches concurrentes bâties sur un même modèle, au cours d'une pluralité de phases opératoires, assimilables chacune à une course Ces phases opératoires sont différentes les unes des autres grâce aux tirages aléatoires du mode de lancement et des actions engendrant une progression ou une attente dans le déroulement des tâches. En fait, ce processus est destiné à créer une multiplicité d'applications multitâche dans lesquelles on trouve des occasions d'utiliser les différents services d'un exécutif. Les phases opératoires sont gérées par une tâche conductrice (conducteur de course) qui donne le coup d'envoi et lance les tâches concurrentes en choisissant aléatoirement pour chacune de ces tâches, un mode de lancement déterminé pris parmi un ensemble de modes de lancement prévus à l'avance, tels que: lancement immédiat inconditionnel, lancement différé en attente d'un événement, lancement différé en attente d'un délai, lui-même aléatoire, etc. Non seulement les tâches concurrentes sont lancées par une primitive choisie au hasard, mais l'ordre dans lequel ces tâches sont lancées est également choisi au hasard. Une fois les tâches concurrentes lancées, la tâche conductrice surveille les registres d'arrivée (achè- vement) des tâches concurrentes. Une fois lancée, chaque tâche concurrente va se voir attribuer au hasard des actions de deux types différents, à savoir: des actions d'un premier type qui consistent en une progression, et des actions d'un second type qui consistent en une attente. Ainsi, aléatoirement, une tâche concurrente pourra faire plusieurs pas successifs avant de s'arrêter. Tant que la totalité des tâches concurrentes n'est par parvenue à son achèvement (fin de la phase opératoire) la tâche conductrice libère les tâches concurrentes de leur condition d'attente, et ce, de la façon suivante: elle tire aléatoirement des numéros d'événements publics ou privés et provoque l'arrivée de ces événements, libérant ainsi les tâches concurrentes qui pouvaient les attendre, les délais qui bloquent les tâches concurrentes s'épuisent d'eux-mêmes, du fait qu'elle est la moins prioritaire (tâche de fond) elle ne reprend la main que lorsque toutes les autres tâches sont bloquées. Quand toutes les tâches concurrentes sont achevées (arrivées à destination) la tâche conductrice modifie aléatoirement l'ordre dans lequel ces tâches vont être relancées pour la phase opératoire suivante. Il apparaît clairement que le procédé précédemment défini permet d'évaluer les performances d'un exécutif sur un processeur donné. il - 12 - En effet, la mesure du temps cumulé au fur et à mesure des phases opératoires et la durée moyenne d'une phase opératoire (recalculée après chacune desdites phases) sont des paramètres intéressants à étudier: Ils permettent d'effectuer au niveau macroscopique des comparaisons, des détections d'anomalie et même des ajustements Ce procédé ne peut pas en effet mesurer le temps d'une primitive déterminée, mais il permet d'apprécier une performance globale. Un autre avantage du procédé selon l'invention consiste en ce qu'il permet à un réalisateur d'exécutif de comparer différentes solutions. Outre les tâches concurrentes et la tâche conductrice, le procédé selon l'invention peut faire intervenir au moins une tâche serveur de ressource externe (périphérique) telle qu'une tâche de gestion d'un écran, une tâche serveur de ressource interne (calcul) telle que le distributeur de nombres aléatoires utilisés dans le procédé, et une tâche cyclique. En effet, la progression des tâches concurrentes peut être avantageusement figurée sur un écran de visualisation de type classique par exemple de 24 lignes/80 colonnes pouvant être adressé en XY Comme cet écran constitue une ressource non partageable, il se trouve donc géré par la tâche de type serveur qui regroupe et traite dans l'ordre d'arrivée toutes les demandes de visualisation qui lui parviennent des autres tâches. Ainsi, par exemple, les demandes lui arrivent sous la forme de messages déposés dans une boite aux lettres Les tâches préparent leur message et l'envoient (primitive "SEND") dans la boîte Si la boîte est pleine, les tâches sont bloquées en attendant de pouvoir déposer leur message et reprendre la main De son côté, la tâche 13 - serveur de ressources externes ("DISPLAYTASK") boucle sur la réception de message (primitive "RECEIVE") et le traitement du message reçu Si la boîte est vide, la tâche serveur est bloquée en attente de recevoir un nouveau message Ces messages décrivent le type d'entrée/sortie qui doit être réalisé pour le compte de la tâche appelante Typiquement, les messages contiennent les informations suivantes: le numéro de ligne et le numéro de colonne d'écran, le type (entier, caractère, chaîne de caractères,), la valeur de l'entier, du caractère ou de la chaîne de caractères. L'indivisibilité de la suite de caractères émis vers le périphérique est assurée par cette tâche serveur de ressources externes qui traite complètement une demande avant de prendre en compte la demande suivante, et ce, quelle que soit la priorité des tâches appelantes. La tâche distributeur de nombres aléatoires ("RANDOMTASK") se charge de distribuer les nombres aléatoires utilisés par les tâches En effet, au lieu de prévoir des tâches possédant leur propre générateur de nombres aléatoires, il s'est avéré préférable de faire une tâche de type serveur qui calcule et fournit tous les nombres aléatoires demandés par l'ensemble des tâches. Ainsi, par exemple, les nombres aléatoires sont déposés dans une boîte aux lettres ("RANDOMBOX") Les tâches qui désirent obtenir un nombre se mettent en réception sur la boîte (primitive "RECEIVE") Si la boîte est vide, les tâches appelantes sont bloquées en attendant de pouvoir extraire un nombre et poursuivre leur exécution De son côté, la tâche serveur de ressources internes ("RANDOMTASK"), ici une tâche distributeur de nombres aléatoires boucle sur le calcul d'un nombre aléatoire et l'envoi du nombre (primitive "SEND") dans la boîte Si la 14 - boîte est pleine, la tâche serveur est bloquée en attente de pouvoir déposer un nouveau nombre. La tâche cyclique, complètement indépendante des autres tâches, impose de façon périodique, deux régimes de vitesse qui influent sur le déroulement des tâches concurrentes lors des différentes phases opératoires. Cette tâche cyclique utilise, par exemple, un événement "SPEED EV" qu'elle bascule à chaque nouveau cycle Elle utilise pour cela trois primitives: une première primitive "TEST EVENT" pour connaître l'état dans lequel il se trouve, une deuxième primitive "SETEVENT" pour le mettre à l'état arrivé (vitesse lente), une troisième primitive "RESETEVENT" pour le mettre à l'état non-arrivé (vitesse rapide). Comme cette tâche est cyclique et ne peut pas se permettre de prendre le moindre retard, elle affiche son état (vitesse rapide/lente) par un message envoyé conditionnellement (primitive "TESTANDSEND") vers le serveur d'écran. Toutes les tâches précédemment évoquées jouent un rôle important, en ce sens qu'elles oht un travail substantiel à faire qui représente un taux non négligeable d'occupation du processeur. En outre, les priorités respectives de ces tâches sont réglées de façon à répartir leur activité dans le temps et à créer un maximum de cas différents de préemption. Comme précédemment mentionné, la tâche conductrice est la moins prioritaire, puisque c'est la tâche de fond La tâche serveur de ressource externe ("DISPLAYTASK") est un niveau plus prioritaire, puis viennent les tâches concurrentes qui sont réparties de préférence sur - plusieurs niveaux de priorité croissants La tâche serveur de ressource interne ("RANDOMTASK") a un niveau de priorité correspondant sensiblement au niveau moyen des priorités des tâches concurrentes La tâche cyclique ("SPEED TASK") se voit attribuer la plus haute priorité, pour garantir sa cyclicité. Dans cet exemple, les tâches concurrentes sont au nombre de vingt, regroupées en deux groupes de dix dans chacun desquels les tâches concurrentes ont des priorités allant en décroissant, les valeurs moyennes des priorités (force) de ces deux groupes étant sensiblement égales. Chaque tâche est représentée à l'écran par une simple lettre (ou une série de lettres identiques présentées sous la forme d'un histogramme) qui se déplace le long d'un parcours de 77 pas élémentaires (piste) au fur et à mesure de l'avancement de la tâche Le premier groupe comprend les tâches A à J, tandis que le second groupe comprend les tâches K à T. La phase préalable du procédé selon l'invention comprend ici, dans l'ordre: l'initialisation de l'horloge temps réel de l'exécutif, le lancement de la tâche conductrice, la création de l'ensemble des objets temps réels nécessaires tels que les boîtes aux lettres, le lancement des deux tâches serveur (gérant d'écran et distributeur de nombres aléatoires). Au départ de la phase opératoire, la tâche conducteur efface l'écran, affiche le parcours que doit suivre chacune des tâches (figure 1) ainsi que des renseignements d'ordre général, tels que: le numéro de la prochaine phase opératoire (ou course), le temps total des phases opératoires déjà réalisées, 16 - le temps moyen d'une phase opératoire, etc. Les parcours de chacune des tâches concurrentes peuvent comprendre des "obstacles" communs gérés en ressource non partageable, chacun de ces "obstacles" ne pouvant être franchi que par une seule tâche concurrente à la fois. Lorsqu'une tâche se trouve face à un obstacle, elle doit attendre pour le franchir que l'obstacle se libère A cet effet, en arrivant sur un obstacle, chaque tâche demande l'accès à la ressource correspondante par une primitive "RESERVE" ou par une primitive "TESTANDRESERVE", selon le cas, et libère en fin d'obstacle la ressource qu'elle occupait, par une primitive "FREE" Eventuellement, une tâche concurrente pourra, par exemple, franchir un obstacle occupé sans attendre qu'il se libère, si elle obtient un bonus par tirage aléatoire et si la tâche cyclique affiche une condition déterminée (par exemple vitesse rapide). Chaque tâche concurrente effectue sa progression jusqu'à ce qu'elle atteigne la fin du parcours (ligne d'arrivée). Dans ce dernier cas, les tâches concurrentes inscrivent leur nom sur un registre qui est consulté en permanence par la tâche conductrice pour détecter la fin d'une phase opératoire, en vue d'en relancer une nouvelle Ainsi, par exemple, les tâches concurrentes ayant passé la ligne d'arrivée déposent (primitive "SEND") dans une boîte aux lettres ("ATENDBOX") leur code d'identification, attestant par là-même qu'elles ont bien terminé leur parcours et ne sont pas restées bloquées en chemin De son côté, la tâche conductrice extrait les codes d'identification des tâches concurrentes qui peuvent s'être inscrites depuis sa dernière consultation (primitive "TESTANDRECEIVE"). Les tâches sont classées selon leur ordre d'arrivée en fin de parcours De la même manière que précédemment, la 17 - tâche conductrice envoie dans la boite aux lettres adéquate (tâche "RANKBOX") le nombre de classements, a priori, retenus avant le démarrage des tâches concurrentes, les dernières tâches arrivées n'étant pas départagées Dans cet exemple, seules les quatre premières tâches concurrentes sont classées, étant entendu que ce type de classement est purement arbitraire Comme précédemment mentionné, la tâche conductrice surveille le registre d'arrivée des tâches concurrentes et, tant qu'elle n'a pas son compte signifiant que la phase opératoire est terminée, elle va elle-même libérer les tâches concurrentes de leur condition d'attente de la façon suivante: elle tire aléatoirement des numéros d'événements publics ou privés et provoque l'arrivée de ces événements, libérant ainsi les tâches concurrentes qui pouvaient les attendre Les délais qui bloquent les tâches concurrentes s'épuisent d'eux-mêmes Ainsi, par exemple, les tâches concurrentes se bloquent grâce à des primitives "WAITDELAY" et "WAITEVENT" Les attentes sur événement se font, soit sur un événement privé attaché à chaque tâche concurrente ("CONCUREV"), soit sur un événement public commun à toutes les tâches concurrentes "DRIVER EV" La tâche conductrice débloque ces tâches par la primitive "PULSEEVENT" sur ces événements. En tant que tâche de fond, la tâche conductrice ne reprend la main que lorsque toutes les autres tâches sont bloquées (autrement dit, lorsqu'il n'y a rien de mieux à faire, on décide de faire progresser la phase opératoire). Si l'exécutif offre une primitive d'arrêt de périodicité des tâches cycliques, celle-ci peut être testée sur la tâche vitesse, dès qu'une tâche concurrente est arrivée. On vérifie visuellement que le reste de la course se déroule avec les mêmes conditions de vitesse. 18 - Dans l'exemple précédemment décrit, le procédé selon l'invention s'appliquait à une configuration monoprocesseur Il importe de noter à ce sujet que ce procédé s'applique également au test des exécutifs multiprocesseurs puisque toutes les relations inter-tâche se font par l'entremise de l'exécutif et qu'aucune tâche n'a la visibilité directe d'un objet manipulé par une autre tâche Il est donc tout à fait possible de répartir les tâches dans des mémoires séparées dès l'instant que l'exécutif offre des primitives de communication de données La répartition des tâches sur les différents processeurs n'est qu'une question d'imagination. Ainsi, dans une configuration biprocesseur, le premier processeur pourra être affecté à la tâche conductrice, à la tâche cyclique et aux tâches concurrentes Le deuxième processeur pourra être affecté aux deux tâches serveur (externe et interne). Dans une configuration quadriprocesseur, le premier processeur pourra être affecté, par exemple, à la tâche conductrice et à la tâche cyclique, le deuxième processeur aux tâches concurrentes, le troisième processeur à la tâche serveur interne et le quatrième processeur à la tâche serveur externe. Bien que le non-déterminisme soit la caractéristique primordiale du procédé selon l'invention, il est néanmoins possible de le rendre déterministe par exemple dans un but de répétitivité. Une première solution consiste à supprimer tout ce qui a rapport au temps, comme les attentes sur délais et les tâches cycliques. Une autre solution plus intéressante, quand on peut maîtriser l'écoulement du temps au niveau de l'exécutif, est de simuler des tops horloge et de faire en sorte que 19 - lorsque la tâche conductrice reprend la main, (toutes les tâches concurrentes étant bloquées sur une condition d'attente quelconque) elle puisse provoquer l'équivalent d'un top horloge et faire en sorte que le temps s'écoule, mais d'une façon synchrone aux tâches. Bien entendu, toute version déterministe offre une couverture de tests beaucoup moins importante que la version non-déterministe. L'exemple de mise en oeuvre du procédé selon l'invention, qui est décrit ci-après, est destiné à assurer la validation des boîtes aux lettres et de l'exécutif temps réel (de type préemptif) des calculateurs commercialisés sous la dénomination SERIE 7000 par la Demanderesse et dont on souhaite tester les primitives suivantes: TASK (tâche) lance la tâche spécifiée immédiatement. TASK EVENT (tâche, événement) lance la tâche spécifiée en attente de l'événement spécifié Si l'événement est déjà arrivé, cette primitive est équivalente à un TASK. TASKDELAY (tâche, délai) lance la tâche spécifiée en attente du délai spécifié Si le délai est déjà épuisé, cette primitive est équivalente à un TASK. CYCLE (tâche, période) lance la tâche spécifiée immédiatement La tâche sera automatiquement relancée à la période spécifiée. ENDCYCLE (tâche) arrête la périodicité de la tâche spécifiée sans arrêter la tâche. ENDTASK arrête l'exécution de la tâche en cours La tâche devra être relancée par une primitive de lancement. - SETEVENT (événement) passe l'événement spécifié dans l'état arrivé Toutes les tâches en attente de cet événement sont libérées. RESETEVENT (événement) passe l'événement spécifié dans l'état non-arrivé. TESTEVENT (événement, compte rendu) fournit l'état de l'événement spécifié dans le compte rendu. PULSEEVENT (événement) passe l'événement spécifié dans l'état arrivé puis dans l'état non-arrivé de façon indivisible Toutes les tâches en attente de cet événement sont libérées. WAITEVENT (événement) bloque la tâche en attente de l'événement spécifié s'il n'est pas déjà arrivé sinon ne fait rien. RESERVE (ressource) demande l'accès à la ressource spécifiée Si la ressource est libre, la tâche continue son exécution en occupant la ressource Si la ressource est occupée, la tâche est bloquée en attente de libération de la ressource. TEST AND RESERVE (ressource, compte rendu) teste et demande l'accès à la ressource spécifiée Le compte rendu indique l'état de la ressource Si la ressource est libre, la tâche continue son exécution en occupant la ressource Si la ressource est occupée, la tâche continue son exécution sans occuper la ressource. FREE (ressource) libère l'accès à la ressource spécifiée. Si plusieurs tâches sont en attente de cette ressource, elle est attribuée à la tâche la plus prioritaire qui reprend son exécution. 21 - WAITDELAY (délai) bloque la tâche en attente du délai spécifié s'il n'est pas déjà épuisé sinon ne fait rien. TIMER décrémente les compteurs de délai et de période gérés par l'exécutif Cette primitive est normalement placée dans la procédure d'interruption Horloge Temps Réel Elle prévient l'exécutif de l'écoulement du temps. SCHEDULE permet d'ordonnancer les tâches lorsque la primitive TIMER est utilisée en dehors d'une procédure d'interruption. SEND (boîte aux lettres, message) envoie le message spécifié dans la boîte aux lettres spécifiée Si la boite n'est pas pleine, le message est déposé et la tâche continue son exécution Si la boîte est pleine, la tâche est bloquée en attente de pouvoir déposer son message. TESTANDSEND (boîte aux lettres, message, compte rendu) tente d'envoyer le message spécifié dans la boîte aux lettres spécifiée Le compte rendu indique l'état de la boîte (pleine ou non) Si la boîte n'est pas pleine, le message est déposé et la tâche continue son exécution Si la boîte est pleine, la tâche continue son exécution sans avoir déposé son message. RECEIVE (boîte aux lettres, message) reçoit le message spécifié de la boîte aux lettres spécifiée Si la boîte n'est pas vide, le plus ancien message est extrait et la tâche continue son exécution Si la boite est vide, la tâche est bloquée en attente de pouvoir recevoir un message. TESTANDRECEIVE (boîte aux lettres, message, compte rendu) tente de recevoir le message spécifié de la boîte aux lettres spécifiée Le compte rendu indique l'état de la boîte (vide ou non) Si la boîte n'est pas vide, le plus ancien message est extrait et la tâche continue son 22 2684467 exécution Si la boîte est vide, la tâche continue son exécution sans avoir reçu de message. Dans cet exécutif La priorité des tâches est comprise entre O (la plus haute) et 63 (la plus basse) et toutes les tâches ont une priorité différenciée Les tâches sont identifiées par un numéro qui correspond à leur priorité. Les événements, les ressources et les boîtes aux lettres sont également identifiées par un numéro. Les événements sont initialement dans l'état non- arrivé, les ressources dans l'état libre et les boîtes aux lettres dans l'état vide. Les tâches concurrentes, au nombre de 10, sont réparties en deux groupes dans lesquels elles sont respectivement désignées par les termes CONCUR (A à J) et CONCUR (K à T). Le procédé selon l'invention, qui est exécuté par un programme, commence par un appel à la procédure d'interruption de montée d'alimentation Dès que l'Horloge Temps Réel est initialisée, la procédure d'interruption Horloge Temps Réel est automatiquement appelée par le matériel à la cadence choisie. Le programme possède les objets globaux suivants boîte aux lettres DISPLAY BOX boîte aux lettres RANDOMBOX boîte aux lettres RANKBOX boîte aux lettres ATENDBOX événement commun SPEEDEV événement commun DRIVEREV 23 événement privé CONCURAEV événement privé CONCUR B EV événement privé CONCURCEV événement privé CONCURTEV ressource GATE 1 _RES ressource GATE 2 _RES ressource GATE 3 _RES ressource GATE 4 _RES Procédure d'interruption de montée d'alimentation Initialisation de l'Horloge Temps Réel à la cadence d'l ms (version non- déterministe uniquement) Initialisation du Temps Absolu à O appel primitive TASK (DRIVER_TASK) pour lancer la tâche conductrice Fin d'interruption Procédure d'interruption Horloge Temps Réel (version non- déterministe) Incrémenter le Temps Absolu appel primitive TIMER Fin d'interruption Tâche DRIVERTASK priorité 23 Initialiser le nombre de courses à O Création des objets Temps Réels boîtes aux lettres appel primitive TASK (RANDOM_TASK) pour lancer le serveur de nombres aléatoires appel primitive TASK (DISPLAY TASK) pour lancer le serveur d'écran Répéter appel NEWRACE Indéfiniment Fin DRIVER TASK 24 - Procédure NEWRACE Effacer l'écran appel DISPLAY TRACK appel DISPLAYRACE appel quatre fois primitive SEND (RANKBOX) pour classer les quatre premières tâches concurrentes Pour toutes les tâches concurrentes prises dans un ordre a priori appel STARTCONCUR (paramètres de la tâche concurrente) Fin Pour appel primitive CYCLE (SPEED_TASK) pour lancer cycliquement la tâche cyclique avec une période comprise aléatoirement entre 100 ms et 1 s Répéter appel TICK (version déterministe uniquement) Tirer un nombre entre 1 et 21 Cas 1: appel primitive PULSEEVENT (CONCURAEV) événement privé Cas 2: appel primitive PULSEEVENT (CONCURBEV) événement privé Cas 3: appel primitive PULSEEVENT (CONCURCEV) événement privé Cas 19: appel primitive PULSEEVENT (CONCURSEV) événement privé Cas 20: appel primitive PULSEEVENT (CONCURTEV) événement privé Cas 21: appel primitive PULSE_EVENT (DRIVER_EV) événement commun Fin des Cas appel TESTATEND Si une première tâche concurrente est arrivée appel primitive END_CYCLE (SPEED_TASK) pour arrêter la cyclicité de la tâche cyclique Fin Si Jusqu'à ce que toutes les tâches concurrentes soient arrivées - Mélanger l'ordre de départ des tâches concurrentes pour la prochaine course Fin NEWRACE Procédure START CONCUR (CONCUR TASK) Tirer un nombre entre 1 et 3 Cas 1: appel primitive TASK (CONCUR_TASK) pour lancement immédiat de la tâche concurrente Cas 2: appel primitive TASK_EVENT (CONCURTASK) pour lancement différé de la tâche concurrente en attente de son événement privé Cas 3: appel primitive TASK_EVENT (CONCUR_TASK) pour lancement différé de la tâche concurrente en attente d'un délai compris aléatoirement entre O et 100 ms Fin des Cas Fin START-CONCUR Procédure TESTAT END Répéter appel primitive TEST_AND_RECEIVE (AT_END_BOX) pour tenter de recevoir un message Si message reçu alors inscrire la tâche concurrente arrivée au registre Jusqu'à l'épuisement des messages en attente Fin TESTAT END Procédure DISPLAYTRACK Préparer un message pour afficher la piste: Pour tous les caractères qui constituent la piste appel primitive SEND (DISPLAY_BOX) pour envoyer ce caractère Fin Pour Fin DISPLAY TRACK Procédure DISPLAYRACE Incrémenter le nombre de courses entre les tâches concurrentes Préparer un message pour afficher le numéro de course: 26 - le texte "Phase no" en ligne 24, colonne 1 appel primitive SEND (DISPLAY_BOX) pour envoyer ce texte le numéro de course en ligne 24, colonne 10 appel primitive SEND (DISPLAY_BOX) pour envoyer ce nombre Préparer un message pour afficher le temps total des courses: le texte "Temps total" en ligne 24, colonne 30 appel primitive SEND (DISPLAY_BOX) pour envoyer ce texte le temps total en ms en ligne 24, colonne 42 appel primitive SEND (DISPLAYBOX) pour envoyer ce nombre Préparer un message pour afficher le temps moyen d'une course: le texte "Temps moyen" en ligne 24, colonne 50 appel primitive SEND (DISPLAYBOX) pour envoyer ce texte le temps moyen en ms en ligne 24, colonne 62 appel primitive SEND (DISPLAYBOX) pour envoyer ce nombre Fin DISPLAYRACE Procédure TICK (appelée uniquement dans la version déterministe) Incrémenter le Temps Absolu appel primitive TIMER appel primitive SCHEDULE Fin TICK Fonction RANDOM appel primitive RECEIVE (RANDOMBOX) pour recevoir un message Renvoyer le nombre aléatoire flottant appartenant à l'intervalle ( 0 0 compris et 1 0 non compris) contenu dans le message Fin RANDOM 27 - Tâche CONCURRENTEATASK priorité 1 La tâche concurrente A va courir sur la ligne No 1 à partir de la colonne 1 appel MOVECONCUR (paramètres de la tâche concurrente A) Fin CONCURA TASK Tâche CONCURRENTEBTASK priorité 3 La tâche concurrente B va courir sur la ligne No 2 à partir de la colonne 1 appel MOVECONCUR (paramètres de la tâche concurrente B) Fin tâche CONCURRENTEBTASK Tâche CONCURRENTE C TASK priorité 5 La tâche concurrente C va courir sur la ligne No 3 à partir de la colonne 1 appel MOVECONCUR (paramètres de la tâche concurrente C) Fin tâche CONCURRENTECTASK Tâche CONCURRENTEDTASK priorité 7 La tâche concurrente D va courir sur la ligne No 4 à partir de la colonne 1 appel MOVECONCUR (paramètres de la tâche concurrente D) Fin tâche CONCURRENTEDTASK Tâche CONCURRENTE E TASK priorité 9 La tâche concurrente E va courir sur la ligne No 5 à partir de la colonne 1 appel MOVECONCUR (paramètres de la tâche concurrente E) Fin tâche CONCURRENTEETASK Tâche CONCURRENTE F TASK priorité 12 28 - La tâche concurrente F va courir sur la ligne No 6 à partir de la colonne 1 appel MOVECONCUR (paramètres de la tâche concurrente F) Fin tâche CONCURRENTEF TASK Tâche CONCURRENTEGTASK priorité 14 La tâche concurrente G va courir sur la ligne No 7 à partir de la colonne 1 appel MOVE CONCUR (paramètres de la tâche concurrente G) Fin tâche CONCURRENTEG TASK Tâche CONCURRENTEHTASK priorité 16 La tâche concurrente H va courir sur la ligne No 8 à partir de la colonne 1 appel MOVECONCUR (paramètres de la tâche concurrente H) Fin tâche CONCURRENTEHTASK Tâche CONCURRENTE I TASK priorité 18 La tâche concurrente I va courir sur la ligne No 9 à partir de la colonne 1 appel MOVECONCUR (paramètres de la tâche concurrente I) Fin tâche CONCURRENTEITASK Tâche CONCURRENTEJTASK priorité 20 La tâche concurrente J va courir sur la ligne No 10 à partir de la colonne 1 appel MOVECONCUR (paramètres de la tâche concurrente J) Fin tâche CONCURRENTEJ TASK Tâche CONCURRENTE K TASK priorité 2 La tâche concurrente K va courir sur la ligne No 12 à partir de la colonne 1 29 - appel MOVECONCUR (paramètres de la tâche concurrente K) Fin tâche CONCURRENTEKTASK Tâche CONCURRENTELTASK priorité 4 La tâche concurrente L va courir sur la ligne No 13 à partir de la colonne 1 appel MOVECONCUR (paramètres de la tâche concurrente L) Fin tâche CONCURRENTELTASK Tâche CONCURRENTE M TASK priorité 6 La tâche concurrente M va courir sur la ligne No 14 à partir de la colonne 1 appel MOVECONCUR (paramètres de la tâche concurrente M) Fin tâche CONCURRENTEMTASK Tâche CONCURRENTENTASK priorité 8 La tâche concurrente N va courir sur la ligne No 15 à partir de la colonne 1 appel MOVECONCUR (paramètres de la tâche concurrente N) Fin tâche CONCURRENTENTASK Tâche CONCURRENTE O TASK priorité 10 La tâche concurrente O va courir sur la ligne No 16 à partir de la colonne 1 appel MOVECONCUR (paramètres de la tâche concurrente O) Fin tâche CONCURRENTEOTASK Tâche CONCURRENTEPTASK priorité 13 La tâche concurrente P va courir sur la ligne No 17 à partir de la colonne 1 appel MOVECONCUR (paramètres de la tâche concurrente P) Fin tâche CONCURRENTE P TASK - Tâche CONCURRENTE Q TASK priorité 15 La tâche concurrente Q va courir sur la ligne No 18 à partir de la colonne 1 appel MOVECONCUR (paramètres de la tâche concurrente Q) Fin tâche CONCURRENTE Q TASK Tâche CONCURRENTERTASK priorité 17 La tâche concurrente R va courir sur la ligne No 19 à partir de la colonne 1 appel MOVECONCUR (paramètres de la tâche concurrente R) Fin tâche CONCURRENTER TASK Tâche CONCURRENTE S TASK priorité 19 La tâche concurrente S va courir sur la ligne No 20 à partir de la colonne 1 appel MOVECONCUR (paramètres de la tâche concurrente S) Fin tâche CONCURRENTESTASK Tâche CONCURRENTETTASK priorité 21 La tâche concurrente T va courir sur la ligne No 21 à partir de la colonne 1 appel MOVECONCUR (paramètres de la tâche concurrente T) Fin tâche CONCURRENTETTASK Procédure MOVE CONCUR (paramètres d'une tâche concurrente) Afficher la désignation de la tâche concurrente en question sur sa ligne en première colonne Répéter Tirer un nombre aléatoire entre 1 et 6 Cas 1: appel primitive TESTEVENT (SPEED- EV) pour savoir dans quelle condition de vitesse on se trouve Si rapide alors appel STEP (rapide et pas de bonus) 31 - Si lent alors appel STEP (lent et pas de bonus) Cas 2: appel primitive TESTEVENT (SPEEDEV) pour savoir dans quelle condition de vitesse on est Si rapide alors appel STEP (rapide et pas de bonus) Si lent alors on ne fait rien Cas 3: appel primitive TESTEVENT (SPEEDEV) pour savoir dans quelle condition on est Si rapide alors appel STEP (rapide et bonus) Si lent alors on ne fait rien Cas 4: appel primitive WAITEVENT (CONCUREV) pour attendre son événement privé Cas 5: appel primitive WAITEVENT (DRIVEREV) pour attendre l'événement commun Cas 6: appel primitive WAITDELAY pour attendre un délai tiré aléatoirement entre O et 100 ms Fin des Cas Jusqu'à ce que la tâche concurrente soit en colonne 77 appel DISPLAYRANK pour afficher son classement appel ATEND pour s'inscrire à l'arrivée appel primitive END TASK pour terminer la tâche concurrente en cours Fin MOVECONCUR Procédure STEP (vitesse et bonus) Si la tâche concurrente est face à un obstacle ("l") alors Si il bénéficie d'un bonus alors appel primitive TESTANDRESERVE (GATERES) pour tenter de réserver la ressource obstacle Si la ressource était occupée (elle n'est pas réservée) alors sauter complètement l'obstacle Fin Si Sinon appel primitive RESERVE (GATERES) pour réserver la ressource obstacle Fin Si 32 - Sinon Si la tâche concurrente est sur l'obstacle ("l") alors appel primitive FREE (GATERES) pour ressource obstacle Fin Si Avancer la tâche concurrente d'une colonne Si la vitesse est rapide alors Afficher la lettre identifiant la tâche en majuscules sur sa ligne et sa colonne Sinon Afficher la lettre identifiant la tâche en minuscules sur sa ligne et sa colonne Fin Si Fin STEP la fin de libérer la concurrente concurrente Procédure DISPLAYRANK appel primitive TESTANDRECEIVE (RANKBOX) pour tenter de recevoir un message contenant un classement Si un message a été reçu alors Afficher le classement en colonne 79 de la ligne de la tâche concurrente Fin Si Fin DISPLAY RANK Procédure ATEND Préparer le message donnant l'identification de la tâche concurrente appel primitive SEND (AT END BOX) pour envoyer le message Fin ATEND Tâche DISPLAYTASK priorité 22 Initialiser le périphérique écran (vitesse, parité, etc) Effacer l'écran Répéter appel primitive RECEIVE (DISPLAYBOX) en vue d'exploiter le message reçu 33 2684467 Envoyer le curseur de l'écran sur la ligne et la colonne spécifiées Ecrire à l'écran selon le type de valeur spécifié: Cas caractère: Afficher le caractère Cas chaîne de caractères: Afficher chaîne de caractères Cas nombre entier: Afficher le nombre entier etc Fin des Cas Indéfiniment Fin DISPLAYTASK Tâche SPEED TASK priorité O appel primitive TEST_EVENT (SPEEDEV) pour tester l'état de l'événement Si l'événement est arrivé ce qui correspond au régime lent, alors appel primitive RESETEVENT (SPEEDEV) pour le mettre à non-arrivé appel DISPLAYSPEED (rapide) Sinon c'est qu'on est en régime rapide appel primitive SET-EVENT (SPEED_EV) pour le mettre à arrivé appel DISPLAYSPEED (lent) Fin Si Fin SPEEDTASK Procédure DISPLAYSPEED (vitesse) préparer le message à afficher en ligne 24, colonne 20 Si la vitesse est lente alors le message est "lent" en minuscules Sinon le message est "RAPIDE" en majuscules Fin Si appel primitive TEST_ANDSEND (DISPLAY_BOX) pour envoyer le message Fin DISPLAY SPEED 34 - Tâche RANDOMTASK priorité 11 Initialiser le générateur de nombres pseudo-aléatoires Répéter Calculer un nombre aléatoire et le ranger dans le message appel primitive SEND (RANDOM BOX) pour envoyer le message Indéfiniment Fin RANDOMTASK La progression des tâches concurrentes peut être visualisée à l'écran selon le mode de représentation illustré par les figures 1 à 4 sur lesquelles: le parcours commun des tâches concurrentes est représenté par une ligne horizontale en traits interrompus (chaque segment indiquant une progression de un pas) et les obstacles sont indiqués par des espaces entre crochets pouvant comprendre un ou plusieurs pas, selon leur importance; chaque tâche concurrente est représentée par une lettre (en majuscule dans la première condition de la tâche cyclique et en minuscule dans la seconde condition de la tâche cyclique) qui se déplace parallèlement en parcours commun, la progression de cette tâche étant indiquée sous la forme d'un histogramme; les tâches concurrentes sont réparties en deux groupes (de A jusqu'à J et de K à T) respectivement disposés en-dessus et en-dessous du parcours commun; des indications utiles telles que, par exemple, le numéro de la phase opératoire, la condition imposée par la tâche cyclique, le temps total de la phase opératoire, et le temps moyen des phases opératoires précédemment exécutées (fenêtres 11, 12, 13, 14); les numéros 1, 2, 3 situés dans la marge droite 15 (figures 3 et 4) désignent les trois premières tâches concurrentes dans l'ordre de leur arrivée En final, seules les quatre premières tâches concurrentes sont - signalées dans cette fenêtre, ce paramètre étant réglable. Dans l'instant qui précède le départ d'une phase opératoire, seul le parcours est représenté à l'écran (figure 1) Au moment du départ, les tâches concurrentes apparaissent sur une ligne verticale de départ de la façon indiquée sur la figure 2 o seules les tâches D et S ont entamé leur progression La figure 3 montre les positions respectives des tâches en milieu de la phase opératoire, les tâches N, D, O étant arrivées dans l'ordre, en fin de parcours. A la fin de la phase opératoire, toutes les tâches concurrentes sont arrivées en fin de parcours (figure 4). Bien entendu, l'invention ne se limite pas à ce mode de représentation. 36 - Revendications 1 Procédé pour le test des primitives d'un exécutif temps réel permettant d'exécuter plusieurs tâches en parallèle sur un processeur conçu pour n'exécuter qu'une seule tâche à la fois, chaque tâche utilisant l'ensemble des ressources de la machine nécessaires à son exécution, et ce, grâce à un ensemble de primitives de synchronisation et de partage des ressources qui permettent aux différentes tâches de s'exécuter, de façon asynchrone, caractérisé en ce qu'il consiste à mettre en oeuvre une pluralité de tâches coopérantes, à savoir: un ensemble de tâches concurrentes, bâties sur un même modèle et qui ne diffèrent les unes des autres que par leur contexte statique (désignation, priorité), chacune de ces tâches concurrentes pouvant effectuer une suite d'actions de deux types, déterminées aléatoirement, à savoir: des actions engendrant une progression dans le déroulement de la tâche et des actions consistant en des attentes; une tâche conductrice qui organise la mise en oeuvre des tâches concurrentes et qui règle plus particulièrement le lancement des tâches concurrentes, qui active leur déroulement et qui détecte leur achèvement; et une tâche serveur de ressource interne, telle qu'un distributeur de nombres aléatoires; ladite mise en oeuvre comportant: la détermination des priorités respectives des tâches, de manière à répartir leur activité dans le temps et à créer un maximum de cas différents de préemption, 37 2684467 une phase préalable comportant: une initialisation de l'horloge temps réel, le lancement de la tâche conducteur, la création de l'ensemble des objets temps réel nécessaires, le lancement des tâches serveur, une succession de phases opératoires, au cours de chacune desquelles la tâche conductrice fait concourir les tâches concurrentes selon un même parcours, cette phase comportant: le choix aléatoire d'un mode de lancement des tâches concurrentes, parmi différents modes de lancements préétablis, le lancement des tâches concurrentes selon le mode de lancement choisi, au moyen de primitives choisies aléatoirement, dans un ordre choisi au hasard, chacune des tâches, une fois lancée, tirant au hasard les susdites actions, la libération des tâches concurrentes, de leur condition d'attente, soit par un épuisement des délais qui les bloquent, soit par un tirage aléatoire de numéros d'événements publics ou privés qui libèrent les tâches concurrentes en attente de ces événements, la détection de l'arrivée de chacune des tâches concurrentes en fin de parcours, la prise en compte et la mémorisation de paramètres caractéristiques de la phase opératoire qui vient de se dérouler, la modification de l'ordre dans lequel les tâches opératoires vont être relancées au cours de la phase opératoire suivante, le lancement de la phase opératoire suivante, l'analyse des susdits paramètres pendant le déroulement des susdites phases opératoires et/ou à l'achèvement de celles-ci. 38 - 2 Procédé selon la revendication 1, caractérisé en ce que les différents modes de lancements préétablis comprennent: le lancement immédiat inconditionnel, le lancement différé en attente d'un événement, le lancement différé en attente d'un délai, lui-même aléatoire. 3 Procédé selon l'une des revendications 1 et 2, caractérisé en ce qu'il fait en outre intervenir au moins une tâche serveur de ressource externe, une tâche de serveur de ressource interne, et une tâche cyclique. 4 Procédé selon la revendication 3, caractérisé en ce que la tâche serveur de ressource externe est une tâche de gestion d'un écran, la tâche serveur de ressource interne est un distributeur des nombres aléatoires utilisés par les tâches dans le procédé, et la tâche cyclique impose, de façon périodique, des conditions qui influent sur le déroulement des tâches concurrentes lors des différentes phases opératoires. Procédé selon l'une des revendications précédentes, caractérisé en ce que le classement des susdites tâches en fonction de leur priorité, dans un ordre croissant, est le suivant: la tâche conductrice qui est la tâche de fond, la tâche serveur de ressource externe, les tâches concurrentes qui sont réparties sur plusieurs niveaux de priorité croissants, la tâche serveur de ressource interne, et la tâche cyclique. 39 - 6 Procédé selon l'une des revendications précédentes, caractérisé en ce que la tâche serveur de ressource externe reçoit des demandes émanant des tâches appelantes sous la forme de messages qui décrivent le type d'entrée/sortie qui doit être réalisé pour le compte de la tâche appelante, ces messages étant disposés dans une première boîte aux lettres qui, lorsqu'elle est pleine, provoque un blocage des tâches appelantes qui demeurent dans l'attente de pouvoir déposer leur message et reprendre la main, et en ce que, dans le cas o la première boîte aux lettres est vide, la tâche serveur de ressource externe est bloquée en attente de recevoir un nouveau message. 7 Procédé selon l'une des revendications précédentes, caractérisé en ce que la tâche serveur de ressources externes traite complètement une demande avant de prendre en compte la demande suivante, et ce, quelle que soit la priorité des tâches appelantes. 8 Procédé selon l'une des revendications précédentes, caractérisé en ce que la tâche serveur de ressource interne consiste en une tâche distributeur de nombres aléatoires déposant les nombres aléatoires dans une deuxième boîte aux lettres, en ce que les tâches qui désirent obtenir un nombre se mettent en réception sur cette deuxième boîte aux lettres, en ce que si cette deuxième boîte aux lettres est vide, les tâches appelantes sont bloquées en attendant de pouvoir extraire un nombre et poursuivre leur exécution, et en ce que, lorsque la deuxième boîte aux lettres est pleine, la susdite tâche distributeur se bloque, dans l'attente de pouvoir déposer un nouveau nombre. - 9 Procédé selon l'une des revendications précédentes, caractérisé en ce que la susdite tâche cyclique utilise un événement qu'elle bascule à chaque nouveau cycle, cette tâche cyclique utilisant trois primitives, à savoir: une première primitive pour connaître l'état dans lequel se trouve cet événement, une deuxième primitive pour le mettre à l'état arrivé, une troisième primitive pour le mettre à l'état non- arrivé. Procédé selon l'une des revendications précédentes, caractérisé en ce que le parcours de chacune des tâches concurrentes comprend des obstacles communs gérés en ressource non partageable, chacun de ces obstacles ne pouvant être franchi que par une seule tâche concurrente à la fois, et en ce qu'en arrivant sur un obstacle, chaque tâche concurrente demande l'accès à la ressource correspondante par une première primitive et libère en fin d'obstacle la ressource qu'elle occupait par une deuxième primitive. 11 Procédé selon la revendication 10, caractérisé en ce qu'une tâche concurrente peut franchir un obstacle occupé sans attendre qu'il se libère, à la suite de l'obtention au hasard d'un bonus, par exemple lorsque la tâche cyclique affiche une condition déterminée. 12 Procédé selon l'une des revendications précédentes, caractérisé en ce qu'à la fin de son parcours, chaque tâche concurrente inscrit son nom sur un registre qui est consulté en permanence par la tâche conductrice pour 41 - détecter la fin d'une phase opératoire, en vue d'en relancer une nouvelle. 13 Procédé selon l'une des revendications précédentes, caractérisé en ce que les tâches concurrentes de tête sont classées selon leur ordre d'arrivée par la tâche conductrice alors que les tâches concurrentes de queue ne sont pas départagées.