Riscritta buona parte dei semafori con SystemV
authorSimone Piccardi <piccardi@gnulinux.it>
Thu, 29 Aug 2002 17:00:36 +0000 (17:00 +0000)
committerSimone Piccardi <piccardi@gnulinux.it>
Thu, 29 Aug 2002 17:00:36 +0000 (17:00 +0000)
fileadv.tex
ipc.tex

index a3118b09778834913399512c55dc9865f187335f..3b0575ae289f19441b6dbe59a50d2b032f809c0b 100644 (file)
@@ -388,10 +388,11 @@ implementata sia direttamente nel kernel, che in user space attraverso l'uso
 di thread. Al momento\footnote{fino ai kernel della serie 2.4.x, nella serie
   2.5.x è però iniziato un lavoro completo di riscrittura di tutto il sistema
   di I/O, che prevede anche l'introduzione di un nuovo layer per l'I/O
-  asincrono.} esiste una sola versione stabile di questa interfaccia, quella
-delle \acr{glibc}, che è realizzata completamente in user space.  Esistono
-comunque vari progetti sperimentali (come il KAIO della SGI, o i patch di
-Benjamin La Haise) che prevedono un supporto diretto da parte del kernel.
+  asincrono (effettuato a partire dal 2.5.32).} esiste una sola versione
+stabile di questa interfaccia, quella delle \acr{glibc}, che è realizzata
+completamente in user space.  Esistono comunque vari progetti sperimentali
+(come il KAIO della SGI, o i patch di Benjamin La Haise) che prevedono un
+supporto diretto da parte del kernel.
 
 Lo standard prevede che tutte le operazioni di I/O asincrono siano controllate
 attraverso l'uso di una apposita struttura \type{aiocb} (il cui nome sta per
diff --git a/ipc.tex b/ipc.tex
index a7cb5768702723fc39aeafb1b03b17e5da4ae6ca..6bb3836063151a4225ae1c543b38fbd041b621ba 100644 (file)
--- a/ipc.tex
+++ b/ipc.tex
@@ -1368,7 +1368,7 @@ eseguire; i valori possibili sono:
   riceveranno un errore di \macro{EIDRM}, e tutti processi in attesa su
   funzioni di di lettura o di scrittura sulla coda saranno svegliati ricevendo
   il medesimo errore. Questo comando può essere eseguito solo da un processo
-  con userid effettivo corrispondente al creatore o al proprietario della
+  con userid effettivo corrispondente al creatore o al proprietario della
   coda, o all'amministratore.
 \item[\macro{IPC\_SET}] Permette di modificare i permessi ed il proprietario
   della coda, ed il limite massimo sulle dimensioni del totale dei messaggi in
@@ -1415,10 +1415,10 @@ La funzione inserisce il messaggio sulla coda specificata da \param{msqid}; il
 messaggio ha lunghezza specificata da \param{msgsz} ed è passato attraverso
 l'argomento \param{msgp}.  Quest'ultimo deve venire passato sempre in una
 forma che corrisponda alla struttura \var{msgbuf} riportata in
-\figref{fig:ipc_msbug}.  La dimensione massima per il testo di un messaggio
+\figref{fig:ipc_msbuf}.  La dimensione massima per il testo di un messaggio
 non può comunque superare il limite \macro{MSGMAX}.
 
-La struttura di \figref{fig:ipc_msbug} comunque è solo un modello, tanto che
+La struttura di \figref{fig:ipc_msbuf} comunque è solo un modello, tanto che
 la definizione contenuta in \file{sys/msg.h} usa esplicitamente per il secondo
 campo il valore \code{mtext[1]}, che non è di nessuna utilità ai fini pratici.
 La sola cosa che conta è che abbia come primo membro un campo \var{mtype},
@@ -1428,7 +1428,7 @@ invece pu
 del messaggio.
 
 In generale pertanto per inviare un messaggio con \func{msgsnd} si usa
