%% ipc.tex
%%
-%% Copyright (C) 2000-2004 Simone Piccardi. Permission is granted to
+%% Copyright (C) 2000-2005 Simone Piccardi. Permission is granted to
%% copy, distribute and/or modify this document under the terms of the GNU Free
%% Documentation License, Version 1.1 or any later version published by the
%% Free Software Foundation; with the Invariant Sections being "Un preambolo",
vecchie versioni delle librerie del C, come le libc5.}
\begin{figure}[htb]
- \centering \includegraphics[width=15cm]{img/semtruct}
+ \centering \includegraphics[width=13cm]{img/semtruct}
\caption{Schema della struttura di un insieme di semafori.}
\label{fig:ipc_sem_schema}
\end{figure}
kernel crea una struttura \struct{sem\_queue} che viene aggiunta in fondo alla
coda di attesa associata a ciascun insieme di semafori\footnote{che viene
referenziata tramite i campi \var{sem\_pending} e \var{sem\_pending\_last}
- di \struct{semid\_ds}.}. Nella struttura viene memorizzato il riferimento
-alle operazioni richieste (nel campo \var{sops}, che è un puntatore ad una
-struttura \struct{sembuf}) e al processo corrente (nel campo \var{sleeper})
-poi quest'ultimo viene messo stato di attesa e viene invocato lo
-scheduler\index{\textit{scheduler}} per passare all'esecuzione di un altro
-processo.
+ di \struct{semid\_ds}.}.
+
+Nella struttura viene memorizzato il riferimento alle operazioni richieste
+(nel campo \var{sops}, che è un puntatore ad una struttura \struct{sembuf}) e
+al processo corrente (nel campo \var{sleeper}) poi quest'ultimo viene messo
+stato di attesa e viene invocato lo scheduler\index{\textit{scheduler}} per
+passare all'esecuzione di un altro processo.
Se invece tutte le operazioni possono avere successo queste vengono eseguite
immediatamente, dopo di che il kernel esegue una scansione della coda di
struttura \struct{sem\_queue} viene rimossa e lo stato del processo associato
all'operazione (\var{sleeper}) viene riportato a \textit{running}; il tutto
viene ripetuto fin quando non ci sono più operazioni eseguibili o si è
-svuotata la coda.
-
-Per gestire il meccanismo del ripristino tutte le volte che per un'operazione
-si è specificato il flag \const{SEM\_UNDO} viene mantenuta per ciascun insieme
-di semafori una apposita struttura \struct{sem\_undo} che contiene (nel vettore
-puntato dal campo \var{semadj}) un valore di aggiustamento per ogni semaforo
-cui viene sommato l'opposto del valore usato per l'operazione.
+svuotata la coda. Per gestire il meccanismo del ripristino tutte le volte che
+per un'operazione si è specificato il flag \const{SEM\_UNDO} viene mantenuta
+per ciascun insieme di semafori una apposita struttura \struct{sem\_undo} che
+contiene (nel vettore puntato dal campo \var{semadj}) un valore di
+aggiustamento per ogni semaforo cui viene sommato l'opposto del valore usato
+per l'operazione.
Queste strutture sono mantenute in due liste,\footnote{rispettivamente
attraverso i due campi \var{id\_next} e \var{proc\_next}.} una associata
l'operazione;\footnote{attraverso il campo \var{semundo} di
\struct{task\_struct}, come mostrato in \ref{fig:ipc_sem_schema}.} quando un
processo termina, la lista ad esso associata viene scandita e le operazioni
-applicate al semaforo.
-
-Siccome un processo può accumulare delle richieste di ripristino per semafori
-differenti chiamate attraverso diverse chiamate a \func{semop}, si pone il
-problema di come eseguire il ripristino dei semafori all'uscita del processo,
-ed in particolare se questo può essere fatto atomicamente. Il punto è cosa
-succede quando una delle operazioni previste per il ripristino non può essere
-eseguita immediatamente perché ad esempio il semaforo è occupato; in tal caso
-infatti, se si pone il processo in stato di \textit{sleep} aspettando la
-disponibilità del semaforo (come faceva l'implementazione originaria) si perde
-l'atomicità dell'operazione. La scelta fatta dal kernel è pertanto quella di
-effettuare subito le operazioni che non prevedono un blocco del processo e di
-ignorare silenziosamente le altre; questo però comporta il fatto che il
-ripristino non è comunque garantito in tutte le occasioni.
+applicate al semaforo. Siccome un processo può accumulare delle richieste di
+ripristino per semafori differenti chiamate attraverso diverse chiamate a
+\func{semop}, si pone il problema di come eseguire il ripristino dei semafori
+all'uscita del processo, ed in particolare se questo può essere fatto
+atomicamente.
+
+Il punto è cosa succede quando una delle operazioni previste per il ripristino
+non può essere eseguita immediatamente perché ad esempio il semaforo è
+occupato; in tal caso infatti, se si pone il processo in stato di
+\textit{sleep} aspettando la disponibilità del semaforo (come faceva
+l'implementazione originaria) si perde l'atomicità dell'operazione. La scelta
+fatta dal kernel è pertanto quella di effettuare subito le operazioni che non
+prevedono un blocco del processo e di ignorare silenziosamente le altre;
+questo però comporta il fatto che il ripristino non è comunque garantito in
+tutte le occasioni.
Come esempio di uso dell'interfaccia dei semafori vediamo come implementare
con essa dei semplici \textit{mutex} (cioè semafori binari), tutto il codice