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}
 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
 
 \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
 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
 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
 \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.
 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}
 
 }
 \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
 
 \begin{figure}[!htb]
   \footnotesize \centering
@@ -2026,10 +2027,15 @@ struct sembuf
   \label{fig:ipc_sembuf}
 \end{figure}
 
   \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
 \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.
 
 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}
 
 \subsection{Memoria condivisa}
 \label{sec:ipc_sysv_shm}