[Kos-dev] "Race condition" 1
Thomas Petazzoni
kos-dev@enix.org
Mon, 26 May 2003 10:37:05 +0200
This is an OpenPGP/MIME signed message (RFC 2440 and 3156)
--------------enig94DAE791D14A600DE99BE365
Content-Type: text/plain; charset=ISO-8859-15
Content-Transfer-Encoding: 8bit
Hello,
> Si : ASSERT_FATAL(test_interrupt_enabled() == FALSE); dans
> cpl0_switch_with_return. Donc quand un thread demande un switch, avant
> le switch, IE est a 0, donc quand on retournera vers lui, dans tous
> les cas IE est remis a 0 au moment du iret. Le seul cas qui deconnait,
> c'est quand le iret ne restaurait pas un contexte de thread qui avait
> appele cpl0_switch_with_return, ie quand le iret restaurait le
> contexte d'un thread tout neuf, pour lequel IE vaut 1. Mettre IE a 0
> pour les nouveaux threads fait que dans tous les cas le iret restaure
> le contexte d'un thread avec interruptions desactivees. Il serait pas
> inutile d'ailleurs de mettre un test du type ASSERT_FATAL sur le IE a
> 0 du eflags du to_context dans cpl0_switch_no_return_internal et
> cpl0_switch_with_return .
Bon, ok, j'avais encore tort apparemment, j'ai toujours un peu de mal
avec ces changements de contexte. On peut effectivement essayer de
tester le IE du Eflags dans cpl0_switch_no_return_internal pour vérifier
qu'on fait pas n'importe quoi, mais appeler ASSERT_FATAL depuis du code
assembleur, hum ;-)
Je serais pour recopier le ASSERT_FATAL(test_interrupt_enabled() ==
FALSE); juste en dessous de l'appel à cpl0_switch_with_return_internal
pour être sur qu'on a effectivement toujours les interruptions
désactivées après le changement de contexte.
Je retiens donc ta solution : au lieu d'initialiser Eflags à 514 lors de
la création du thread on l'initialise à 2 (== (514 & ~(1<<9)), et on
fait ensuite comme tu as dit dans execute_thread.
> Thomas> En ce qui concerne le passage du spinlock en paramètre, il
> Thomas> faudra passer un pointeur, et donc toutes les macros
> Thomas> *_spin_* ne fonctionneront pas.
>
> ?
#define write_spin_lock(spinlock,flags) \
do { save_flags(flags); cli(); \
LOCKING_REPORT("write_lock_sl(" # spinlock " : "); \
ASSERT_FATAL((spinlock).state == LCK_READY); \
ASSERT_FATAL((spinlock).nb_readers == 0); \
ASSERT_FATAL((spinlock).nb_writers == 0); \
(spinlock).nb_writers = 1; \
LOCKING_REPORT("read=%d,writ=%d)\n", (spinlock).nb_readers,
(spinlock).nb_writers); \
} while(0)
Cette définition suppose qu'on a accès *directement* à la structure
spinlock_t, et non pas à un (spinlock_t *). Or, si on veut que
kwaitqueue_add_* relache un spinlock au bon moment, il faut passer un
pointeur dessus.
Thomas
--
PETAZZONI Thomas - thomas DOT petazzoni AT enix DOT org - UIN : 34937744
Web: 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
--------------enig94DAE791D14A600DE99BE365
Content-Type: application/pgp-signature
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.1 (MingW32)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org
iD8DBQE+0dIx9lPLMJjT96cRApjDAJwKg3qgGz0Oy7/XmSk7emw77COMNACeKpvB
XBZM71dU2LuoY7M5RZJAPH0=
=jByx
-----END PGP SIGNATURE-----
--------------enig94DAE791D14A600DE99BE365--