[Kos-dev] "Race condition" 1

Thomas Petazzoni kos-dev@enix.org
Wed, 28 May 2003 23:00:40 +0200


-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Bonsoir,

> Si cette solution est appliquée, il reste la deuxième race condition à
> régler, celle qui tourne autour de l'implémentation foireuse des
> sémaphores, avec relachage du lock un peu trop tot.

J'ai effectivement appliqué cette solution, et elle fonctionne, enfin en
tout cas je n'ai pas réussi à la mettre en défaut : elle tourne pour un
test avec 100, 200, 500, 1000, 2000 et 3000 threads noyau. A noter que
bien sur il n'y a pas 3000 threads noyau en simultané : on est limité à
256 threads noyaux simultanés, mais il y a bien création/destruction de
3000 threads qui font chacun 100 boucles avec dans chaque boucle un
appel à usleep(). Le scheduler, les waitqueues, et les changements de
contexte sont donc mis à rude épreuve.

A un moment, j'ai cru qu'il restait une race condition : le test disait
qu'il restait des threads, et ne se terminait jamais. En fait j'avais
fait la supposition que l'incrémentation et la décrémentation était
atomiques, ce qui n'est pas le cas. J'ai donc ajouté des cli() et sti()
pour protéger cette incrémentation et cette décrementation. Voici les
bouts de code assembleur :

*** La décrémentation se fait bien de manière atomique, en une seule
instruction (j'ai laissé les relocations pour qu'on voit bien de quoi il
s'agit) ***

  5f:   fa                      cli
  60:   ff 0d 00 00 00 00       decl   0x0
                        62: R_386_32    .bss
  66:   fb                      sti

*** L'incrémentation est faite de manière indirecte en passant par un
registre, ce qui fait qu'on pouvait écraser une zone mémoire qui avait
déjà été incrémentée ***

  9e:   fa                      cli
  9f:   8b 15 00 00 00 00       mov    0x0,%edx
                        a1: R_386_32    .bss
  a5:   42                      inc    %edx
  a6:   89 15 00 00 00 00       mov    %edx,0x0
                        a8: R_386_32    .bss
  ac:   fb                      sti

Voila, donc la solution d'appeler le cpl0_delete_pending_thread dans le
cpl0_switch_no_return_internal fonctionne bien. Je n'ai pas encore
committé, parce qu'il faut que je nettoie un peu partout le bazar que
j'ai fait.

Ce soir j'ai des amis qui arrivent, donc pas de developpement d'ici le
début de la semaine prochaine. La premiere chose dont je vais m'occuper
est la deuxième race condition, en revoyant le fonctionnement du
scheduler et des waitqueues.

Bonne soirée,

Thomas
- --
PETAZZONI Thomas - thomas.petazzoni@enix.org - UIN : 34937744
http://www.enix.org/~thomas/
KOS: http://kos.enix.org/ - Lolut: http://lolut.utbm.info
Fingerprint : 0BE1 4CF3 CEA4 AC9D CC6E  1624 F653 CB30 98D3 F7A7
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.2 (GNU/Linux)
Comment: Using GnuPG with Debian - http://enigmail.mozdev.org

iD8DBQE+1SN49lPLMJjT96cRApTlAJ9hEX1OOLDPouT3juULXF6Es7EQTACeLDyj
ECdIwPXIRfrciMjRNolNMzo=
=hmhA
-----END PGP SIGNATURE-----