Définitions des macros | |
#define | FredTHREAD_NIL (FredThread)NIL |
Définition du thread inexistant. | |
Définitions des types | |
typedef void *(* | FredRunnable )(void *) |
Le type d'une procédure initiale de thread. | |
typedef FredThreadDesc * | FredThread |
L'identité d'un thread est un pointeur sur son descripteur. | |
typedef FredList | FredQueue |
Définition du type queue de threads. | |
Fonctions | |
FredThread | FredThreadSpawn (int stacksz, FredRunnable function, void *arg, void **resref) |
Création et lancement d'un thread. | |
void | FredThreadExit (void *res) |
Terminaison immédiate du thread courant. | |
void | FredThreadYield () |
Le thread courant passe la main à un autre thread. | |
FredThread | FredThreadCurrent () |
Rend l'identité du thread courant. |
|
Implantation C'est un simple alias du pointeur nul de cellule de liste |
|
Implantation C'est un simple alias d'une liste. |
|
Implantation
00498 { 00499 return current; 00500 } |
|
Implantation On rend le résultat à l'endrioit défini au mau moment de la création du thread par FreedThreadSpawn() . Le thread est mis dans la file des décédés pour que sa mémoire soit libérer par leon
00438 { 00439 FredThread old; 00440 FredCountDownStop();/* arrêt décomptage */ 00441 /* mettre le résultat à l'endroit demandé */ 00442 if(current->resref)*(current->resref)=res; 00443 FredMaskOn();/* début d'exclusion mutuelle */ 00444 /* réveil de leon */ 00445 FredThreadWakeUp(&leonQ); 00446 /* 00447 un thread ne peut libérer la mémoire 00448 dans laquelle il s'exécute. Il délègue cela 00449 a leon en s'inscrivant dans la 00450 file des threads défunts 00451 */ 00452 FredThreadSuspend(&deadQ); 00453 /* on ne revient jamais ici */ 00454 FredAbort(" erreur fatale dans threadDie"); 00455 } |
|
Implantation On alloue la mémoire pour un descripteur de thread et la pile (éventuellement arrondi ). Si cette étape est franchi avec succès, on initialise le descripteur du thread ( FredThreadDesc ) et son contexte. On l'insère enfin dans la file des prêts readyQ en incrémentant le nombre de threads vivants nbFredThreads .
00393 { 00394 FredThread nw; 00395 /* allocation d'un descripteur de thread si possible */ 00396 nw= FredNEW(FredThreadDesc) ; 00397 if(!nw) return nw; 00398 /* calcul taille de pile */ 00399 nw->stacksz=FredSTACK_SIZE(stacksz); 00400 /* allocation de la pile si possible */ 00401 if(!(nw->stack=(char*)FredAtomicAlloc(nw->stacksz))) { 00402 /* plus de mémoire */ 00403 FredDELETE( nw); return FredTHREAD_NIL; 00404 } 00405 /* initialisation du descripteur */ 00406 nw->err=0; /* init errno à OK */ 00407 nw-> entry=function; /* fonction à exécuter */ 00408 nw->val=arg; /* son argument */ 00409 nw->resref=resref; /* où mettre le résultat */ 00410 /* initialisation du contexte processeur du thread */ 00411 FredContextInit(nw->ctx, 00412 FredMAKE_SP(nw->stack,nw->stacksz), 00413 FredThreadHarness); 00414 FredMaskOn();/* début d'exclusion mutuelle */ 00415 FredQueuePutLast(&readyQ,nw);/* réveil du nouveau thread */ 00416 nbFredThreads++; /* un thread de plus !! */ 00417 FredMaskOff();/* fin d'exclusion mutuelle */ 00418 return nw; 00419 } |
|
Implantation
00466 { 00467 FredThread old; 00468 FredMaskOn(); /* début d'exclusion mutuelle */ 00469 current->err=errno; /* sauver errno */ 00470 FredCountDownStop();/* arrêt décomptage */ 00471 old=current; 00472 /* le courant se met en queue des prêts */ 00473 /* on tire un nouveau courant */ 00474 FredQueuePutLast(&readyQ,current); 00475 current=FredQueueGetFirst(&readyQ); 00476 /* traiter le cas d'un unique thread actif : rien faire */ 00477 if(current!=old)FredContextSwitch(old->ctx,current->ctx); 00478 /* 00479 on reviendra ici lors de son réveil : 00480 on relance le décomptage du quantum 00481 */ 00482 FredCountDownStart(quantum);/* lancer décomptage */ 00483 errno=current->err;/* restaurer errno */ 00484 FredMaskOff();/* fin d'exclusion mutuelle */ 00485 } |