TacOS-team / tacos

Système d'exploitation / Operating System
GNU General Public License v3.0
9 stars 4 forks source link

Scheduling immédiat quand nécessaire #181

Closed NicolasFloquet closed 9 years ago

NicolasFloquet commented 10 years ago

Quand un process n'a plus rien à faire, il serait bien d'appeler le scheduler de façon anticipée afin de passer à autre chose. sys_sleep (scheduler.c:307) fait ça très bien. Il faudrait recenser toutes les situation qui nécessiteraient un réordonnancement immédiat, et appliquer la méthode utilisée dans sys_sleep. D'autre part, il faudrait également créer une nouvelle méthode, ou renommer la méthode actuelle servant à lancer un scheduling immédiat (start_scheduling c'est un peu ambigue je trouve).

Pour le moment j'ai pensé aux points suivants:

à étoffer si y'a d'autres cas

MaximeCheramy commented 10 years ago

À la place de start_scheduling, je propose : reschedule.

Et sinon, il y a un truc que j'ai vu dans d'autres OS c'est simplement avoir un flag passé à true pour lui dire de faire un réordonnancement. Et avant de revenir d'un syscall, on check ce flag pour savoir s'il faut appeler la méthode qui réordonnance. L'avantage c'est qu'il suffit de modifier un flag sans appeler l'ordo en plein milieu et on réordonnance au dernier moment, quand on a bien fini.

Notons aussi qu'on peut très bien checker en sortant du sys_call si le process en cours est toujours actif...

Autre remarque : je vois des boucles à certains endroits (sys_sleep et ksemP). Genre :

  while(proc->state == PROCSTATE_WAITING) asm("hlt");

Au lieu de faire des trucs du genre, on devrait simplement rappeler l'ordo (ça rejoint ce que tu dis mais je virerais cette boucle qui doit pas servir). C'est à l'ordonnanceur de ne pas exécuter ce processus. Car là en plus, c'est même pas idle qui s'exécute, c'est n'imp.

NicolasFloquet commented 10 years ago

De la façon dont ça fonctionne actuellement, même si on reschedule "immédiatement", je pense qu'il y a un court instant pendant lequel on continue à s'exécuter (défini par la précision de notre timer). Concrètement, c'est pas réellement immédiat, du coup ces boucles sont justifiées. L'idée que tu propose de faire le resceduling dans le wrapper d'interruption si jamais un flag est levé est intéressante. Partout ailleurs, c'est impossible de faire un vrai rescheduling direct (impossible de récupérer le contexte du processus), il faut que je regarde à quel point c'est faisable.

MaximeCheramy commented 10 years ago