-ridefinire una struttura simile a quella di \figref{fig:ipc_msbug}, adattando
+ridefinire una struttura simile a quella di \figref{fig:ipc_msbuf}, adattando
 alle proprie esigenze il campo \var{mtype}, (o ridefinendo come si vuole il
 corpo del messaggio, anche con più campi o con strutture più complesse) avendo
 però la cura di mantenere nel primo campo un valore di tipo \ctyp{long} che ne
@@ -1438,7 +1438,7 @@ Si tenga presente che la lunghezza che deve essere indicata in questo
 argomento è solo quella del messaggio, non quella di tutta la struttura, se
 cioè \var{message} è una propria struttura che si passa alla funzione,
 \param{msgsz} dovrà essere uguale a \code{sizeof(message)-sizeof(long)}, (se
-consideriamo il caso dell'esempio in \figref{fig:ipc_msbug}, \param{msgsz}
+consideriamo il caso dell'esempio in \figref{fig:ipc_msbuf}, \param{msgsz}
 dovrà essere pari a \macro{LENGHT}).
 
 \begin{figure}[!htb]
@@ -1452,14 +1452,14 @@ dovr
     \end{lstlisting}
   \end{minipage} 
   \normalsize 
-  \caption{Schema della struttura \var{msgbug}, da utilizzare come argomento
+  \caption{Schema della struttura \var{msgbuf}, da utilizzare come argomento
     per inviare/ricevere messaggi.}
-  \label{fig:ipc_msbug}
+  \label{fig:ipc_msbuf}
 \end{figure}
 
 Per capire meglio il funzionamento della funzione riprendiamo in
 considerazione la struttura della coda illustrata in
-\secref{fig:ipc_mq_schema}. Alla chiamata di \func{msgsnd} il nuovo messaggio
+\figref{fig:ipc_mq_schema}. Alla chiamata di \func{msgsnd} il nuovo messaggio
 sarà aggiunto in fondo alla lista inserendo una nuova struttura \var{msg}, il
 puntatore \var{msg\_last} di \var{msqid\_ds} verrà aggiornato, come pure il
 puntatore al messaggio successivo per quello che era il precedente ultimo
@@ -1525,9 +1525,9 @@ rimosso dalla stessa) 
 
 La funzione legge un messaggio dalla coda specificata scrivendolo nel buffer
 indicato da \param{msgp}, che avrà un formato analogo a quello di
