Non mais regarde par exemple le noyau linux à l'époque des 2.x (x ≤ 4): le portage avait plus ou moins nécessité une réécriture complète de certaines portions du noyau pour chaque nouvelle architecture visée. Alors qu'à partir du noyau 2.6, comme un gros effort de nettoyage de code, de factorisation, etc., avait été apporté, le plus gros avantage avait finalement été (au moins au début) la meilleure portabilité du code, ce qui permettait de modifier le noyau en un endroit et de ne devoir dupliquer certaines modifications que bien plus rarement.
Autre exemple : le code de NetBSD (et en fait, OpenBSD itou de ce que j'ai pu voir) est considéré comme extrêmement portable, car même les drivers sont écrit en C ISO (+POSIX je suppose), avec une quantité de code assembleur extrêmement limité, ceci grâce à l'utilisation de wrappers (fonctions d'adaptations) « légers » qui parlent le « langage » de l'OS (bref, qui pigent ses API), et qui évitent voir interdisent l'utilisation de code ASM directement.
Imaginons un code de ce genre :
/* Ce code est sans doute mal synchronisé; je l'utilise juste pour l'exemple. */externvolatileintg_lock;/* Tentative de prise de verrou */#if defined(HAS_COMPARE_AND_SWAP)while(compare_and_swap(g_lock,0,1)!=1);// do nothing: busy waiting -- bad programmer, no cookie !#elif defined(HAS_TEST_AND_SET)while(test_and_set(g_lock)==1);// do nothing: busy waiting -- bad programmer, no cookie !#endif/* plus loin dans le code ... *//* Libération du verrou */#if defined(HAS_COMPARE_AND_SWAP) || defined(HAS_TEST_AND_SET)g_lock=0;#endif
Il est évident que ce truc n'est pas portable. Le code de verrouillage/déverrouillage devrait être encapsulé dans des fonctions spécifiques (par exemple, mutex_lock() et mutex_unlock()1), et encore mieux, il faudrait « fabriquer » un compare_and_swap à partir d'un test_and_set si C&S n'existe pas sur l'archi cible, comme ça le code ne pourrait jamais casser, même si en pratique il risquerait de perdre en perf (car du coup pour fabriquer un C&S à partir d'un T&S, tu dois utiliser une variable tierce pour modifier le mot, faire le test, et renvoyer l'ancienne version).
Note que mon exemple est complètement artificiel, vu que gcc et ses potes (au moins llvm et icc, mais sans doute les autres compilos aussi) ont déjà des intrinsics pour générer le bon code. Cela dit, l'OS devrait enrober ces opérations malgré tout pour assurer la portabilité du code au-delà de l'usage d'un compilateur en particulier.
Et je ne parle même pas de l'utilisation d'une variable globale... ↩
[^] # Re: et ca compile ?
Posté par lasher . En réponse au journal OpenSSL est mort, vive (le futur) LibreSSL. Évalué à 10.
Non mais regarde par exemple le noyau linux à l'époque des 2.x (x ≤ 4): le portage avait plus ou moins nécessité une réécriture complète de certaines portions du noyau pour chaque nouvelle architecture visée. Alors qu'à partir du noyau 2.6, comme un gros effort de nettoyage de code, de factorisation, etc., avait été apporté, le plus gros avantage avait finalement été (au moins au début) la meilleure portabilité du code, ce qui permettait de modifier le noyau en un endroit et de ne devoir dupliquer certaines modifications que bien plus rarement.
Autre exemple : le code de NetBSD (et en fait, OpenBSD itou de ce que j'ai pu voir) est considéré comme extrêmement portable, car même les drivers sont écrit en C ISO (+POSIX je suppose), avec une quantité de code assembleur extrêmement limité, ceci grâce à l'utilisation de wrappers (fonctions d'adaptations) « légers » qui parlent le « langage » de l'OS (bref, qui pigent ses API), et qui évitent voir interdisent l'utilisation de code ASM directement.
Imaginons un code de ce genre :
Il est évident que ce truc n'est pas portable. Le code de verrouillage/déverrouillage devrait être encapsulé dans des fonctions spécifiques (par exemple,
mutex_lock()etmutex_unlock()1 ), et encore mieux, il faudrait « fabriquer » uncompare_and_swapà partir d'untest_and_setsi C&S n'existe pas sur l'archi cible, comme ça le code ne pourrait jamais casser, même si en pratique il risquerait de perdre en perf (car du coup pour fabriquer un C&S à partir d'un T&S, tu dois utiliser une variable tierce pour modifier le mot, faire le test, et renvoyer l'ancienne version).Note que mon exemple est complètement artificiel, vu que
gccet ses potes (au moinsllvmeticc, mais sans doute les autres compilos aussi) ont déjà des intrinsics pour générer le bon code. Cela dit, l'OS devrait enrober ces opérations malgré tout pour assurer la portabilité du code au-delà de l'usage d'un compilateur en particulier.Et je ne parle même pas de l'utilisation d'une variable globale... ↩