384 | | Pour la partie pratique, je ne vous fait pas modifier ou pire écrire la gestion des threads, mais je vous invite à lire le code. Pour Vous vous forcer à ouvrir les fichiers, vous allez répondre à quelques questions sur le code. Puis vous allez changer la manière de lire les caractères du TTY pour la rendre plus efficace. |
385 | | |
386 | | Dans la 1ère version proposée, tty_read() tente de lire le registre status pour savoir s'il y a un caractère en attente, sinon elle cède le processeur avec thread_yield(), le problème est que l'on peut perdre des frappes du clavier. |
387 | | Ici T0 appelle tty_read() qui cède le processeur à T1 en l'absence de frappes. |
388 | | |
389 | | **kernel/harch.c** |
390 | | |
391 | | * Le thread tente de lire le clavier en lisant `status`, en cas d'échec il cède le processeur en sachant qu'on lui rendra plus tard. |
392 | | * En cas de succès, il enregistre le caractère lu dans le buffer et décrémente le nombre de caractères attendus, si c'est le dernier, il sort. |
393 | | * Notez qu'il n'y a pas de loopback (c'est-à-dire de renvoi du caractère vers l'écran. C'est une opération complexe, on ne peut pas tout renvoyer (par exemple les flèches), c'est à la fonction système de faire ce travail. |
394 | | |
395 | | {{{#!c |
396 | | int tty_read (int tty, char *buf, unsigned count) |
397 | | { |
398 | | int res = 0; // nb of read char |
399 | | tty = tty % NTTYS; // to be sure that tty is an existing tty |
400 | | int c; // char read |
401 | | |
402 | | while (count--) { |
403 | | while (!__tty_regs_map[ tty ].status) { // wait for a char from the keyboard |
404 | | thread_yield(); // nothing then we yield the processor |
405 | | } |
406 | | c = __tty_regs_map[ tty ].read; // read the char |
407 | | *buf++ = c; |
408 | | res++; |
409 | | } |
410 | | return res; // return the number of char read |
411 | | } |
412 | | }}} |
413 | | |
414 | | Le schéma ci-dessous illustre le problème. |
415 | | [[Image(htdocs:img/IRQTTY_1.png,nolink,height=200)]] |
416 | | Le thread **`T0`** demande des lectures, `T1` prend le temps qui lui est donné jusqu'à l'IRQ du TIMER, je vous propose de lire le code en détail. |
| 384 | Pour la partie pratique, je ne vous fait pas modifier, ou pire écrire, la gestion des threads, mais je vous invite à lire le code. Pour Vous vous forcer à ouvrir les fichiers, vous allez répondre à quelques questions sur le code. Puis vous allez changer la manière de lire les caractères du TTY pour la rendre plus efficace. |
| 511 | **kernel/harch.c** |
| 512 | |
| 513 | * Le thread tente de lire le clavier en lisant `status`, en cas d'échec il cède le processeur avec `thread_yield()`, en sachant qu'on lui rendra plus tard. |
| 514 | * En cas de succès, il enregistre le caractère lu dans le buffer et décrémente le nombre de caractères attendus, si c'est le dernier, il sort. |
| 515 | * Notez qu'il n'y a pas de loopback (c'est-à-dire de renvoi du caractère vers l'écran. C'est une opération complexe, on ne peut pas tout renvoyer (par exemple les flèches), c'est à la fonction système de faire ce travail. |
| 516 | |
| 517 | {{{#!c |
| 518 | int tty_read (int tty, char *buf, unsigned count) |
| 519 | { |
| 520 | int res = 0; // nb of read char |
| 521 | tty = tty % NTTYS; // to be sure that tty is an existing tty |
| 522 | int c; // char read |
| 523 | |
| 524 | while (count--) { |
| 525 | while (!__tty_regs_map[ tty ].status) { // wait for a char from the keyboard |
| 526 | thread_yield(); // nothing then we yield the processor |
| 527 | } |
| 528 | c = __tty_regs_map[ tty ].read; // read the char |
| 529 | *buf++ = c; |
| 530 | res++; |
| 531 | } |
| 532 | return res; // return the number of char read |
| 533 | } |
| 534 | }}} |
| 535 | |
| 536 | |
| 537 | Le schéma ci-dessous illustre le problème: |
| 538 | * **`T0`** appelle tty_read() qui cède le processeur à **`T1`** en l'absence de frappes. |
| 539 | * Le thread **`T0`** demande des lectures à chaque qu'il a le processeur, **`T1`** prend le temps qui lui est donné jusqu'à l'IRQ du TIMER. |
| 540 | * Si l'utilisateur frappe beaucoup de touches pendant que **`T0`** n'a pas le processeur. Le caractères lus doivent être stockés quelque-part dans le contrôleur de TTY pour ne pas les perdre. Mais si cette mémoire est trop petite, on risque de perdre des caractères. |
| 541 | |
| 542 | [[Image(htdocs:img/IRQTTY_1.png,nolink,height=200)]] |
| 543 | |
| 544 | L'idée va être d'utiliser l'IRQ du TTY pour réagir à chaque frappe du clavier pendant l'exécution de **`T1`** pour lire le clavier et stocker les caractères dans une file d'attente. |
| 545 | |