-\figref{fig:ipc_msbug}. L'argomento \param{msgsz} indica la lunghezza massima
+\figref{fig:ipc_msbuf}. L'argomento \param{msgsz} indica la lunghezza massima
 del testo del messaggio (equivalente al valore del parametro \macro{LENGHT}
-nell'esempio di \figref{fig:ipc_msbug}).
+nell'esempio di \figref{fig:ipc_msbuf}).
 
 Se il testo del messaggio ha lunghezza inferiore a \param{msgsz} esso viene
 rimosso dalla coda; in caso contrario, se \param{msgflg} è impostato a
@@ -1587,11 +1587,49 @@ il tipo di messaggio, per restituire indietro le frasi ai client.
 \subsection{Semafori}
 \label{sec:ipc_sysv_sem}
 
-Il secondo oggetto introdotto dal \textit{System V IPC} è quello dei semafori.
-Un semaforo è uno speciale contatore che permette di controllare l'accesso a
-risorse condivise. La funzione che permette di creare o ottenere
-l'identificatore di un insieme di semafori è \func{semget}, ed il suo prototipo
-è:
+I semafori non sono meccanismi di intercomunicazione diretta come quelli
+(pipe, fifo e code di messaggi) visti finora, e non consentono di scambiare
+dati fra processi, ma servono piuttosto come meccanismi di sincronizzazione o
+di protezione per le \textsl{sezioni critiche}\index{sezioni critiche} del
+codice (si ricordi quanto detto in \secref{sec:proc_race_cond}). 
+
+Un semaforo è uno speciale contatore, mantenuto nel kernel, che permette, a
+seconda del suo valore, di consentire o meno la prosecuzione dell'esecuzione
+del codice. In questo modo l'accesso ad una risorsa condivisa da più processi
+può essere controllato, associando ad essa un semaforo che consente di
+assicurare che non più di un processo alla volta possa usarla.
+
+Il concetto di semaforo è uno dei concetti base nella programmazione ed è
+assolutamente generico, così come del tutto generali sono modalità con cui lo
+si utilizza. Un processo che deve accedere ad una risorsa eseguirà un
+controllo del semaforo: se questo è positivo il suo valore sarà decrementato,
+indicando che si è consumato una unità della risorsa, ed il processo potrà
+proseguire nell'utilizzo di quest'ultima, provvedendo a rilasciarla, una volta
+completate le operazioni volute, reincrementando il semaforo.
+
+Se al momento del controllo il valore del semaforo è nullo, siamo invece in
+una situazione in cui la risorsa non è disponibile, ed il processo si
+bloccherà in stato di \textit{sleep} fin quando chi la sta utilizzando non la
+rilascerà, incrementando il valore del semaforo. Non appena il semaforo torna
+positivo, indicando che la risorsa è disponibile, il processo sarà svegliato,
+e si potrà operare come nel caso precedente (decremento del semaforo, accesso
+alla risorsa, incremento del semaforo).
+
+Per poter implementare questo tipo di logica le operazioni di controllo e
+decremento del contatore associato al semaforo devono essere atomiche,
+pertanto una realizzazione di un oggetto di questo tipo è necessariamente
+demandata al kernel. La forma più semplice di semaforo è quella del
+\textsl{semaforo binario}, o \textit{mutex}, in cui un valore diverso da zero
+(normalmente 1) indica la libertà di accesso, e un valore nullo l'occupazione
+della risorsa; in generale però si possono usare semafori con valori interi,
+utilizzando il valore del contatore come indicatore del ``numero di risorse''
+ancora disponibili.
+
+Il sistema di comunicazione interprocesso di System V IPC prevede anche i
+semafori, ma gli oggetti utilizzati non sono semafori singoli, ma gruppi di
+semafori detti \textsl{insiemi} (o \textit{semaphore set}); la funzione che
+permette di creare o ottenere l'identificatore di un insieme di semafori è
+\func{semget}, ed il suo prototipo è:
 \begin{functions}
   \headdecl{sys/types.h} 
   \headdecl{sys/ipc.h} 
@@ -1606,15 +1644,55 @@ l'identificatore di un insieme di semafori 
     valori visti per \func{msgget}.}
 \end{functions}
 
