semop, semtimedop - Opérations sur les sémaphores.
Un sémaphore est représenté par une structure anonyme
incluant les membres suivants :
unsigned short semval; /* valeur du sémaphore */
unsigned short semzcnt; /* # Attente pour zéro */
unsigned short semncnt; /* # Attente d'incrément */
pid_t sempid; /* dernier processus agissant */
La fonction
semop
effectue des opérations sur les membres de l'ensemble de sémaphores identifié par
semid.
Chacun des
nsops
éléments dans le tableau pointé par
sops
indique une opération à effectuer sur un sémaphore
en utilisant une structure
struct sembuf
définie comme suit:
short sem_num; /* Numéro du sémaphore (0=premier) */
short sem_op; /* Opération sur le sémaphore */
short sem_flg; /* Options pour l'opération */
Les options possibles pour
sem_flg
sont
IPC_NOWAIT
et
SEM_UNDO.
Si une opération indique l'option
SEM_UNDO,
elle sera annulée lorsque le processus se terminera.
L'ensemble des opérations contenues dans
sops
est effectué
atomiquement.
Les opérations sont toutes réalisées en même temps, et seulement si elle
peuvent toutes être effectuées.
Le comportement de l'appel-système si toutes les opérations ne sont pas
réalisables dépend de la présence de l'attribut
IPC_NOWAIT
dans les champs
sem_flg
décrits plus bas.
Chaque opération est effectuée sur le
sem_num-ième
sémaphore de l'ensemble. Le premier sémaphore est le
numéro
0 .
Pour chaque sémaphore l'opération est l'une des trois décrites
ci-dessous.
Si l'argument
sem_op
est un entier positif, la fonction ajoute cette
valeur à
semval.
De plus si
SEM_UNDO
est demandé, le système met à jour le compteur "undo" du sémaphore
(
semadj).
Cette opération n'est jamais bloquante.
Le processus appelant doit avoir l'autorisation de modification
sur le jeu de sémaphores.
Si
sem_op
vaut zéro le processus attend que
semval
soit nul. Plusieurs cas sont possibles :
Si
semval
vaut zéro, l'appel système continue immédiatement
Sinon, si l'on a réclamé
IPC_NOWAIT
dans
sem_flg,
l'appel système échoue (en annulant les actions précédentes)
et
errno
contient
le code d'erreur
EAGAIN.
Autrement
semzcnt
est incrémenté
de 1 et le processus s'endort jusqu'à ce que l'un
des évènements suivants se produise :
- *
-
semval
devient égal à 0, alors
semzcnt
est décrémenté. L'appel système continue
- *
-
Le jeu de sémaphores est supprimé. L'appel système
échoue et
errno
contient le code d'erreur
EIDRM.
- *
-
Le processus reçoit un signal à intercepter, la
valeur de
semzcnt
est décrémentée et l'appel système échoue avec
errno
contenant le code d'erreur
EINTR.
- *
-
La limite temporelle indiquée par
timeout
dans un
semtimedop
a expiré : l'appel-système échoue avec
errno
contenant
EAGAIN.
Si
sem_op
est inférieur à zéro, le processus appelant doit avoir
l'autorisation de modification sur le jeu de sémaphores.
Si
semval
est supérieur ou égal à la valeur absolue de
sem_op,
la valeur absolue de
sem_op
est soustraite de
semval.
Si
SEM_UNDO
est indiqué, le système met à jour le compteur "undo" du
sémaphore. Puis l'appel système continue.
Autrement si l'on a réclamé
IPC_NOWAIT
dans
sem_flg,
l'appel système échoue (annulant les actions précédentes
et
errno
contient le code d'erreur
EAGAIN.
Sinon
semncnt
est décrémenté de un et le processus s'endort jusqu'à ce
que l'un des évènements suivants se produise :
- *
-
semval
devient supérieur ou égal à la valeur absolue de
sem_op,
alors la valeur
semncnt
est décrémentée, la valeur absolue de
sem_op
est soustraite de
semval
et si
SEM_UNDO
est demandé le système met à jour le compteur "undo" du
sémaphore. Puis l'appel système continue.
- *
-
Le jeu de sémaphores est supprimé. L'appel système
échoue et
errno
contient le code d'erreur
EIDRM.
- *
-
Le processus reçoit un signal à intercepter, la
valeur de
semncnt
est décrémentée et l'appel système échoue avec
errno
contenant le code d'erreur
EINTR.
- *
-
La limite temporelle indiqué par
timeout
dans un
semtimedop
a expiré : l'appel-système échoue avec
errno
contenant
EAGAIN.
en cas de succès, le membre
sempid
de la structure
sem
de chacun des sémaphores indiqués dans le tableau pointé par
sops
est rempli avec le PID du processus appelant.
Enfin
sem_otime
est fixé à l'heure actuelle.
La fonction
semtimedop
se comporte comme
semop
sauf que dans le cas où le processus doit dormir, la
durée maximale du sommeil est limitée par la valeur
spécifiée dans la structure
timespec
dont l'adresse est transmise dans le paramètre
timeout.
Si la limite indiquée a été atteint,
l'appel-système échoue avec
errno
contenant
EAGAIN
(et aucune opération de
sops
n'est réalisée).
Si le paramètre
timeout
est
NULL,
alors
semtimedop
se comporte exactement comme
semop.
Les structures
sem_undo
d'un processus ne sont pas héritées par ses enfants lors d'un
fork(2).
par contre elles sont transmises lors d'un
execve(2).
semop
n'est jamais relancé automatiquement après avoir été interrompu par un gestionnaire
de signal quelque soit l'attribut
SA_RESTART
durant l'installation du gestionnaire.
semadj
est un entier pour le processus qui représente simplement le compte (négatif)
des opérations sur le sémaphore réalisées par
l'attribut
SEM_UNDO.
Quand la valeur d'un sémaphore est fixée directement par une requête
SETVAL
ou
SETALL
de
semctl(2),
la valeur
semadj
correspondante est effacée dans tous les processus.
Les valeurs
semval,
sempid,
semzcnt, et
semnct
pour un sémaphore peuvent être retrouvées avec des appels
semctl(2)
spécifiques.
Les limites système suivantes concernent
semop :
- SEMOPM
-
Nombre maximal d'opérations pour un appel système
semop(32).
- SEMVMX
-
Valeur maximale pour
semval :
dépendante de l'implémentation (32767).
L'implémentation n'a pas de limites intrinsèques pour
la valeur maximale d'effacement en sortie
(
SEMAEM),
le nombre de structure d'annulation sur le système
(
SEMMNU),
et le nombre maximal de structures d'annulation pour un processus.
SVr4, SVID. SVr4 documente les conditions d'erreur supplémentaires
EINVAL, EFBIG, et ENOSPC.
Christophe Blaess, 1996-2003.