Je ne suis pas sûr de comprendre en quoi ces boucles sont nécessaires. Dans tous les cas que j'ai vu, il n'y a pas de code à exécuter après la boucle (je comprendrais ton argument s'il y avait des choses après). Donc autant sortir du syscall et au moment de revenir en userland, vu que l'ordonnanceur sera passé, on ne redonnera pas la main au processus qui s'exécutait.

NicolasFloquet commented 10 years ago

Je répète, de la façon dont ça fonctionne actuellement, si tu ne met pas cette boucle, le process va continuer à s'exécuter, éventuellement retourner en userland, puis finir par être interrompu par le scheduler. C'est pas vraiment ce qu'on attend d'un sleep ou un semP. Je vois pas ce qui, pour le moment, pourrait faire que l'ordonnanceur soit passé au moment de revenir en userland

MaximeCheramy commented 10 years ago

Ah oui oui, actuellement dans les cas où on appelle pas l'ordo explicitement, c'est bien-sûr nécessaire. Je parlais de la nécessité des boucles si on appelle l'ordo.

NicolasFloquet commented 10 years ago

Bon, pour clarifier les choses, ce ticket a pour but de répertorier les endroits où le scheduling immédiat est nécessaire. L'ajout d'un mécanisme de rescheduling immédiat est traité par le ticket #182

MaximeCheramy commented 10 years ago

Je lisais tes tickets sur les signaux et je me faisais la réflexion suivante :

Actuellement, si j'ai bien compris, l'un des problème est qu'on est déjà en espace kernel en train d'envoyer ou recevoir un signal et là ya l'ordonnanceur qui passe alors qu'on a pas fini et qui va nous provoquer des trucs bizarres comme un changement du process en cours. Une solution serait alors de désactiver l'ordo, faire des sections critiques, etc. Mais j'ai aussi repensé à ce ticket.

Si l'ordonnanceur n'était jamais appelé par un timer ou par appel de fonction mais en utilisant un flag tel que décrit plus haut (check du flag à chaque retour en user land pour savoir s'il faut réordonnancer). Cela permettrait de simplement passer le flag à true périodiquement mais si on est déjà dans le kernel l'ordo ne passera qu'une fois le syscall terminé au lieu de le faire en plein milieu.

Qu'en penses-tu ? Est-ce que tu préfères tenter de régler le problème des signaux maintenant ou est-ce qu'on tente un refactoring du scheduler avant ? (que ce soit cette approche ou un autre, cette question reste valide)

NicolasFloquet commented 10 years ago

Alors je vais commencer par la fin: Oui, vaut mieux finir de corriger les signaux avant de toucher au scheduleur.

Pour ce que tu dis avant, si on se contente d'utiliser uniquement un flag qu'on vérifie à chaque retour en userland, ça veut dire qu'un process qui ne fait que tu userland ne rendrait jamais main. Ce genre d'approche marche bien dans les OS temps réel qui mettent en place d'autres méchanismes (sanction sur dépassement de période, partitionnement temporel, etc.), mais pour TacOS je vois pas bien comment on pourrait garantir le bon partage du CPU sans tick...

MaximeCheramy commented 10 years ago

Pardon, je n'ai pas été assez précis, j'ai bien sûr pensé à ce que tu dis. Lorsque tu dis :

un process qui ne fait que tu userland ne rendrait jamais main

C'est pas vrai. Le timer du scheduler fait une interruption pour que le kernel passe le flag à true. Ensuite on repasse en userland. Et c'est donc à ce moment là qu'on check le flag et donc on réexecute l'ordo.

NicolasFloquet commented 10 years ago

Ouais mais du coup, je vois pas l'intérêt par rapport à ce qu'on fait déjà

MaximeCheramy commented 10 years ago

Prenons un exemple :

Nous avons une interruption du timer qui sert au scheduler. Là nous avons 2 possibilités :

La différence par rapport à ce qu'on fait déjà est simple : l'ordonnanceur ne s'exécute que lorsqu'on a fini de traiter les syscalls ou autres interruptions. Alors qu'actuellement ça peut se passer à tout moment.

Pour moi c'est intéressant parce que même si on protège avec des sections critiques, en l'état, on est pas à l'abris d'un changement du processus courant ce qui pourrait donner n'importe quoi en pratique, genre le syscall se fait préempter par l'ordo, l'ordo change le processus courant, et le syscall reprend son exécution et se trompe de processus courant puisqu'il a changé...

NicolasFloquet commented 10 years ago

Du coup, comment ça se passe avec un syscall bloquant?

MaximeCheramy commented 10 years ago

(histoire de garder une trace écrite de notre réflexion, je recopie ma reponse-question ici)

On a quoi comme syscall bloquant ? Et est-ce que c'est normal qu'un syscall soit bloquant ? Au sens où en fait il passe juste le process en attente et redonne la main à l'OS qui va executer la tache idle ‎Ça rejoint pas notre conversation sur les boucles while inutiles ?

MaximeCheramy commented 10 years ago

J'étais en train de bidouiller la partie scheduling pour pouvoir me remettre en tête son fonctionnement. Et là j'ai une question pour toi : j'ai renommé la fonction schedule en do_schedule mais qui renvoie rien et ne prend pas d'arguement. Ensuite j'ai créé une fonction schedule avec la signature qui va bien et qui ne fait qu'appeler do_schedule et renvoyer NULL. Pourquoi TacOS reboot au lancement ?

MaximeCheramy commented 10 years ago

Est-ce que c'est lié à la valeur hardcodée ?

MaximeCheramy commented 9 years ago

Je serais assez chaud pour déterrer ce ticket que je trouve très intéressant.

NicolasFloquet commented 9 years ago

Pourquoi pas, il est loin d'être aussi simple qu'il en a l'air, genre, très très loin, mais ok.

NicolasFloquet commented 9 years ago

Je pense qu'on devrait effectivement considérer ce ticket ainsi que le #182 comme prioritaire.