LES FIBERS : DES THREADS NON PRÉEMPTÉS PAR LE SYSTÈME

cirec
Messages postés
3832
Date d'inscription
vendredi 23 juillet 2004
Statut
Modérateur
Dernière intervention
17 février 2022
- 1 mars 2009 à 18:01
cs_Loda
Messages postés
814
Date d'inscription
vendredi 3 novembre 2000
Statut
Membre
Dernière intervention
30 juillet 2009
- 10 mars 2009 à 12:34
Cette discussion concerne un article du site. Pour la consulter dans son contexte d'origine, cliquez sur le lien ci-dessous.

https://codes-sources.commentcamarche.net/source/49393-les-fibers-des-threads-non-preemptes-par-le-systeme

cs_Loda
Messages postés
814
Date d'inscription
vendredi 3 novembre 2000
Statut
Membre
Dernière intervention
30 juillet 2009
3
10 mars 2009 à 12:34
@DeltaFX:

les Fibers seulement te permet qu'un autres Fibers (thread) de TON application ne préempte pas TON Fiber (thread) courant. Ce qui limite les problèmes de multi-thread (lock,...)

si tu veux faire tu RT sous windows.... humm. windows n'est pas RT, mais tu peux regarder du côté de solution commercial "windows compatible" comme rtos32.
http://www.on-time.com/rtos-32.htm

Avec RTOS32, C'est très facile de faire tourner une application Delphi "normal" pour du RT embarqué. (Il propose un ordonnancement digne d'un OS RT, ...)
cs_rt15
Messages postés
3874
Date d'inscription
mardi 8 mars 2005
Statut
Modérateur
Dernière intervention
7 novembre 2014
14
9 mars 2009 à 16:07
Non, malheureusement ce n'est plus la saison du père noël. Windows schedule les threads. Les threads schedulent les fibers.

http://msdn.microsoft.com/en-us/library/ms682661(VS.85).aspx
DeltaFX
Messages postés
449
Date d'inscription
lundi 19 avril 2004
Statut
Membre
Dernière intervention
8 avril 2009
2
9 mars 2009 à 15:54
Pas préempté par le system ? Gnh ?

Ce qui veut dire que si je crée (admettons que ) un scheduler de Fibres qui soit lui meme un Fiber et que je l'appelle mettons Round-Robin (par exemple) je peux faire du temps réel Hard sous zindowz ? *start droolin' on my keyboard*

pour de vrai ?
cs_rt15
Messages postés
3874
Date d'inscription
mardi 8 mars 2005
Statut
Modérateur
Dernière intervention
7 novembre 2014
14
9 mars 2009 à 12:32
Je rejoins les félicitations générales. Très belle source. Originale, qui peut aider ceux qui veulent faire des fibers... Du grand art.

En attendant une grosse pointure que je ne suis pas, je peux essayer de donner un début d'explication concernant les quelques lignes d'assembleur. Soit dit en passant l'assembleur est infiniment plus simple que le Delphi sur le plan syntaxique : il y a vraiment pas beaucoup d'instructions et elles sont toutes relativement simples. C'est pas du tout un langage qu'il faut considéré comme inabordable et réservé à je ne sais quels bidouilleurs de l'extrème.

Le processeur est composé d'un certain nombre de registres, c'est à dire de cases nommées pouvant contenir des valeurs.

Quand le windows décide de changer le thread en cours d'exécution, il remplace les valeurs stockées dans ces registres par celles du thread à exécuter.

On appelle ça des contexte d'exécution. Windows garde en mémoire le contexte de tous les threads et remplace un contexte par un autre pour changer de thread.

Dans un processus, tous les threads ont accès à la même mémoire.

Donc si un processus a un thread A et un thread B, comment faire la différence entre les deux ?

En sockant dans le contexte des informations sur le thread courant.

A chaque changement de thread, le contexte étant mis à jour, les informations sur le thread sont mises à jour.

Le processus peut ainsi facilement connaître son thread qui est en cours d'exécution.

GetCurrentThreadId par exemple, exploite probablement les informations de contexte pour renvoyer l'id du thread.

Où sont stockées ses informations dans le contexte ?

Le contexte, composé de registre, est de taille très restreinte pour des raisons de performance évidente.

