Table des matières du kit Noyau | Index du kit du Noyau |
Déclarations dans : be/kernel/OS.h
Librairie : libroot.so
Un sémaphore est un marqueur utilisé pour synchronizer plusieurs threads. Le concept du sémaphore est simple : pour entrer dans une "section critique" protogée par un sémaphore, un thread doit d'abord "aquérir" le sémaphore, par la fonction acquire_sem(). Lorsqu'il sort de la section critique, le thread "relâche" le sémaphore avec release_sem().
L'avantage du système de sémaphore est que si un thread ne peut pas acquérir un sémaphore (parce le sémaphore doit d'abord être relâché par le précédant acquéreur), le thread bloque dans l'appel à acquire_sem(). Pendant qu'il est bloqué, le thread ne gâche aucun cycle CPU.
Pour plus d'informations sur les sémaphores, consultez "Concepts de Sémaphore". Pour des exemples de code, consultez "Exemples d'usage de sémaphore".
|
Ces fonctions tentent d'acquérir le sémaphore identifié par l'argument sem. Sauf en cas d'erreur, acquire_sem() ne retourne pas tant que le sémaphore n'a pas été réellement acquis.
acquire_sem_etc() est la version véritable d'acquisition : c'est essentiellement la même que acquire_sem(), mais, en plus, elle vous laisse acquérir un sémaphore plus d'une fois, et fournir un mode timeout :
|
A part le timeout et le nombre d'acquisition, il n'y a pas de différence entre les deux fonction d'acquisition. Spécifiquement, tout sémaphore peut être acquis par l'une ou l'autre fonction. Vous relâchez toujours un sémaphore par release_sem() (ou release_sem_etc()), peu importe quelle fonction fut utilisée pour l'acquérir.
Pour déterminer si un sémaphore est disponible, la fonction regarde le compteur du sémaphore (avant de le décrémenter) :
CODES DE RETOUR
Les autres valeurs de retour ne s'appliquent qu'à acquire_sem_etc() :
|
Créé un nouveau sémaphore et retourne un sem_id unique au système qui l'identifie. Les arguments sont :
Les sem_id valides sont des entiers positifs. Vous devez toujours vérifier la validité d'un nouveau sémaphore via une séquence telle que :
if ((my_sem = create_sem(1,"My Semaphore")) < B_OK) /* Si c'est moins que B_NO_ERROR, my_sem est invalide. */
create_sem() positionne le propriétaire du nouveau sémaphore à la team du thread appelant. La propriété peut être ré-affectée par la fonction set_sem_owner(). Lorsque le propriétaire meurt (lorsque tous les threads dans la team sont morts), le sémaphore est automatiquement détruit. Le propriétaire est aussi important dans un appel à delete_sem() : seuls les threads appartenant au propriétaire du sémaphore sont autorisés à détruire ce sémaphore.
CODES DE RETOUR
|
Détruit le sémaphore identifié par l'argument. S'il y a des threads attendant dans la file de threads du sémaphore, ils sont immédiatement débloqués.
|
CODES DE RETOUR
|
|
Retourne, par référence dans thread_count, la valeur du compteur de thread du sémaphore :
Pendant que cette fonction retourne et que vous observiez la valeur de thread_count, le compteur de thread du sémaphore peut avoir changé. Bien que l'observation du compteur de thread peut vous aider pendant le deboggage de votre programme, cette fonction ne doit pas être une partie complète de la conception de votre application.
CODES DE RETOUR
|
Copient les informations sur un sémaphore particulier dans la structure sem_info désignée par info. La première version de ces fonctions indique le sémaphore directement, par son sem_id.
La version get_next_sem_info(), elle, vous permet de parcourir la liste des sémaphores d'une team, par appel successifs. L'argument team identifie la team que vous voulez observer; une valeur team de 0 signifie la team du thread appelant. L'argument cookie est un marqueur, positionnez-le à 0 lors du premier appel, la fonction s'occupe du reste. Celle-ci retourne B_BAD_VALUE lorsqu'il n'y a plus de sémaphore à visiter :
/* Obtenir le sem_info pour chaque sémaphore de cette team. */ sem_info info; int32 cookie = 0; while (get_next_sem_info(0, &cookie, &info) == B_OK) ...
CODES DE RETOUR
|
La fonction release_sem() libère le thread qui attend en premier dans la file de threads du sémaphore (si il y en a un), et incrémente le compteur de thread du sémaphore. release_sem_etc() fait de même, mais pour count threads.
Normalement, relâcher un sémaphore invoque automatiquement le scheduler du noyau. Autrement dit, lorsque votre thread appelle release_sem(), vous êtes plutot sûr qu'un autre thread va être activé à votre place, même si votre thread n'avait pas reçu tout son quota de temps CPU. Si vous voulez éviter cet automatisme, appellez release_sem_etc() avec une valeur de flags à B_DO_NOT_RESCHEDULE. Prévenir la préemption automatique est particulièrement utile si vous relâcher tout un paquet de sémaphores d'un coup : en évitant la préemption vous évitez des changements de contexte non nécessaires.
CODES DE RETOUR
See also: acquire_sem()
|
Transfere la propriété d'un sémaphore particulier à team. Un sémaphore ne peut être la propriété que d'une seule team à la fois; en positionnant le propriétaire d'un sémaphore, vous le retirer à son propriétaire actuel.
Il n'y a pas des restrictions sur qui peut être propriétaire d'un sémaphore, ni sur qui peut transferer cette propriété. En pratique, cependant, la seule raison pour transferer la propriété est si vous écrivez un pilote de périphérique et que vous avez besoin qu'un sémaphore appartienne au noyau (la team connue, pour cet usage, comme B_SYSTEM_TEAM).
La propriété d'un sémaphore est nécessaire pour deux raisons :
Pour découvrir le propriétaire d'un sémaphore, utilisez la fonction get_sem_info().
CODES DE RETOUR
|
Les sem_id identifient les sémaphores. L'identifiant (id) est affecté lorsque le sémaphore est créé (create_sem()). Les valeurs sont uniques à travers tout le système.
|
La structure sem_info fournit des informations sur un sémaphore. Vous obtenez cette structure par la fonction get_sem_info(). L'information dans la structure sem_info est garantie consistente en interne, mais l'ensemble de la structure doit être considérée comme non à jour dès que vous la recevez. Elle fournit une photo du sémaphore tel qu'il était juste avant le retour de la fonction.
Les champs sont :
|
Table des matières du kit Noyau | Index du kit du Noyau |