From: Simone Piccardi Date: Tue, 15 Oct 2002 17:31:51 +0000 (+0000) Subject: Finita semop. X-Git-Url: https://gapil.gnulinux.it/gitweb/?p=gapil.git;a=commitdiff_plain;h=495eb594133c44bbe8a2fae9779e37e67bc152fa Finita semop. --- diff --git a/ipc.tex b/ipc.tex index c879a06..1502f34 100644 --- 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}