Le contexte est donc stocké en mémoire et pointée par un des registres, fs.

Chaque thread a donc son propre fs qui pointe sur son propre contexte, le TEB, pour Thread Environment Block :
http://undocumented.ntinternals.net/UserMode/Undocumented%20Functions/NT%20Objects/Thread/TEB.html

Le TEB permet de récupérer beaucoup d'informations sur le thread et le processus :
Il y a un pointeur sur le Process Environment Block, les IDs du thread et du processus (Dans RealClientId)...

Et un pointeur sur les infos sur la fibre.

Le pointeur sur ces infos se trouve dans la Tib, la première structure du TEB.

Le TEB est bien représentée sur wikipedia (Ils appellent ça le TIB, mais le TIB est seulement la première partie), avec les offset :
http://en.wikipedia.org/wiki/Win32_Thread_Information_Block
On voit que "Fiber data" se trouve à l'offset de la TEB/TIB + 0x10 16 $10 octets.

C'est ça que va chercher l'assembleur.

function GetCurrentFiber : Pointer;
asm
mov eax, fs:[$10]
end;

La valeur de retour de la fonction doit être mise en place dans le registre eax.
Donc il faut déplacer Fiber data dans eax :
mov eax, FiberData

fs est un registre de segment. Les registres de segments permettent de modifier l'adressage. Par défaut, pour une instruction, c'est le registre de segment ds qui est utilisé. mov eax, [$10] est équivalent à mov eax, ds:[$10].

Ici, on veut accèder au TEB et on sait que fs pointe dessus, du moins que l'adresse 0 dans le segment fs correspond à l'adresse du TEB. On précise donc que l'on utilise le registre de segment fs.

Et on tape à l'adresse $10 de ce segment. Détail "amusant", pour ce segment, nil n'est pas du tout une adresse invalide.

Dans le cas de la deuxième fonction :

function GetFiberData : Pointer;
asm
mov eax, fs:[$10]
mov eax, [eax]
end;

On récupère le premier champ de la structure pointé par Fiber Data. Mais je n'ai pas trouvé la définition de la structure en question.

J'espère avoir été au moins vaguement compréhensible...
Caribensila
Messages postés
2527
Date d'inscription
jeudi 15 janvier 2004
Statut
Membre
Dernière intervention
16 octobre 2019
18
2 mars 2009 à 16:41
- Tiens, t'es revenu Francky?
- T'étais où?
- Je parie que tu reviens de Fécamps... Une campagne de pêche à la morue, non? mdr


Merci pour vos commentaires, les gars.
Vous mettez le doigt sur le truc qui m'a longtemps fait hésiter à poster ce source : l'unité Fibers en asm qui permet d'utiliser cette technique sous Delphi.
Elle n'est, bien sûr, pas de moi (c'est pas de mon niveau!). Je l'ai trouvée ainsi, brute de décoffrage.
J'avoue que j'ai essayé de la comprendre... en vain. Me suis même plongé une journée dans l'assembleur; j'ai failli m'y noyer et y rester. C'est plus de mon age, ce truc! Bref, je me suis décidé à poster le truc comme ça. En espérant qu'une 'grosse pointure' du site apportera la lumière à ma lanterne.
De toute façon, avec la POO, on prend l'habitude d'utiliser des concepts qui nous échappent un peu. C'est un peu le but, même si c'est parfois frustrant. Et, d'autre part, c'est aussi un peu le concept de ce site : progresser grâce à l'aide des membres plus "avancés".
Voilà donc les raisons pour lesquelles vous allez pouvoir attendre longtemps mes commentaires sur les quelques lignes de Fibers.pas. Ca ne viendra pas de moi et j'en suis désolé.

Quand à l'intérêt des Fibers, après avoir été emballé au début, comme semble aussi l'être Cirec, je me pose encore des questions et j'aimerais bien voir une application exploiter à fond ce concept et en démontrer la pertinence. C'est peut-être pas un hasard si cette technique est si mal connue et documentée. Je n'en ai en effet encore jamais rencontrées et, encore une fois, j'espère qu'une 'grosse pointure' aura du feu pour ma lanterne.

En tout cas, on sait tous que ça existe, maintenant. Reste plus qu'à en tirer la "quinte essence"...
Afficher les 10 commentaires