-La funzione è del tutto analoga a \func{msgget} ed identico è l'uso degli
-argomenti \param{key} e \param{flag}, per cui non ripeteremo quanto detto al
-proposito in \secref{sec:ipc_sysv_mq}. L'argomento \param{nsems} permette di
-specificare quanti semafori deve contenere l'insieme qualora se ne richieda la
-creazione, e deve essere nullo quando si effettua una richiesta
-dell'identificatore di un insieme già esistente.
+La funzione è del tutto analoga a \func{msgget}, solo che in questo caso
+restituisce l'identificatore di un insieme di semafori, in particolare è
+identico l'uso degli argomenti \param{key} e \param{flag}, per cui non
+ripeteremo quanto detto al proposito in \secref{sec:ipc_sysv_mq}. L'argomento
+\param{nsems} permette di specificare quanti semafori deve contenere l'insieme
+quando se ne richieda la creazione, e deve essere nullo quando si effettua una
+richiesta dell'identificatore di un insieme già esistente.
+
+Purtroppo questa implementazione complica inutilmente lo schema elementare che
+abbiamo descritto, dato che non è possibile definire un singolo semaforo, ma
+se ne deve creare per forza un insieme.  Ma questa in definitiva è solo una
+complicazione inutile, il problema è che i semafori del System V IPC soffrono
+di altri due ben più gravi difetti.
+
+Il primo grave difetto è che non esiste una funzione che permetta di creare ed
+inizializzare un semaforo in un'unica chiamata; occorre prima creare l'insieme
+dei semafori con \func{semget} e poi inizializzarlo con \func{semctl}, si
+perde così ogni possibilità di esegure atomicamente questa operazione.
+
+Il secondo difetto deriva dalla caratteristica generale degli oggetti del
+System V IPC di essere risorse globali di sistema, che non vengono cancellate
+quando nessuno le usa più; ci si così a trova a dover affrontare
+esplicitamente il caso in cui un processo termina per un qualche errore,
+lasciando un semaforo occupato, che resterà tale fino al successivo riavvio
+del sistema. Come vedremo esistono delle modalità per evitare tutto ciò, ma
+diventa necessario indicare esplicitamente che si vuole il ripristino del
+semaforo all'uscita del processo.
+
+\begin{figure}[!htb]
+  \footnotesize \centering
+  \begin{minipage}[c]{15cm}
+    \begin{lstlisting}[labelstep=0]{}
+struct semid_ds
+{
+    struct ipc_perm sem_perm;           /* operation permission struct */
+    time_t sem_otime;                   /* last semop() time */
+    time_t sem_ctime;                   /* last time changed by semctl() */
+    unsigned long int sem_nsems;        /* number of semaphores in set */
+};
+    \end{lstlisting}
+  \end{minipage} 
+  \normalsize 
+  \caption{La struttura \var{semid\_ds}, associata a ciascun insieme di
+    semafori.}
+  \label{fig:ipc_semid_sd}
+\end{figure}
 
 A ciascun insieme di semafori è associata una struttura \var{semid\_ds},
-riportata in \figref{fig:ipc_semid_sd}, come nel caso delle code di messaggi
+riportata in \figref{fig:ipc_semid_sd}. Come nel caso delle code di messaggi
 quando si crea un nuovo insieme di semafori con \func{semget} questa struttura
 viene inizializzata, in particolare il campo \var{sem\_perm} viene
 inizializzato come illustrato in \secref{sec:ipc_sysv_access_control} (si
@@ -1629,29 +1707,42 @@ alterare il semaforo), per quanto riguarda gli altri campi invece:
   effettuata, viene inizializzato a zero.
 \end{itemize*}
 
+Ciascun semaforo dell'isnsieme è realizzato come una struttura di tipo
+\var{sem} che ne contiene i dati essenziali, la sua definizione\footnote{si è
+  riportata la definizione originaria del kernel 1.0, che contiene la prima
+  realizzazione del System V IPC in Linux. In realtà questa struttura ormai è
+  ridotta ai soli due primi membri, e gli altri vengono calcolati
+  dinamicamente. La si è utilizzata a scopo di esempio, perché indica tutti i
+  valori associati ad un semaforo, restituiti dalle funzioni di controllo, e
+  citati dalla pagine di manuale.} è riportata in \figref{fig:ipc_sem}. Di
+norma questa struttura non è accessibile in user space, ma lo sono, in maniera
+indiretta, tramite l'uso delle funzioni di controllo, i valori in essa
+specificati, che indicano rispettivamente: il valore del semaforo, il
+\acr{pid} dell'ultimo processo che ha eseguito una operazione, il numero di
+processi in attesa che esso venga incrementato ed il numero di processi in
+attesa che esso si annulli.
+
 \begin{figure}[!htb]
   \footnotesize \centering
   \begin{minipage}[c]{15cm}
     \begin{lstlisting}[labelstep=0]{}
