Aggiunte alcune note in piu` sulla memoria virtuale. Introdotto il non-linar
[gapil.git] / fileadv.tex
index 3c5cb61271b969e08dd9bf38c9aeeb3065079969..e5205099135084e515d8568f2a628afb33718bf7 100644 (file)
@@ -1,9 +1,9 @@
 %% fileadv.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 "Prefazione",
+%% Free Software Foundation; with the Invariant Sections being "Un preambolo",
 %% with no Front-Cover Texts, and with no Back-Cover Texts.  A copy of the
 %% license is included in the section entitled "GNU Free Documentation
 %% License".
@@ -36,14 +36,14 @@ I/O.
 \label{sec:file_noblocking}
 
 Abbiamo visto in sez.~\ref{sec:sig_gen_beha}, affrontando la suddivisione fra
-\textit{fast} e \textit{slow} system call,\index{system call lente} che in
+\textit{fast} e \textit{slow} system call,\index{system~call~lente} che in
 certi casi le funzioni di I/O possono bloccarsi indefinitamente.\footnote{si
   ricordi però che questo può accadere solo per le pipe, i
-  socket\index{socket} ed alcuni file di dispositivo\index{file!di
-    dispositivo}; sui file normali le funzioni di lettura e scrittura
-  ritornano sempre subito.}  Ad esempio le operazioni di lettura possono
-bloccarsi quando non ci sono dati disponibili sul descrittore su cui si sta
-operando.
+  socket\index{socket} ed alcuni file di
+  dispositivo\index{file!di~dispositivo}; sui file normali le funzioni di
+  lettura e scrittura ritornano sempre subito.}  Ad esempio le operazioni di
+lettura possono bloccarsi quando non ci sono dati disponibili sul descrittore
+su cui si sta operando.
 
 Questo comportamento causa uno dei problemi più comuni che ci si trova ad
 affrontare nelle operazioni di I/O, che si verifica quando si deve operare con
@@ -56,21 +56,20 @@ un'altro disponibile. Questo comporta nel migliore dei casi una operazione
 ritardata inutilmente nell'attesa del completamento di quella bloccata, mentre
 nel peggiore dei casi (quando la conclusione della operazione bloccata dipende
 da quanto si otterrebbe dal file descriptor ``\textsl{disponibile}'') si
-potrebbe addirittura arrivare ad un \textit{deadlock}\index{deadlock}.
+potrebbe addirittura arrivare ad un \textit{deadlock}\itindex{deadlock}.
 
 Abbiamo già accennato in sez.~\ref{sec:file_open} che è possibile prevenire
-questo tipo di comportamento delle funzioni di I/O aprendo un file in quella
-che viene chiamata \textsl{modalità non-bloccante}, attraverso l'uso del flag
-\const{O\_NONBLOCK} nella chiamata di \func{open}. In questo caso le funzioni
-di input/output eseguite sul file che si sarebbero bloccate, ritornano
-immediatamente, restituendo l'errore \errcode{EAGAIN}.
-
-L'utilizzo di questa modalità di I/O permette di risolvere il problema
-controllando a turno i vari file descriptor, in un ciclo in cui si ripete
-l'accesso fintanto che esso non viene garantito.  Ovviamente questa tecnica,
-detta \textit{polling}\index{polling}, è estremamente inefficiente: si tiene
-costantemente impiegata la CPU solo per eseguire in continuazione delle system
-call che nella gran parte dei casi falliranno. 
+questo tipo di comportamento delle funzioni di I/O aprendo un file in
+\textsl{modalità non-bloccante}, attraverso l'uso del flag \const{O\_NONBLOCK}
+nella chiamata di \func{open}. In questo caso le funzioni di input/output
+eseguite sul file che si sarebbero bloccate, ritornano immediatamente,
+restituendo l'errore \errcode{EAGAIN}.  L'utilizzo di questa modalità di I/O
+permette di risolvere il problema controllando a turno i vari file descriptor,
+in un ciclo in cui si ripete l'accesso fintanto che esso non viene garantito.
+Ovviamente questa tecnica, detta \textit{polling}\itindex{polling}, è
+estremamente inefficiente: si tiene costantemente impiegata la CPU solo per
+eseguire in continuazione delle system call che nella gran parte dei casi
+falliranno.
 
 Per superare questo problema è stato introdotto il concetto di \textit{I/O
   multiplexing}, una nuova modalità di operazioni che consenta di tenere sotto
@@ -89,11 +88,11 @@ ulteriori dettagli e qualche esempio in sez.~\ref{sec:TCP_sock_multiplexing}.
 \subsection{Le funzioni \func{select} e \func{pselect}}
 \label{sec:file_select}
 
-Il primo ad introdurre una interfaccia per l'\textit{I/O multiplexing} è stato
-BSD,\footnote{la funzione \func{select} è apparsa in BSD4.2 e standardizzata
-  in BSD4.4, ma è stata portata su tutti i sistemi che supportano i
-  \textit{socket}\index{socket}, compreso le varianti di System V.}  con la
-funzione \funcd{select}, il cui prototipo è:
+Il primo kernel unix-like ad introdurre una interfaccia per l'\textit{I/O
+  multiplexing} è stato BSD,\footnote{la funzione \func{select} è apparsa in
+  BSD4.2 e standardizzata in BSD4.4, ma è stata portata su tutti i sistemi che
+  supportano i \textit{socket}\index{socket}, compreso le varianti di System
+  V.}  con la funzione \funcd{select}, il cui prototipo è:
 \begin{functions}
   \headdecl{sys/time.h}
   \headdecl{sys/types.h}
@@ -124,27 +123,29 @@ degli insiemi specificati (\param{readfds}, \param{writefds} e
 \param{exceptfds}), non diventa attivo, per un tempo massimo specificato da
 \param{timeout}.
 
+\itindbeg{file~descriptor~set} 
+
 Per specificare quali file descriptor si intende \textsl{selezionare}, la
 funzione usa un particolare oggetto, il \textit{file descriptor set},
 identificato dal tipo \type{fd\_set}, che serve ad identificare un insieme di
-file descriptor, in maniera analoga a come un \textit{signal set} (vedi
-sez.~\ref{sec:sig_sigset}) identifica un insieme di segnali. Per la
-manipolazione di questi \textit{file descriptor set} si possono usare delle
-opportune macro di preprocessore:
+file descriptor, in maniera analoga a come un
+\itindex{signal~set}\textit{signal set} (vedi sez.~\ref{sec:sig_sigset})
+identifica un insieme di segnali. Per la manipolazione di questi \textit{file
+  descriptor set} si possono usare delle opportune macro di preprocessore:
 \begin{functions}
   \headdecl{sys/time.h}
   \headdecl{sys/types.h}
   \headdecl{unistd.h}
-  \funcdecl{FD\_ZERO(fd\_set *set)}
+  \funcdecl{void \macro{FD\_ZERO}(fd\_set *set)}
   Inizializza l'insieme (vuoto).
 
-  \funcdecl{FD\_SET(int fd, fd\_set *set)}
+  \funcdecl{void \macro{FD\_SET}(int fd, fd\_set *set)}
   Inserisce il file descriptor \param{fd} nell'insieme.
 
-  \funcdecl{FD\_CLR(int fd, fd\_set *set)}
+  \funcdecl{void \macro{FD\_CLR}(int fd, fd\_set *set)}
   Rimuove il file descriptor \param{fd} nell'insieme.
   
-  \funcdecl{FD\_ISSET(int fd, fd\_set *set)}
+  \funcdecl{int \macro{FD\_ISSET}(int fd, fd\_set *set)}
   Controlla se il file descriptor \param{fd} è nell'insieme.
 \end{functions}
 
@@ -172,30 +173,31 @@ sez.~\ref{sec:TCP_urgent_data}).
 
 Dato che in genere non si tengono mai sotto controllo fino a
 \const{FD\_SETSIZE} file contemporaneamente la funzione richiede di
-specificare qual'è il numero massimo dei file descriptor indicati nei tre
+specificare qual è il numero massimo dei file descriptor indicati nei tre
 insiemi precedenti. Questo viene fatto per efficienza, per evitare di passare
 e far controllare al kernel una quantità di memoria superiore a quella
 necessaria. Questo limite viene indicato tramite l'argomento \param{n}, che
 deve corrispondere al valore massimo aumentato di uno.\footnote{i file
   descriptor infatti sono contati a partire da zero, ed il valore indica il
   numero di quelli da tenere sotto controllo; dimenticarsi di aumentare di uno
-  il valore di \param{n} è un errore comune.}
-
-Infine l'argomento \param{timeout}, specifica un tempo massimo di attesa prima
-che la funzione ritorni; se impostato a \val{NULL} la funzione attende
-indefinitamente. Si può specificare anche un tempo nullo (cioè una struttura
-\struct{timeval} con i campi impostati a zero), qualora si voglia
-semplicemente controllare lo stato corrente dei file descriptor.
+  il valore di \param{n} è un errore comune.}  Infine l'argomento
+\param{timeout}, specifica un tempo massimo di attesa prima che la funzione
+ritorni; se impostato a \val{NULL} la funzione attende indefinitamente. Si può
+specificare anche un tempo nullo (cioè una struttura \struct{timeval} con i
+campi impostati a zero), qualora si voglia semplicemente controllare lo stato
+corrente dei file descriptor.
+\itindend{file~descriptor~set}
 
 La funzione restituisce il numero di file descriptor pronti,\footnote{questo è
   il comportamento previsto dallo standard, ma la standardizzazione della
   funzione è recente, ed esistono ancora alcune versioni di Unix che non si
   comportano in questo modo.}  e ciascun insieme viene sovrascritto per
-indicare i file descriptor pronti per le operazioni ad esso relative, in modo
-da poterli controllare con \const{FD\_ISSET}.  Se invece si ha un timeout
-viene restituito un valore nullo e gli insiemi non vengono modificati.  In
-caso di errore la funzione restituisce -1, ed i valori dei tre insiemi sono
-indefiniti e non si può fare nessun affidamento sul loro contenuto.
+indicare quali sono i file descriptor pronti per le operazioni ad esso
+relative, in modo da poterli controllare con \macro{FD\_ISSET}.  Se invece si
+ha un timeout viene restituito un valore nullo e gli insiemi non vengono
+modificati.  In caso di errore la funzione restituisce -1, ed i valori dei tre
+insiemi sono indefiniti e non si può fare nessun affidamento sul loro
+contenuto.
 
 In Linux \func{select} modifica anche il valore di \param{timeout},
 impostandolo al tempo restante in caso di interruzione prematura; questo è
@@ -268,34 +270,40 @@ immediatamente prima di eseguire l'attesa, e ripristinata al ritorno della
 funzione.
 
 L'uso di \param{sigmask} è stato introdotto allo scopo di prevenire possibili
-race condition\index{race condition} quando ci si deve porre in attesa sia di
-un segnale che di dati.\footnote{in Linux però non è stata ancora introdotta
-  la relativa system call, pertanto la funzione è implementata nelle
-  \acr{glibc} attraverso \func{select} e la possibilità di race condition
-  permane.} La tecnica classica è quella di utilizzare il gestore per
-impostare una variabile globale e controllare questa nel corpo principale del
-programma; abbiamo visto in sez.~\ref{sec:sig_example} come questo lasci spazio
-a possibili race condition, per cui diventa essenziale utilizzare
-\func{sigprocmask} per disabilitare la ricezione del segnale prima di eseguire
-il controllo e riabilitarlo dopo l'esecuzione delle relative operazioni, onde
-evitare l'arrivo di un segnale immediatamente dopo il controllo, che andrebbe
-perso.
+\textit{race condition}\itindex{race~condition} quando ci si deve porre in
+attesa sia di un segnale che di dati. La tecnica classica è quella di
+utilizzare il gestore per impostare una variabile globale e controllare questa
+nel corpo principale del programma; abbiamo visto in
+sez.~\ref{sec:sig_example} come questo lasci spazio a possibili race
+condition, per cui diventa essenziale utilizzare \func{sigprocmask} per
+disabilitare la ricezione del segnale prima di eseguire il controllo e
+riabilitarlo dopo l'esecuzione delle relative operazioni, onde evitare
+l'arrivo di un segnale immediatamente dopo il controllo, che andrebbe perso.
 
 Nel nostro caso il problema si pone quando oltre al segnale si devono tenere
 sotto controllo anche dei file descriptor con \func{select}, in questo caso si
 può fare conto sul fatto che all'arrivo di un segnale essa verrebbe interrotta
 e si potrebbero eseguire di conseguenza le operazioni relative al segnale e
 alla gestione dati con un ciclo del tipo:
-\includecodesnip{listati/select_race.c} qui però emerge una race
-condition,\index{race condition} perché se il segnale arriva prima della
+\includecodesnip{listati/select_race.c} qui però emerge una \textit{race
+  condition},\itindex{race~condition} perché se il segnale arriva prima della
 chiamata a \func{select}, questa non verrà interrotta, e la ricezione del
 segnale non sarà rilevata.
 
-Per questo è stata introdotta \func{pselect}, che attraverso l'argomento
+Per questo è stata introdotta \func{pselect} che attraverso l'argomento
 \param{sigmask} permette di riabilitare la ricezione il segnale
-contestualmente all'esecuzione della funzione, e ribloccandolo non appena essa
-ritorna. In questo modo il precedente codice potrebbe essere modificato
-nel seguente modo: 
+contestualmente all'esecuzione della funzione,\footnote{in Linux però non è
+  presente la relativa system call, e la funzione è implementata nelle
+  \acr{glibc} attraverso \func{select} (vedi \texttt{man select\_tut}) per cui
+  la possibilità di \itindex{race~condition}\textit{race condition} permane;
+  esiste però una soluzione, chiamata \itindex{self-pipe trick}
+  \textit{self-pipe trick}, che consiste nell'aprire una pipe (vedi
+  sez.~\ref{sec:ipc_pipes}) ed usare \func{select} sul capo in lettura della
+  stessa, e indicare l'arrivo di un segnale scrivendo sul capo in scrittura
+  all'interno del manipolatore; in questo modo anche se il segnale va perso
+  prima della chiamata di \func{select} questa lo riconoscerà comunque dalla
+  presenza di dati sulla pipe.} ribloccandolo non appena essa ritorna, così
+che il precedente codice potrebbe essere riscritto nel seguente modo:
 \includecodesnip{listati/pselect_norace.c} 
 in questo caso utilizzando \var{oldmask} durante l'esecuzione di
 \func{pselect} la ricezione del segnale sarà abilitata, ed in caso di
@@ -315,12 +323,12 @@ cui prototipo 
 \begin{prototype}{sys/poll.h}
   {int poll(struct pollfd *ufds, unsigned int nfds, int timeout)}
   
-  La funzione attende un cambiamento di stato per uno dei file descriptor
-  specificati da \param{ufds}.
+  La funzione attende un cambiamento di stato su un insieme di file
+  descriptor.
   
   \bodydesc{La funzione restituisce il numero di file descriptor con attività
-    in caso di successo, o 0 se c'è stato un timeout; in caso di errore viene
-    restituito -1 ed \var{errno} assumerà uno dei valori:
+    in caso di successo, o 0 se c'è stato un timeout e -1 in caso di errore,
+    ed in quest'ultimo caso \var{errno} assumerà uno dei valori:
   \begin{errlist}
   \item[\errcode{EBADF}] Si è specificato un file descriptor sbagliato in uno
     degli insiemi.
@@ -336,8 +344,8 @@ file descriptor, specificati attraverso il puntatore \param{ufds} ad un
 vettore di strutture \struct{pollfd}.  Come con \func{select} si può
 interrompere l'attesa dopo un certo tempo, questo deve essere specificato con
 l'argomento \param{timeout} in numero di millisecondi: un valore negativo
-indica un'attesa indefinita, mentre un valore comporta il ritorno immediato (e
-può essere utilizzato per impiegare \func{poll} in modalità
+indica un'attesa indefinita, mentre un valore nullo comporta il ritorno
+immediato (e può essere utilizzato per impiegare \func{poll} in modalità
 \textsl{non-bloccante}).
 
 \begin{figure}[!htb]
@@ -412,8 +420,8 @@ distinzione ha senso solo per i dati \textit{out-of-band} dei socket (vedi
 sez.~\ref{sec:TCP_urgent_data}), ma su questo e su come \func{poll} reagisce
 alle varie condizioni dei socket torneremo in sez.~\ref{sec:TCP_serv_poll},
 dove vedremo anche un esempio del suo utilizzo. Si tenga conto comunque che le
-costanti relative ai diversi tipi di dati (come \macro{POLLRDNORM} e
-\macro{POLLRDBAND}) sono utilizzabili soltanto qualora si sia definita la
+costanti relative ai diversi tipi di dati (come \const{POLLRDNORM} e
+\const{POLLRDBAND}) sono utilizzabili soltanto qualora si sia definita la
 macro \macro{\_XOPEN\_SOURCE}.\footnote{e ci si ricordi di farlo sempre in
   testa al file, definirla soltanto prima di includere \file{sys/poll.h} non è
   sufficiente.}
@@ -487,7 +495,7 @@ percentuale) sono diventati attivi.
 
 Tuttavia con l'implementazione classica dei segnali questa modalità di I/O
 presenta notevoli problemi, dato che non è possibile determinare, quando i
-file descriptor sono più di uno, qual'è quello responsabile dell'emissione del
+file descriptor sono più di uno, qual è quello responsabile dell'emissione del
 segnale. Inoltre dato che i segnali normali non si accodano (si ricordi quanto
 illustrato in sez.~\ref{sec:sig_notification}), in presenza di più file
 descriptor attivi contemporaneamente, più segnali emessi nello stesso momento
@@ -536,7 +544,7 @@ effettuare in contemporanea le operazioni di calcolo e quelle di I/O.
 
 Benché la modalità di apertura asincrona di un file possa risultare utile in
 varie occasioni (in particolar modo con i socket\index{socket} e gli altri
-file per i quali le funzioni di I/O sono \index{system call lente}system call
+file per i quali le funzioni di I/O sono \index{system~call~lente}system call
 lente), essa è comunque limitata alla notifica della disponibilità del file
 descriptor per le operazioni di I/O, e non ad uno svolgimento asincrono delle
 medesime.  Lo standard POSIX.1b definisce una interfaccia apposita per l'I/O
@@ -728,11 +736,11 @@ esaurimento.
 
 Oltre alle operazioni di lettura e scrittura l'interfaccia POSIX.1b mette a
 disposizione un'altra operazione, quella di sincronizzazione dell'I/O,
-compiuta dalla funzione \func{aio\_fsync}, che ha lo stesso effetto della
+compiuta dalla funzione \funcd{aio\_fsync}, che ha lo stesso effetto della
 analoga \func{fsync}, ma viene eseguita in maniera asincrona; il suo prototipo
 è:
 \begin{prototype}{aio.h}
-{ssize\_t aio\_return(int op, struct aiocb *aiocbp)} 
+{int aio\_fsync(int op, struct aiocb *aiocbp)} 
 
 Richiede la sincronizzazione dei dati per il file indicato da \param{aiocbp}.
   
@@ -938,7 +946,7 @@ prototipi sono:
   \end{errlist}
   ed inoltre \errval{EISDIR}, \errval{ENOMEM}, \errval{EFAULT} (se non sono
   stato allocati correttamente i buffer specificati nei campi
-  \func{iov\_base}), più tutti gli ulteriori errori che potrebbero avere le
+  \var{iov\_base}), più tutti gli ulteriori errori che potrebbero avere le
   usuali funzioni di lettura e scrittura eseguite su \param{fd}.}
 \end{functions}
 
@@ -969,50 +977,59 @@ si sono specificati nel vettore \param{vector}.
 \subsection{File mappati in memoria}
 \label{sec:file_memory_map}
 
+\itindbeg{memory~mapping}
 Una modalità alternativa di I/O, che usa una interfaccia completamente diversa
 rispetto a quella classica vista in cap.~\ref{cha:file_unix_interface}, è il
 cosiddetto \textit{memory-mapped I/O}, che, attraverso il meccanismo della
 \textsl{paginazione}\index{paginazione} usato dalla memoria virtuale (vedi
 sez.~\ref{sec:proc_mem_gen}), permette di \textsl{mappare} il contenuto di un
-file in una sezione dello spazio di indirizzi del processo. Il meccanismo è
-illustrato in fig.~\ref{fig:file_mmap_layout}, una sezione del file viene
-riportata direttamente nello spazio degli indirizzi del programma. Tutte le
-operazioni su questa zona verranno riportate indietro sul file dal meccanismo
-della memoria virtuale\index{memoria virtuale} che trasferirà il contenuto di
-quel segmento sul file invece che nella swap, per cui si può parlare tanto di
-file mappato in memoria, quanto di memoria mappata su file.
+file in una sezione dello spazio di indirizzi del processo. 
+
+Il meccanismo è illustrato in fig.~\ref{fig:file_mmap_layout}, una sezione del
+file viene \textsl{mappata} direttamente nello spazio degli indirizzi del
+programma.  Tutte le operazioni di lettura e scrittura su variabili contenute
+in questa zona di memoria verranno eseguite leggendo e scrivendo dal contenuto
+del file attraverso il sistema della memoria virtuale\index{memoria~virtuale}
+che in maniera analoga a quanto avviene per le pagine che vengono salvate e
+rilette nella swap, si incaricherà di sincronizzare il contenuto di quel
+segmento di memoria con quello del file mappato su di esso.  Per questo motivo
+si può parlare tanto di \textsl{file mappato in memoria}, quanto di
+\textsl{memoria mappata su file}.
 
 \begin{figure}[htb]
   \centering
-  \includegraphics[width=7.cm]{img/mmap_layout}
+  \includegraphics[width=14cm]{img/mmap_layout}
   \caption{Disposizione della memoria di un processo quando si esegue la
   mappatura in memoria di un file.}
   \label{fig:file_mmap_layout}
 \end{figure}
 
-Tutto questo comporta una notevole semplificazione delle operazioni di I/O, in
-quanto non sarà più necessario utilizzare dei buffer intermedi su cui
-appoggiare i dati da traferire, ma questi potranno essere acceduti
-direttamente nella sezione di memoria mappata; inoltre questa interfaccia è
-più efficiente delle usuali funzioni di I/O, in quanto permette di caricare in
-memoria solo le parti del file che sono effettivamente usate ad un dato
-istante.
+L'uso del \textit{memory-mapping} comporta una notevole semplificazione delle
+operazioni di I/O, in quanto non sarà più necessario utilizzare dei buffer
+intermedi su cui appoggiare i dati da traferire, poiché questi potranno essere
+acceduti direttamente nella sezione di memoria mappata; inoltre questa
+interfaccia è più efficiente delle usuali funzioni di I/O, in quanto permette
+di caricare in memoria solo le parti del file che sono effettivamente usate ad
+un dato istante.
 
 Infatti, dato che l'accesso è fatto direttamente attraverso la memoria
-virtuale,\index{memoria virtuale} la sezione di memoria mappata su cui si
+virtuale,\index{memoria~virtuale} la sezione di memoria mappata su cui si
 opera sarà a sua volta letta o scritta sul file una pagina alla volta e solo
 per le parti effettivamente usate, il tutto in maniera completamente
 trasparente al processo; l'accesso alle pagine non ancora caricate avverrà
 allo stesso modo con cui vengono caricate in memoria le pagine che sono state
-salvate sullo swap.  Infine in situazioni in cui la memoria è scarsa, le
-pagine che mappano un file vengono salvate automaticamente, così come le
-pagine dei programmi vengono scritte sulla swap; questo consente di accedere
-ai file su dimensioni il cui solo limite è quello dello spazio di indirizzi
-disponibile, e non della memoria su cui possono esserne lette delle porzioni.
-
-L'interfaccia prevede varie funzioni per la gestione del \textit{memory mapped
-  I/O}, la prima di queste è \funcd{mmap}, che serve ad eseguire la mappatura
-in memoria di un file; il suo prototipo è:
+salvate sullo swap.
+
+Infine in situazioni in cui la memoria è scarsa, le pagine che mappano un file
+vengono salvate automaticamente, così come le pagine dei programmi vengono
+scritte sulla swap; questo consente di accedere ai file su dimensioni il cui
+solo limite è quello dello spazio di indirizzi disponibile, e non della
+memoria su cui possono esserne lette delle porzioni.
+
+L'interfaccia POSIX implementata da Linux prevede varie funzioni per la
+gestione del \textit{memory mapped I/O}, la prima di queste, che serve ad
+eseguire la mappatura in memoria di un file, è \funcd{mmap}; il suo prototipo
+è:
 \begin{functions}
   
   \headdecl{unistd.h}
@@ -1021,7 +1038,7 @@ in memoria di un file; il suo prototipo 
   \funcdecl{void * mmap(void * start, size\_t length, int prot, int flags, int
     fd, off\_t offset)}
   
-  Esegue la mappatura in memoria del file \param{fd}.
+  Esegue la mappatura in memoria della sezione specificata del file \param{fd}.
   
   \bodydesc{La funzione restituisce il puntatore alla zona di memoria mappata
     in caso di successo, e \const{MAP\_FAILED} (-1) in caso di errore, nel
@@ -1039,11 +1056,18 @@ in memoria di un file; il suo prototipo 
       dimensione delle pagine).
     \item[\errcode{ETXTBSY}] Si è impostato \const{MAP\_DENYWRITE} ma
       \param{fd} è aperto in scrittura.
-    \item[\errcode{EAGAIN}] Il file è bloccato, o si è bloccata troppa memoria.
+    \item[\errcode{EAGAIN}] Il file è bloccato, o si è bloccata troppa memoria
+      rispetto a quanto consentito dai limiti di sistema (vedi
+      sez.~\ref{sec:sys_resource_limit}).
     \item[\errcode{ENOMEM}] Non c'è memoria o si è superato il limite sul
       numero di mappature possibili.
     \item[\errcode{ENODEV}] Il filesystem di \param{fd} non supporta il memory
       mapping.
+    \item[\errcode{EPERM}] L'argomento \param{prot} ha richiesto
+      \const{PROT\_EXEC}, ma il filesystem di \param{fd} è montato con
+      l'opzione \texttt{noexec}.
+    \item[\errcode{ENFILE}] Si è superato il limite del sistema sul numero di
+      file aperti (vedi sez.~\ref{sec:sys_resource_limit}).
     \end{errlist}
   }
 \end{functions}
@@ -1077,16 +1101,16 @@ multiplo della dimensione di una pagina di memoria.
 Il valore dell'argomento \param{prot} indica la protezione\footnote{in Linux
   la memoria reale è divisa in pagine: ogni processo vede la sua memoria
   attraverso uno o più segmenti lineari di memoria virtuale.  Per ciascuno di
-  questi segmenti il kernel mantiene nella \textit{page table} la mappatura
-  sulle pagine di memoria reale, ed le modalità di accesso (lettura,
-  esecuzione, scrittura); una loro violazione causa quella che si chiama una
-  \textit{segment violation}, e la relativa emissione del segnale
-  \const{SIGSEGV}.} da applicare al segmento di memoria e deve essere
+  questi segmenti il kernel mantiene nella \itindex{page~table}\textit{page
+    table} la mappatura sulle pagine di memoria reale, ed le modalità di
+  accesso (lettura, esecuzione, scrittura); una loro violazione causa quella
+  che si chiama una \textit{segment violation}, e la relativa emissione del
+  segnale \const{SIGSEGV}.} da applicare al segmento di memoria e deve essere
 specificato come maschera binaria ottenuta dall'OR di uno o più dei valori
 riportati in tab.~\ref{tab:file_mmap_flag}; il valore specificato deve essere
 compatibile con la modalità di accesso con cui si è aperto il file.
 
-L'argomento \param{flags} specifica infine qual'è il tipo di oggetto mappato,
+L'argomento \param{flags} specifica infine qual è il tipo di oggetto mappato,
 le opzioni relative alle modalità con cui è effettuata la mappatura e alle
 modalità con cui le modifiche alla memoria mappata vengono condivise o
 mantenute private al processo che le ha effettuate. Deve essere specificato
@@ -1111,15 +1135,15 @@ tab.~\ref{tab:file_mmap_flag}.
                              visibili agli altri processi che mappano lo stesso
                              file.\footnotemark Il file su disco però non sarà
                              aggiornato fino alla chiamata di \func{msync} o
-                             \func{unmap}), e solo allora le modifiche saranno
+                             \func{munmap}), e solo allora le modifiche saranno
                              visibili per l'I/O convenzionale. Incompatibile
                              con \const{MAP\_PRIVATE}. \\ 
     \const{MAP\_PRIVATE}   & I cambiamenti sulla memoria mappata non vengono
                              riportati sul file. Ne viene fatta una copia
                              privata cui solo il processo chiamante ha
                              accesso.  Le modifiche sono mantenute attraverso
-                             il meccanismo del 
-                             \textit{copy on write}\index{copy on write} e
+                             il meccanismo del \textit{copy on
+                               write}\itindex{copy~on~write} e 
                              salvate su swap in caso di necessità. Non è
                              specificato se i cambiamenti sul file originale
                              vengano riportati sulla regione
@@ -1130,15 +1154,15 @@ tab.~\ref{tab:file_mmap_flag}.
                              dovevano fallire con \errcode{ETXTBSY}).\\
     \const{MAP\_EXECUTABLE}& Ignorato. \\
     \const{MAP\_NORESERVE} & Si usa con \const{MAP\_PRIVATE}. Non riserva
-                             delle pagine di swap ad uso del meccanismo di
-                             \textit{copy on write}\index{copy on write}
+                             delle pagine di swap ad uso del meccanismo del
+                             \textit{copy on write}\itindex{copy~on~write}
                              per mantenere le
                              modifiche fatte alla regione mappata, in
                              questo caso dopo una scrittura, se non c'è più
                              memoria disponibile, si ha l'emissione di
                              un \const{SIGSEGV}. \\
     \const{MAP\_LOCKED}    & Se impostato impedisce lo swapping delle pagine
-                             mappate. \\
+                             mappate.\\
     \const{MAP\_GROWSDOWN} & Usato per gli stack. Indica 
                              che la mappatura deve essere effettuata con gli
                              indirizzi crescenti verso il basso.\\
@@ -1146,35 +1170,36 @@ tab.~\ref{tab:file_mmap_flag}.
                              argomenti \param{fd} e \param{offset} sono
                              ignorati.\footnotemark\\
     \const{MAP\_ANON}      & Sinonimo di \const{MAP\_ANONYMOUS}, deprecato.\\
-    \const{MAP\_FILE}      & Valore di compatibilità, deprecato.\\
+    \const{MAP\_FILE}      & Valore di compatibilità, ignorato.\\
+    \const{MAP\_32BIT}     & Esegue la mappatura sui primi 2GiB dello spazio
+                             degli indirizzi, viene supportato solo sulle
+                             piattaforme \texttt{x86-64} per compatibilità con
+                             le applicazioni a 32 bit. Viene ignorato se si è
+                             richiesto \const{MAP\_FIXED}.\\
+    \const{MAP\_POPULATE}  & Esegue il \itindex{prefaulting}
+                             \textit{prefaulting} delle pagine di memoria
+                             necessarie alla mappatura. \\
+    \const{MAP\_NONBLOCK}  & Esegue un \textit{prefaulting} più limitato che
+                             non causa I/O.\footnotemark \\
+%     \const{MAP\_DONTEXPAND}& Non consente una successiva espansione dell'area
+%                              mappata con \func{mremap}, proposto ma pare non
+%                              implementato.\\
     \hline
   \end{tabular}
   \caption{Valori possibili dell'argomento \param{flag} di \func{mmap}.}
   \label{tab:file_mmap_flag}
 \end{table}
 
-\footnotetext{Dato che tutti faranno riferimento alle stesse pagine di
-  memoria.}  
-\footnotetext{L'uso di questo flag con \const{MAP\_SHARED} è
-  stato implementato in Linux a partire dai kernel della serie 2.4.x.}
 
 Gli effetti dell'accesso ad una zona di memoria mappata su file possono essere
 piuttosto complessi, essi si possono comprendere solo tenendo presente che
 tutto quanto è comunque basato sul basato sul meccanismo della memoria
-virtuale.\index{memoria virtuale} Questo comporta allora una serie di
+virtuale.\index{memoria~virtuale} Questo comporta allora una serie di
 conseguenze. La più ovvia è che se si cerca di scrivere su una zona mappata in
 sola lettura si avrà l'emissione di un segnale di violazione di accesso
 (\const{SIGSEGV}), dato che i permessi sul segmento di memoria relativo non
 consentono questo tipo di accesso.
 
-\begin{figure}[!htb]
-  \centering
-  \includegraphics[width=10cm]{img/mmap_boundary}
-  \caption{Schema della mappatura in memoria di una sezione di file di
-    dimensioni non corrispondenti al bordo di una pagina.}
-  \label{fig:file_mmap_boundary}
-\end{figure}
-
 È invece assai diversa la questione relativa agli accessi al di fuori della
 regione di cui si è richiesta la mappatura. A prima vista infatti si potrebbe
 ritenere che anch'essi debbano generare un segnale di violazione di accesso;
@@ -1182,11 +1207,30 @@ questo per
 paginazione\index{paginazione}, la mappatura in memoria non può che essere
 eseguita su un segmento di dimensioni rigorosamente multiple di quelle di una
 pagina, ed in generale queste potranno non corrispondere alle dimensioni
-effettive del file o della sezione che si vuole mappare. Il caso più comune è
-quello illustrato in fig.~\ref{fig:file_mmap_boundary}, in cui la sezione di
-file non rientra nei confini di una pagina: in tal caso verrà il file sarà
-mappato su un segmento di memoria che si estende fino al bordo della pagina
-successiva.
+effettive del file o della sezione che si vuole mappare. 
+
+\footnotetext[20]{Dato che tutti faranno riferimento alle stesse pagine di
+  memoria.}  
+\footnotetext[21]{L'uso di questo flag con \const{MAP\_SHARED} è
+  stato implementato in Linux a partire dai kernel della serie 2.4.x.}
+
+\footnotetext{questo flag ed il precedente \const{MAP\_POPULATE} sono stati
+  introdotti nel kernel 2.5.46 insieme alla mappatura non lineare di cui
+  parleremo più avanti.}
+
+\begin{figure}[!htb] 
+  \centering
+  \includegraphics[width=12cm]{img/mmap_boundary}
+  \caption{Schema della mappatura in memoria di una sezione di file di
+    dimensioni non corrispondenti al bordo di una pagina.}
+  \label{fig:file_mmap_boundary}
+\end{figure}
+
+
+Il caso più comune è quello illustrato in fig.~\ref{fig:file_mmap_boundary},
+in cui la sezione di file non rientra nei confini di una pagina: in tal caso
+verrà il file sarà mappato su un segmento di memoria che si estende fino al
+bordo della pagina successiva.
 
 In questo caso è possibile accedere a quella zona di memoria che eccede le
 dimensioni specificate da \param{lenght}, senza ottenere un \const{SIGSEGV}
@@ -1200,14 +1244,6 @@ file mappato sono pi
 file è stato troncato, dopo che è stato mappato, ad una dimensione inferiore a
 quella della mappatura in memoria.
 
-\begin{figure}[htb]
-  \centering
-  \includegraphics[width=10cm]{img/mmap_exceed}
-  \caption{Schema della mappatura in memoria di file di dimensioni inferiori
-    alla lunghezza richiesta.}
-  \label{fig:file_mmap_exceed}
-\end{figure}
-
 In questa situazione, per la sezione di pagina parzialmente coperta dal
 contenuto del file, vale esattamente quanto visto in precedenza; invece per la
 parte che eccede, fino alle dimensioni date da \param{length}, l'accesso non
@@ -1225,6 +1261,14 @@ sez.~\ref{sec:file_vfs_work}). Si tenga presente per
 di dispositivi (un esempio è l'interfaccia al ponte PCI-VME del chip Universe)
 che sono utilizzabili solo con questa interfaccia.
 
+\begin{figure}[htb]
+  \centering
+  \includegraphics[width=12cm]{img/mmap_exceed}
+  \caption{Schema della mappatura in memoria di file di dimensioni inferiori
+    alla lunghezza richiesta.}
+  \label{fig:file_mmap_exceed}
+\end{figure}
+
 Dato che passando attraverso una \func{fork} lo spazio di indirizzi viene
 copiato integralmente, i file mappati in memoria verranno ereditati in maniera
 trasparente dal processo figlio, mantenendo gli stessi attributi avuti nel
@@ -1246,12 +1290,12 @@ consentita la scrittura sul file (cio
 o in corrispondenza di una eventuale \func{msync}.
 
 Dato per i file mappati in memoria le operazioni di I/O sono gestite
-direttamente dalla memoria virtuale, occorre essere consapevoli delle
-interazioni che possono esserci con operazioni effettuate con l'interfaccia
-standard dei file di cap.~\ref{cha:file_unix_interface}. Il problema è che una
-volta che si è mappato un file, le operazioni di lettura e scrittura saranno
-eseguite sulla memoria, e riportate su disco in maniera autonoma dal sistema
-della memoria virtuale.
+direttamente dalla \index{memoria~virtuale}memoria virtuale, occorre essere
+consapevoli delle interazioni che possono esserci con operazioni effettuate
+con l'interfaccia standard dei file di cap.~\ref{cha:file_unix_interface}. Il
+problema è che una volta che si è mappato un file, le operazioni di lettura e
+scrittura saranno eseguite sulla memoria, e riportate su disco in maniera
+autonoma dal sistema della memoria virtuale.
 
 Pertanto se si modifica un file con l'interfaccia standard queste modifiche
 potranno essere visibili o meno a seconda del momento in cui la memoria
@@ -1276,8 +1320,9 @@ memoria mappata con il file su disco; il suo prototipo 
   \bodydesc{La funzione restituisce 0 in caso di successo, e -1 in caso di
     errore nel qual caso \var{errno} assumerà uno dei valori:
     \begin{errlist}
-    \item[\errcode{EINVAL}] O \param{start} non è multiplo di \const{PAGESIZE},
-    o si è specificato un valore non valido per \param{flags}.
+    \item[\errcode{EINVAL}] O \param{start} non è multiplo di
+      \const{PAGE\_SIZE}, o si è specificato un valore non valido per
+      \param{flags}.
     \item[\errcode{EFAULT}] L'intervallo specificato non ricade in una zona
       precedentemente mappata.
     \end{errlist}
@@ -1349,6 +1394,133 @@ Alla conclusione del processo, ogni pagina mappata verr
 rilasciata, mentre la chiusura del file descriptor usato per effettuare la
 mappatura in memoria non ha alcun effetto sulla stessa.
 
+Infine Linux supporta alcune operazioni specifiche non disponibili su altri
+kernel unix-like. La prima di queste operazioni è la possibilità di modificare
+un precedente \textit{memory mapping}, ad esempio per espanderlo o
+restringerlo. Questo è realizzato dalla funzione \funcd{mremap}, il cui
+prototipo è:
+\begin{functions}  
+  \headdecl{unistd.h}
+  \headdecl{sys/mman.h} 
+
+  \funcdecl{void * mremap(void *old\_address, size\_t old\_size , size\_t
+    new\_size, unsigned long flags)}
+  
+  Restringe o allarga una mappatura in memoria di un file.
+
+  \bodydesc{La funzione restituisce l'indirizzo alla nuova area di memoria in
+    caso di successo od il valore \const{MAP\_FAILED} (pari a \texttt{(void *)
+      -1}) in caso di errore, nel qual caso \var{errno} assumerà uno dei
+    valori:
+    \begin{errlist}
+    \item[\errcode{EINVAL}] Uno dei puntatori non è validi, in genere si è
+      usato un valore di \param{old\_address} non allineato ad una pagina di
+      memoria.
+    \item[\errcode{EFAULT}] Ci sono degli indirizzi non validi nell'intervallo
+      di memoria specificato dagli argomenti \param{old\_address} e
+      \param{old\_size}, o ci sono altre mappatura di un tipo non
+      corrispondente a quella richiesta.
+    \item[\errcode{ENOMEM}] Non c'è memoria sufficiente oppure l'area di
+      memoria non può essere espansa all'indirizzo virtuale corrente, e non si
+      è specificato \const{MREMAP\_MAYMOVE} nei flag.
+    \item[\errcode{EAGAIN}] Il segmento di memoria scelto è bloccato e non può
+      essere rimappato.
+    \end{errlist}
+  }
+\end{functions}
+
+La funzione richiede come argomenti \param{old\_address} che specifica il
+precedente indirizzo per la mappatura in memoria e \param{old\_size}, che ne
+indica la dimensione, con \param{new\_size} si specifica invece la nuova
+dimensione che si vuole ottenere. Questa funzione usa il meccanismo della
+\index{memoria~virtuale}memoria virtuale per modificare l'associazione fra gli
+indirizzi virtuali del processo e le pagine di memoria, modificando una
+precedente mappatura.
+
+Infine l'argomento \param{flags} è una maschera binaria per i flag che
+controllano il comportamento della funzione. Il solo valore utilizzato è
+\const{MREMAP\_MAYMOVE}\footnote{per poter utilizzare questa costante occorre
+  aver definito \macro{\_GNU\_SOURCE} prima di includere \file{sys/mman.h}.}
+che consente di eseguire l'espansione anche quando non è possibile utilizzare
+il predente indirizzo. Per questo motivo la funzione può restituire un
+indirizzo della nuova zona di memoria, che, se si è usato questo flag, non è
+detto coincida con \param{old\_address}.
+
+La mappatura in memoria di un file viene normalmente eseguita in maniera
+lineare, cioè parti successive di un file vengono mappate linearmente su
+indirizzi successivi in memoria (la prima pagina di un file viene mappata
+sulla prima pagina di memoria e così via). Esistono però delle
+applicazioni\footnote{in particolare la tecnica è usata dai database o dai
+  programmi che realizzano macchine virtuali.} in cui è utile poter mappare
+parti diverse di un file su diverse zone di memoria.
+
+Questo è ovviamente sempre possibile eseguendo più volte la funzione
+\func{mmap} per ciascuna delle diverse aree,\footnote{ed in effetti è quello
+  che veniva fatto prima che fossero introdotte queste estensioni.} ma questo
+approccio ha delle conseguenze molto pesanti in termini di prestazioni. Si
+ricordi infatti che il \textit{memory mapping} funziona facendo ricorso al
+meccanismo della \index{memoria~virtuale} memoria virtuale per trascrivere su
+un file le operazioni effettuate sugli indirizzi di memoria sui cui esso è
+mappato. 
+
+Questo vuol dire che per ciascuna mappatura in memoria deve essere definita
+nella \itindex{page~table} \textit{page table} del processo una nuova area
+della memoria virtuale\footnote{quella che nel gergo del kernel viene chiamata
+  una \textit{virtual memory area} o VMA.} che corrisponda alla mappatura, in
+modo che questa diventi visibile nello spazio degli indirizzi come illustrato
+in fig.~\ref{fig:file_mmap_layout}.
+
+Quando un processo esegue un gran numero di mappature diverse\footnote{si può
+  arrivare anche a centinaia di migliaia.} per realizzare a mano una mappatura
+non-linare si avrà un accrescimento eccessivo della sua \itindex{page~table}
+\textit{page table}, e lo stesso vale per ciascun processo che utilizza questa
+tecnica. In situazioni come questa si possono ottenere peggioramenti notevoli
+delle prestazioni, dato che il kernel dovrà impiegare molte
+risorse\footnote{sia in termini di memoria interna per i dati delle
+  \itindex{page~table} \textit{page table}, che di CPU per il loro
+  aggiornamento.} solo per mantenere i dati di queste mappature.
+
+Per questo motivo con il kernel 2.5.46 è stato introdotto ad opera di Ingo
+Molnar un meccanismo che consente la mappatura non lineare, che è una seconda
+caratteristica specifica di Linux non presente in altri sistemi unix-like.
+Diventa così possibile utilizzare una sola mappatura iniziale\footnote{e
+  quindi una sola \textit{virtual memory area} nella \itindex{page~table}
+  \textit{page table} del processo.} e poi rimappare a piacere all'interno di
+questa i dati del file. Questo viene realizzato tramite una nuova system call,
+\funcd{remap\_file\_pages}, il cui prototipo è:
+\begin{functions}  
+  \headdecl{sys/mman.h} 
+
+  \funcdecl{int remap\_file\_pages(void *start, size\_t size, int prot,
+    ssize\_t pgoff, int flags)}
+  
+  Permette di rimappare non linearmente un precedente \textit{memory mapping}.
+
+  \bodydesc{La funzione restituisce 0 in caso di successo e -1 in caso di
+    errore, nel qual caso \var{errno} assumerà uno dei valori:
+    \begin{errlist}
+    \item[\errcode{EINVAL}] Uno dei puntatori non è validi, in genere si è
+      usato un valore di \param{old\_address} non allineato ad una pagina di
+      memoria.
+    \end{errlist}
+  }
+\end{functions}
+
+
+Insiema al meccanismo per la mappatura non-lineare con sono stati introdotti
+anche due nuovi flag per \func{mmap}: \const{MAP\_POPULATE} e
+\const{MAP\_NONBLOCK}.
+
+
+\itindend{memory~mapping}
+
+
+% i raw device 
+%\subsection{I \textit{raw} device}
+%\label{sec:file_raw_device}
+
+
+
 
 \section{Il file locking}
 \label{sec:file_locking}
@@ -1360,18 +1532,18 @@ diversi. In quell'occasione si 
 in \textit{append mode}, quando più processi scrivono contemporaneamente sullo
 stesso file non è possibile determinare la sequenza in cui essi opereranno.
 
-Questo causa la possibilità di race condition\index{race condition}; in
-generale le situazioni più comuni sono due: l'interazione fra un processo che
-scrive e altri che leggono, in cui questi ultimi possono leggere informazioni
-scritte solo in maniera parziale o incompleta; o quella in cui diversi
-processi scrivono, mescolando in maniera imprevedibile il loro output sul
-file.
+Questo causa la possibilità di una \textit{race condition}
+\itindex{race~condition}; in generale le situazioni più comuni sono due:
+l'interazione fra un processo che scrive e altri che leggono, in cui questi
+ultimi possono leggere informazioni scritte solo in maniera parziale o
+incompleta; o quella in cui diversi processi scrivono, mescolando in maniera
+imprevedibile il loro output sul file.
 
 In tutti questi casi il \textit{file locking} è la tecnica che permette di
-evitare le race condition\index{race condition}, attraverso una serie di
-funzioni che permettono di bloccare l'accesso al file da parte di altri
-processi, così da evitare le sovrapposizioni, e garantire la atomicità delle
-operazioni di scrittura.
+evitare le \textit{race condition}\itindex{race~condition}, attraverso una
+serie di funzioni che permettono di bloccare l'accesso al file da parte di
+altri processi, così da evitare le sovrapposizioni, e garantire la atomicità
+delle operazioni di scrittura.
 
 
 
@@ -1530,13 +1702,13 @@ anche se richiesto attraverso un file descriptor, agisce sempre su un file;
 perciò le informazioni relative agli eventuali \textit{file lock} sono
 mantenute a livello di inode\index{inode},\footnote{in particolare, come
   accennato in fig.~\ref{fig:file_flock_struct}, i \textit{file lock} sono
-  mantenuti un una \textit{linked list}\index{linked list} di strutture
-  \struct{file\_lock}. La lista è referenziata dall'indirizzo di partenza
-  mantenuto dal campo \var{i\_flock} della struttura \struct{inode} (per le
-  definizioni esatte si faccia riferimento al file \file{fs.h} nei sorgenti
-  del kernel).  Un bit del campo \var{fl\_flags} di specifica se si tratta di
-  un lock in semantica BSD (\const{FL\_FLOCK}) o POSIX (\const{FL\_POSIX}).}
-dato che questo è l'unico riferimento in comune che possono avere due processi
+  mantenuti un una \textit{linked~list} di strutture \struct{file\_lock}. La
+  lista è referenziata dall'indirizzo di partenza mantenuto dal campo
+  \var{i\_flock} della struttura \struct{inode} (per le definizioni esatte si
+  faccia riferimento al file \file{fs.h} nei sorgenti del kernel).  Un bit del
+  campo \var{fl\_flags} di specifica se si tratta di un lock in semantica BSD
+  (\const{FL\_FLOCK}) o POSIX (\const{FL\_POSIX}).} \itindex{linked~list} dato
+che questo è l'unico riferimento in comune che possono avere due processi
 diversi che aprono lo stesso file.
 
 \begin{figure}[htb]
@@ -1619,7 +1791,7 @@ essa viene usata solo secondo il prototipo:
     \item[\errcode{EDEADLK}] Si è richiesto un lock su una regione bloccata da
       un altro processo che è a sua volta in attesa dello sblocco di un lock
       mantenuto dal processo corrente; si avrebbe pertanto un
-      \textit{deadlock}\index{deadlock}. Non è garantito che il sistema
+      \textit{deadlock}\itindex{deadlock}. Non è garantito che il sistema
       riconosca sempre questa situazione.
     \item[\errcode{EINTR}] La funzione è stata interrotta da un segnale prima
       di poter acquisire un lock.
@@ -1739,7 +1911,7 @@ stato effettivamente acquisito.
 
 \begin{figure}[htb]
   \centering \includegraphics[width=9cm]{img/file_lock_dead}
-  \caption{Schema di una situazione di \textit{deadlock}\index{deadlock}.}
+  \caption{Schema di una situazione di \textit{deadlock}\itindex{deadlock}.}
   \label{fig:file_flock_dead}
 \end{figure}
 
@@ -1751,11 +1923,11 @@ un lock sulla regione 2 che non pu
 del processo 2; il processo 1 si bloccherà fintanto che il processo 2 non
 rilasci il blocco. Ma cosa accade se il processo 2 nel frattempo tenta a sua
 volta di ottenere un lock sulla regione A? Questa è una tipica situazione che
-porta ad un \textit{deadlock}\index{deadlock}, dato che a quel punto anche il
-processo 2 si bloccherebbe, e niente potrebbe sbloccare l'altro processo. Per
-questo motivo il kernel si incarica di rilevare situazioni di questo tipo, ed
-impedirle restituendo un errore di \errcode{EDEADLK} alla funzione che cerca
-di acquisire un lock che porterebbe ad un \textit{deadlock}.
+porta ad un \textit{deadlock}\itindex{deadlock}, dato che a quel punto anche
+il processo 2 si bloccherebbe, e niente potrebbe sbloccare l'altro processo.
+Per questo motivo il kernel si incarica di rilevare situazioni di questo tipo,
+ed impedirle restituendo un errore di \errcode{EDEADLK} alla funzione che
+cerca di acquisire un lock che porterebbe ad un \textit{deadlock}.
 
 \begin{figure}[!bht]
   \centering \includegraphics[width=13cm]{img/file_posix_lock}
@@ -1782,7 +1954,8 @@ questo caso la titolarit
 voce nella file table, ma con il valore del \acr{pid} del processo.
 
 Quando si richiede un lock il kernel effettua una scansione di tutti i lock
-presenti sul file\footnote{scandisce cioè la linked list delle strutture
+presenti sul file\footnote{scandisce cioè la
+  \itindex{linked~list}\textit{linked list} delle strutture
   \struct{file\_lock}, scartando automaticamente quelle per cui
   \var{fl\_flags} non è \const{FL\_POSIX}, così che le due interfacce restano
   ben separate.}  per verificare se la regione richiesta non si sovrappone ad
@@ -1866,7 +2039,7 @@ POSIX), e la variabile \var{cmd} che specifica la modalit
 lock (bloccante o meno), a seconda dell'opzione \cmd{-b}.
 
 Il programma inizia col controllare (\texttt{\small 11--14}) che venga passato
-un parametro (il file da bloccare), che sia stato scelto (\texttt{\small
+un argomento (il file da bloccare), che sia stato scelto (\texttt{\small
   15--18}) il tipo di lock, dopo di che apre (\texttt{\small 19}) il file,
 uscendo (\texttt{\small 20--23}) in caso di errore. A questo punto il
 comportamento dipende dalla semantica scelta; nel caso sia BSD occorre