Finita semop.
authorSimone Piccardi <piccardi@gnulinux.it>
Tue, 15 Oct 2002 17:31:51 +0000 (17:31 +0000)
committerSimone Piccardi <piccardi@gnulinux.it>
Tue, 15 Oct 2002 17:31:51 +0000 (17:31 +0000)
ipc.tex

diff --git a/ipc.tex b/ipc.tex
index c879a062589ce32c7e5710a16109f5098aab96bb..1502f34f3fe6cde7cf60c807c12bc45d592f15b4 100644 (file)
--- a/ipc.tex
+++ b/ipc.tex
@@ -1488,7 +1488,7 @@ argomento 
 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_msbuf}, \param{msgsz}
-dovrà essere pari a \macro{LENGHT}).
+dovrà essere pari a \macro{LENGTH}).
 
 \begin{figure}[!htb]
   \footnotesize \centering
@@ -1575,7 +1575,7 @@ 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_msbuf}. L'argomento \param{msgsz} indica la lunghezza massima
-del testo del messaggio (equivalente al valore del parametro \macro{LENGHT}
+del testo del messaggio (equivalente al valore del parametro \macro{LENGTH}
 nell'esempio di \figref{fig:ipc_msbuf}).
 
 Se il testo del messaggio ha lunghezza inferiore a \param{msgsz} esso viene
@@ -1938,7 +1938,7 @@ seguenti:
 \end{basedescript}
 
 Quando si imposta il valore di un semaforo (sia che lo si faccia per tutto
-l'insieme con \macro{SETALL}, che per un solo semforo con \macro{SETVAL}), i
+l'insieme con \macro{SETALL}, che per un solo semaforo 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.
@@ -2001,12 +2001,13 @@ vengono effettuate con la funzione \func{semop}, il cui prototipo 
 }
 \end{functions}
 
-La funzione permette di eseguire un certo numero di operazioni, specificato
-dall'argomento \param{nsop}, sull'insieme di semafori \param{semid}. Le
-operazioni da eseguire vengono indicate attraverso un vettore di \param{nsop}
-strutture \var{sembuf}, il cui indirizzo è passato nell'argomento
-\param{sops}. Le operazioni richieste verranno effettivamente eseguite se e
-soltanto se è possibile effettuarle tutte quante.
+La funzione permette di eseguire operazioni multiple sui singoli semafori di
+un insieme. La funzione richiede come primo argomento l'identificatore
+\param{semid} dell'insieme su cui si vuole operare. Il numero di operazioni da
+effettuare viene specificato con l'argomento \param{nsop}, mentre il loro
+contenuto viene passato con un puntatore ad un vettore di strutture
+\var{sembuf} nell'argomento \param{sops}. Le operazioni richieste vengono
+effettivamente eseguite se e soltanto se è possibile effettuarle tutte quante.
 
 \begin{figure}[!htb]
   \footnotesize \centering
@@ -2026,10 +2027,15 @@ struct sembuf
   \label{fig:ipc_sembuf}
 \end{figure}
 
-Il primo campo della struttura \var{sembuf}, la cui definizione è riportata in
-\figref{fig:ipc_sembuf}, serve per indicare su quale semaforo dell'insieme si
-intende eseguire l'operazione; si ricordi che i semafori sono numerati come in
-un vettore, per cui il primo semaforo corrisponde ad un valore nullo di
+Il contenuto di ciascuna operazione deve essere specificato attraverso una
+opportuna struttura \var{sembuf} (la cui definizione è riportata in
+\figref{fig:ipc_sembuf}) che il programma chiamante deve avere cura di
+allocare in un opportuno vettore. La struttura permette di indicare il
+semaforo su cui operare, il tipo di operazione, ed un flag di controllo.
+
+Il campo \var{sem\_num} serve per indicare a quale semaforo dell'insieme fa
+riferimento l'operazione; si ricordi che i semafori sono numerati come in un
+vettore, per cui il primo semaforo corrisponde ad un valore nullo di
 \var{sem\_num}.
 
 Il campo \var{sem\_flg} è un flag, mantenuto come maschera binaria, per il
@@ -2041,26 +2047,88 @@ immediatamente con un errore di \macro{EAGAIN}.  Impostando \macro{SEM\_UNDO}
 si richiede invece che l'operazione venga registrata in modo che il valore del
 semaforo possa essere ripristinato all'uscita del processo.
 
-Infine \var{sem\_op} è il campo che controlla l'operazione che viene eseguita.
-Se si specifica un valore positivo questo viene aggiunto al valore corrente di
-\var{semval}; l'operazione ha sempre successo ed il processo non viene mai
-bloccato. Specificando \macro{SEM\_UNDO} si aggiorna il contatore per il
-ripristino del valore del semaforo. Al chiamate è richiesto il privilegio di
-alterazione (scrittura) sull'insieme di semafori.
-
-Se si specifica un valore nullo il processo deve avere il privilegio di
-lettura sull'insieme. Nel caso \var{semval} sia zero l'esecuzione procede
-immediatamente, altrimenti viene incrementato \var{semzcnt} di uno ed il
-processo resta in stato di \textit{sleep} fintanto che non si ha una delle
-condizioni seguenti:
-\begin{itemize*}
-\item \var{semval} diventa zero, nel qual caso \var{semzcnt} viene
-  decrementato di uno.
-\item l'insieme di semafori viene rimosso, nel qual caso \func{semop} ritorna
-  un errore di \macro{EIDRM}.
-\item il processo chiamante riceve un segnale, nel qual caso \var{semzcnt}
-  viene decrementato di uno e \func{semop} ritorna un errore di \macro{EINTR}.
-\end{itemize*}
+Infine \var{sem\_op} è il campo che controlla l'operazione che viene eseguita
+e determina il comportamento della chiamata a \func{semop}; tre sono i casi
+possibili:
+\begin{basedescript}{\desclabelwidth{2.0cm}}
+\item[\var{sem\_op}$>0$] In questo caso il valore di \var{sem\_op} viene
+  aggiunto al valore corrente di \var{semval}. La funzione ritorna
+  immediatamente (con un errore di \macro{ERANGE} qualora si sia superato il
+  limite \macro{SEMVMX}) ed il processo non viene bloccato in nessun caso.
+  Specificando \macro{SEM\_UNDO} si aggiorna il contatore per il ripristino
+  del valore del semaforo. Al processo chiamante è richiesto il privilegio di
+  alterazione (scrittura) sull'insieme di semafori.
+  
+\item[\var{sem\_op}$=0$] Nel caso \var{semval} sia zero l'esecuzione procede
+  immediatamente. Se \var{semval} è diverso da zero il comportamento è
+  controllato da \var{sem\_flg}, se è stato impostato \macro{IPC\_NOWAIT} la
+  funzione ritorna con un errore di \macro{EAGAIN}, altrimenti viene
+  incrementato \var{semzcnt} di uno ed il processo resta in stato di
+  \textit{sleep} fintanto che non si ha una delle condizioni seguenti:
+  \begin{itemize*}
+  \item \var{semval} diventa zero, nel qual caso \var{semzcnt} viene
+    decrementato di uno.
+  \item l'insieme di semafori viene rimosso, nel qual caso \func{semop} ritorna
+    un errore di \macro{EIDRM}.
+  \item il processo chiamante riceve un segnale, nel qual caso \var{semzcnt}
+    viene decrementato di uno e \func{semop} ritorna un errore di
+    \macro{EINTR}.
+  \end{itemize*}
+  Al processo chiamante è richiesto il privilegio di lettura dell'insieme dei
+  semafori.
+  
+\item[\var{sem\_op}$<0$] Nel caso in cui \var{semval} è maggiore o uguale del
+  valore assoluto di \var{sem\_op} (se cioè la somma dei due valori resta
+  positiva o nulla) i valori vengono sommati e la funzione ritorna
+  immediatamente; qualora si sia impostato \macro{SEM\_UNDO} viene anche
+  aggiornato il contatore per il ripristino del valore del semaforo. In caso
+  contrario (quando cioè la somma darebbe luogo ad un valore di \var{semval}
+  negativo) se si è impostato \macro{IPC\_NOWAIT} la funzione ritorna con un
+  errore di \macro{EAGAIN}, altrimenti viene incrementato di uno \var{semncnt}
+  ed il processo resta in stato di \textit{sleep} fintanto che non si ha una
+  delle condizioni seguenti:
+  \begin{itemize*}
+  \item \var{semval} diventa maggiore o uguale del valore assoluto di
+    \var{sem\_op}, nel qual caso \var{semncnt} viene decrementato di uno, il
+    valore di \var{sem\_op} viene sommato a \var{semval}, e se era stato
+    impostato \macro{SEM\_UNDO} viene aggiornato il contatore per il
+    ripristino del valore del semaforo.
+  \item l'insieme di semafori viene rimosso, nel qual caso \func{semop} ritorna
+    un errore di \macro{EIDRM}.
+  \item il processo chiamante riceve un segnale, nel qual caso \var{semncnt}
+    viene decrementato di uno e \func{semop} ritorna un errore di
+    \macro{EINTR}.
+  \end{itemize*}    
+  Al processo chiamante è richiesto il privilegio di alterazione (scrittura)
+  sull'insieme di semafori.
+\end{basedescript}
+
+In caso di successo della funzione viene aggiornato di \var{sempid} per ogni
+semaforo modificato al valore del \acr{pid} del processo chiamante; inoltre
+vengono pure aggiornati al tempo corrente i campi \var{sem\_otime} e
+\var{sem\_ctime}.
+
+Dato che, come già accennato in precedenza, in caso di uscita inaspettata i
+semafori possono restare occupati, abbiamo visto come \func{semop} permetta di
+attivare un meccanismo di ripristino attraverso l'uso del flag
+\macro{SEM\_UNDO}. Il meccanismo è implementato tramite una apposita struttura
+\var{sem\_undo}, associata ad ogni processo per ciascun semaforo che esso ha
+modificato; all'uscita i semafori modificati vengono ripristinati, e le
+strutture disallocate.  Per mantenere coerente il comportamento queste
+strutture non vengono ereditate attraverso una \func{fork} (altrimenti si
+avrebbe un doppio ripristino), mentre vengono passate nell'esecuzione di una
+\func{exec} (altrimenti non si avrebbe ripristino).
+
+Resta comunque insoluto il problema di fondo di questo meccanismo, che non si
+adatta al concetto di operazioni atomiche su un semaforo, dato che le
+richieste di ripristino si accumulano attraverso diverse chiamate a
+\func{semop}, cosa succede se all'uscita del processo?  Si deve porre il
+processo in stato di \textit{sleep} o andare avanti come se fosse stato
+impostato \macro{IPC\_NOWAIT}. La scelta del kernel è quella di effettuare le
+operazioni che non prevedono un blocco del processo ed ignorare
+silenziosamente le altre. Questo comporta che un comportamento senza problemi
+può essere garantito solo per i semafori privati.
+
 
 \subsection{Memoria condivisa}
 \label{sec:ipc_sysv_shm}