-struct semid_ds
-{
-    struct ipc_perm sem_perm;           /* operation permission struct */
-    time_t sem_otime;                   /* last semop() time */
-    time_t sem_ctime;                   /* last time changed by semctl() */
-    unsigned long int sem_nsems;        /* number of semaphores in set */
+struct sem {
+  short   sempid;         /* pid of last operation */
+  ushort  semval;         /* current value */
+  ushort  semncnt;        /* num procs awaiting increase in semval */
+  ushort  semzcnt;        /* num procs awaiting semval = 0 */
 };
     \end{lstlisting}
   \end{minipage} 
   \normalsize 
-  \caption{La struttura \var{semid\_ds}, associata a ciascun insieme di
-    semafori.}
-  \label{fig:ipc_semid_sd}
+  \caption{La struttura \var{sem}, che contiene i dati di un signolo semaforo.}
+  \label{fig:ipc_sem}
 \end{figure}
 
 Come per le code di messaggi anche per gli insiemi di semafori esistono una
 serie di limiti, i cui valori sono associati ad altrettante costanti, che si
-sono riportate in \tabref{tab:ipc_sem_limits}. Alcuni di questi sono
-accessibili e modificabili al solito attraverso \func{sysctl} o scrivendo
+sono riportate in \tabref{tab:ipc_sem_limits}. Alcuni di questi limiti sono
+al solito accessibili e modificabili attraverso \func{sysctl} o scrivendo
 direttamente nel file \file{/proc/sys/kernel/sem}.
 
 \begin{table}[htb]
@@ -1680,75 +1771,22 @@ direttamente nel file \file{/proc/sys/kernel/sem}.
   \label{tab:ipc_sem_limits}
 \end{table}
 
-I semafori non sono meccanismi di intercomunicazione diretta come quelli
-(pipe, fifo e code di messaggi) visti finora, e non consentono di scambiare
-dati fra processi, ma servono piuttosto come meccanismi di sincronizzazione o
-di protezione per le \textsl{sezioni critiche}\index{sezioni critiche} del
-codice (si ricordi quanto detto in \secref{sec:proc_race_cond}).
-
-Un semaforo è uno speciale contatore, mantenuto nel kernel, che permette, a
-seconda del suo valore, di consentire o meno la prosecuzione dell'esecuzione
-del codice. In questo modo l'accesso ad una risorsa condivisa da più processi
-può essere controllato, associando ad essa un semaforo che consente di
-assicurare che non più di un processo alla volta possa usarla.
-
-Il concetto di semaforo è uno dei concetti base nella programmazione ed è
-assolutamente generico, così come del tutto generali sono modalità con cui lo
-si utilizza. Un processo che deve accedere ad una risorsa eseguirà un
-controllo del semaforo: se questo è positivo il suo valore sarà decrementato,
-indicando che si è consumato una unità della risorsa, ed il processo potrà
-proseguire nell'utilizzo di quest'ultima, provvedendo a rilasciarla, una volta
-completate le operazioni volute, reincrementando il semaforo.
-
-Se al momento del controllo il valore del semaforo è nullo, siamo invece in
-una situazione in cui la risorsa non è disponibile, ed il processo si
-bloccherà in stato di \textit{sleep} fin quando chi la sta utilizzando non la
-rilascerà, incrementando il valore del semaforo. Non appena il semaforo torna
-positivo, indicando che la risorsa è disponibile, il processo sarà svegliato,
-e si potrà operare come nel caso precedente (decremento del semaforo, accesso
-alla risorsa, incremento del semaforo).
-
-Per poter implementare questo tipo di logica le operazioni di controllo e
-decremento del contatore associato al semaforo devono essere atomiche,
-pertanto una realizzazione di un oggetto di questo tipo è necessariamente
-demandata al kernel. La forma più semplice di semaforo è quella del
-\textsl{semaforo binaria}, o \textit{mutex}, in cui un valore diverso da zero
-(normalmente 1) indica la libertà di accesso, e un valore nullo l'occupazione
-della risorsa; in generale però si possono usare semafori con valori interi,
-utilizzando il valore del contatore come indicatore del ``numero di risorse''
-ancora disponibili.
-
-Purtroppo l'implementazione effettuata nel sistema di intercomunicazione di
-System V complica inutilmente questo schema elementare: anzittutto non è
-possibile definire un singolo semaforo, ma se ne deve creare per forza un
-insieme, specificando il numero di semafori che esso deve contenere con
-l'argomento \param{nsem} di \func{semget}.
-
-Ma i difetti maggiori dei semafori nel System V IPC sono due: il primo è che
-non esiste una funzione che permetta di creare ed inizializzare un semaforo in
-un'unica operazione atomica; occorre prima creare l'insieme con \func{semget}
-e poi inizializzarlo con \func{semctl}.  
-
-Il secondo è che essendo i semafori delle risorse globali di sistema, che non
-vengono cancellate quando nessuno le usa più, ci si trova a dover affrontare
-esplicitamente il caso in cui un processo termina per un qualche errore,
-lasciando un semaforo occupato, che resterà tale per sempre, a meno di non
-rimediare la situazione con opportune operazioni di ripristino.
-
-Come accennato una volta creato l'insieme di semafori per l'inizializzazione
-dei valori occorre ricorrere ad una funzione separata, \func{semctl}, che è
-quella che effettua le operazioni di controllo; il suo prototipo è:
+La funzione che permette di effettuare le varie operazioni di controllo sui
+semafori (fra le quali, come accennato, è impropriamente compresa anche la
+loro inizializzazione) è \func{semctl}; il suo prototipo è:
 \begin{functions}
   \headdecl{sys/types.h} 
   \headdecl{sys/ipc.h} 
   \headdecl{sys/sem.h} 
   
-  \funcdecl{int semctl(int semid, int semnum, int cmd, ...)}
+  \funcdecl{int semctl(int semid, int semnum, int cmd)}
+  \funcdecl{int semctl(int semid, int semnum, int cmd, union semun arg)}
   
   Esegue le operazioni di controllo su un semaforo o un insieme di semafori.
   
-  \bodydesc{La funzione restituisce 0 in caso di successo o -1 in caso di
-    errore, nel qual caso \var{errno} viene settato a:
+  \bodydesc{La funzione restituisce in caso di successo un valore positivo
+    quanto usata con tre argomenti ed un valore nullo quando usata con
+    quattro. In caso di errore restituisce -1, ed \var{errno} viene settata a:
     \begin{errlist}
     \item[\macro{EACCES}] Il processo non ha i privilegi per eseguire
       l'operazione richiesta.
@@ -1764,9 +1802,87 @@ quella che effettua le operazioni di controllo; il suo prototipo 
 \end{functions}
 
 La funzione può avere tre o quattro parametri, a seconda dell'operazione
-specificata con \param{cmd}
+specificata con \param{cmd}, ed opera o sull'intero insieme specificato da
+\param{semid} o sul sigolo semaforo di un insieme, specificato da
+\param{semnum}. Qualora la funzione operi con quattro argomenti \param{arg} è
+un argomento generico che deve essere una \var{union semun}, si è riportato la
+relativa definizione in \figref{fig:ipc_semun}.
 
+\begin{figure}[!htb]
+  \footnotesize \centering
+  \begin{minipage}[c]{15cm}
+    \begin{lstlisting}[labelstep=0]{}
+union semun {
+      int val;                  /* value for SETVAL */
+      struct semid_ds *buf;     /* buffer for IPC_STAT, IPC_SET */
+      unsigned short *array;    /* array for GETALL, SETALL */
+                                /* Linux specific part: */
+      struct seminfo *__buf;    /* buffer for IPC_INFO */
+};
+    \end{lstlisting}
+  \end{minipage} 
+  \normalsize 
+  \caption{La definizione dei possibili valori di una \var{union semun}, usata
+    come quarto argomento della funzione \func{semctl}.}
+  \label{fig:ipc_semun}
+\end{figure}
+
+Il comportamento della funzione, come il numero di parametri, dipende dal
+valore dell'argomento \param{cmd}, che specifica l'azione da intraprendere; i
+possibili valori legali per questo argomento sono:
+\begin{basedescript}{\desclabelwidth{2.2cm}\desclabelstyle{\nextlinelabel}}
+\item[\macro{IPC\_STAT}] Legge i dati dell'insieme di semafori, copiando il
+  contenuto della relativa struttura \var{semid\_ds} all'indirizzo specificato
+  con \var{arg.buf}. Occorre avere il permesso di lettura. L'argomento
+  \param{semnum} viene ignorato.
+\item[\macro{IPC\_RMID}] Rimuove l'insieme di semafori e le relative strutture
+  dati, con effetto immediato. Tutti i processi che erano stato di
+  \textit{sleep} vengono svegliati, ritornando con un errore di \macro{EIDRM}.
+  L'userid effettivo del processo deve corrispondere o al creatore o al
+  proprietario dell'insieme, o all'amministratore. L'argomento \param{semnum}
+  viene ignorato.
+\item[\macro{IPC\_SET}] Permette di modificare i permessi ed il proprietario
+  dell'insieme. I valori devono essere passati in una struttura
+  \var{semid\_ds} puntata da \param{arg.buf} di cui saranno usati soltanto i
+  campi \var{sem\_perm.uid}, \var{sem\_perm.gid} e i nove bit meno
+  significativi di \var{sem\_perm.mode}. L'userid effettivo del processo deve
+  corrispondere o al creatore o al proprietario dell'insieme, o
+  all'amministratore.  L'argomento \param{semnum} viene ignorato.
+\item[\macro{GETALL}] Restituisce il valore corrente di ciascun semaforo
+  dell'insieme (il campo \var{semval} di \var{sem}) nel vettore indicato da
+  \param{arg.array}. Occorre avere il permesso di lettura. L'argomento
+  \param{semnum} viene ignorato.
+\item[\macro{GETNCNT}] Restituisce come valore di ritorno della funzione il
+  numero di processi in attesa che il semaforo \param{semnum} dell'insieme
+  venga incrementato (il campo \var{semncnt} di \var{sem}); va invocata con
+  tre argomenti.  Occorre avere il permesso di lettura.
+\item[\macro{GETPID}] Restituisce come valore di ritorno della funzione il
+  \acr{pid} dell'ultimo processo che ha compiuto una operazione sul semaforo
+  \param{semnum} dell'insieme (il campo \var{sempid} di \var{sem}); va
+  invocata con tre argomenti.  Occorre avere il permesso di lettura.
+\item[\macro{GETVAL}] Restituisce come valore di ritorno della funzione il il
+  valore corrente del semaforo \param{semnum} dell'insieme (il campo
+  \var{semval} di \var{sem}); va invocata con tre argomenti.  Occorre avere il
+  permesso di lettura.
+\item[\macro{GETZCNT}] Restituisce come valore di ritorno della funzione il
+  numero di processi in attesa che il valore del semaforo \param{semnum}
+  dell'insieme diventi nullo (il campo \var{semncnt} di \var{sem}); va
+  invocata con tre argomenti.  Occorre avere il permesso di lettura.
+\item[\macro{SETALL}] Inizializza il valore di tutti i semafori dell'insieme,
+  aggiornando il campo \var{sem\_ctime} di \var{semid\_ds}. I valori devono
+  essere passati nel vettore indicato da \param{arg.array}.  Si devono avere i
+  privilegi di scrittura sul semaforo.  L'argomento \param{semnum} viene
+  ignorato.
+\item[\macro{SETVAL}] Inizializza il semaforo \param{semnum} al valore passato
+  dall'argomento \param{arg.val}, aggiornando il campo \var{sem\_ctime} di
+  \var{semid\_ds}.  Si devono avere i privilegi di scrittura sul semaforo.
+\end{basedescript}
 
+Quando si imposta il valore di un semaforo (sia che lo si faccia per tutto
+l'insieme con \macro{SETALL}, che per uno solo con \macro{SETVAL}, i processi
+in attesa su di esso reagiscono di conseguenza al cambiamento di valore.
+Inoltre la coda delle operazioni di ripristino viene cancellata per tutti i
+semafori il cui valore viene modificato.