[SOS] Re: Là, je suis perdu !

David Decotigny david.decotigny at free.fr
Dim 5 Juin 22:44:49 CEST 2005


Bonjour,

David Decotigny a écrit :
> Je vais quand meme regarder de plus pres. C'est une solution qui marche

J'ai regarde. Il s'avere qu'il y a bien un bug dans sos. Ce bug peut
etre contourné en changeant la valeur de ips mais il y a mieux.

Ce qui se passait est le scenario suivant :
 - dans le thread idle, instruction hlt (le processeur attend une IRQ)
 - l'IRQ timer arrive, fait son mic mac. Comme elle avait interrompu un
   thread noyau (le thread idle), on retourne dans le thread idle
 - apres hlt dans idle, c'est sos_thread_yield() qui est appelee, qui
   decide d'elire le thread user "init" en attente
 - et au moment du switch, les interruptions ayant ete masquees pendant
   le yield, et etant reactivees pdt le switch : paf une IRQ timer en
   attente est servie
 - cette IRQ timer decide toujours de faire un round-robin, et retourne
   vers le thread idle. On reboucle a la premiere etape.

En mesurant avec bochs, on trouve que les etapes 2 et 3 ci-dessus
demandent un tout petit peu plus de 5000 instructions chez moi (depend
du compilo). Or, l'ecart entre 2 IRQ timer est de 5000 instructions si
ips=500000 puisque le timer est programmé pour generer ses IRQ a 100 Hz.
Donc l'arrivee de cette IRQ timer (etape 4) est normal. Le fait que le
thread user ne soit jamais demarre est donc normal et une solution pour
qu'il puisse demarrer est d'augmenter ips dans la config de bochs.

Bon, mais cette solution n'est pas completement satisfaisante. Car
pourquoi l'IRQ timer a l'etape 5 elit toujours le thread idle ? En
effet, l'ordonnanceur de sos est cense faire du timesharing type Unix.
Compte tenu de la priorite du thread user, le systeme devrait laisser la
main au thread user pendant au moins 200ms, ie 20 IRQ timer, avant de
repasser la main a idle. Or ici : mystere, on ne beneficie que d'1 seule
periode de l'IRQ timer. Si ce probleme etait regle, le thread user
pourrait progresser car l'etape "yield" avant le retour vers le thread
user serait supprimee.

La solution ? Corriger un bug de sos. En effet, si on regarde comment
fonctionne l'ordonnanceur et si on debugge, on s'apercevra que la valeur
dans le champ "sos_thread::user_time_spent_in_slice" n'est pas mise a
jour comme il faut. C'est tout simplement qu'il s'agit d'un champ dans
une union. Or la valeur a cet endroit est ecrasee quand le thread passe
en mode "ready", ce qui arrive a chaque fois que sos_reschedule est
appelee, car les champs rdy_prev/rdy_next sont dans la meme union. Et
voila. Pour resoudre le probleme, le plus simple est donc de sortir le
"sos_thread::user_time_spent_in_slice" de l'union, comme ca on est sur
qu'il ne sera pas ecrase. Une autre solution est de modifier
sos_reschedule pour pas qu'elle mette le thread appelant dans la liste
des threads ready.

Ci-joint le patch. Plus besoin de modifier le ips de bochs, le laisser a
la valeur par defaut (500000) convient. On peut meme descendre
en-dessous de 350000 chez moi (depend du compilo).

Bonne journee,

-------------- section suivante --------------
Une pièce jointe non texte a été nettoyée...
Nom: a.diff
Type: text/x-patch
Taille: 2235 octets
Desc: non disponible
Url: http://the-doors.enix.org/pipermail/sos/attachments/20050605/46d7ff81/a.bin


Plus d'informations sur la liste de diffusion Sos