Reindicizzazioni.
[gapil.git] / fileadv.tex
index 38da0ecff3796640fb330035813107e0edb17ce1..caab10082b300693aa1bb850c9ea980f54e6676c 100644 (file)
@@ -29,9 +29,9 @@ controllo più dettagliato delle modalità di I/O.
 In sez.~\ref{sec:file_shared_access} abbiamo preso in esame le modalità in cui
 un sistema unix-like gestisce l'accesso concorrente ai file da parte di
 processi diversi. In quell'occasione si è visto come, con l'eccezione dei file
-aperti in \itindex{append~mode} \textit{append mode}, quando più processi
-scrivono contemporaneamente sullo stesso file non è possibile determinare la
-sequenza in cui essi opereranno.
+aperti 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 una \itindex{race~condition} \textit{race
   condition}; in generale le situazioni più comuni sono due: l'interazione fra
@@ -3850,7 +3850,7 @@ ognuna di esse dovrà essere specificato il tipo di operazione con il campo
 \begin{basedescript}{\desclabelwidth{2.0cm}}
 \item[\const{LIO\_READ}]  si richiede una operazione di lettura.
 \item[\const{LIO\_WRITE}] si richiede una operazione di scrittura.
-\item[\const{LIO\_NOP}] non si effettua nessuna operazione.
+na operazione.
 \end{basedescript}
 dove \const{LIO\_NOP} viene usato quando si ha a che fare con un vettore di
 dimensione fissa, per poter specificare solo alcune operazioni, o quando si
@@ -3907,12 +3907,12 @@ 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}.
+del file attraverso il sistema della memoria virtuale illustrato in
+sez.~\ref{sec:proc_mem_gen} che in maniera analoga a quanto avviene per le
+pagine che vengono salvate e rilette nella \textit{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}.
 
 L'uso del \textit{memory-mapping} comporta una notevole semplificazione delle
 operazioni di I/O, in quanto non sarà più necessario utilizzare dei buffer
@@ -3928,12 +3928,12 @@ 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.
+salvate sullo \textit{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
+scritte sulla \textit{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 di sistema
@@ -3941,9 +3941,8 @@ 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{funcproto}{
-\fhead{unistd.h}
+%\fhead{unistd.h}
 \fhead{sys/mman.h} 
 \fdecl{void * mmap(void * start, size\_t length, int prot, int flags, int
     fd, off\_t offset)}
@@ -3951,8 +3950,8 @@ prototipo è:
 }
 
 {La funzione ritorna il puntatore alla zona di memoria mappata in caso di
-  successo, e \const{MAP\_FAILED} ($-1$) per un errore, nel qual caso
-  \var{errno} assumerà uno dei valori:
+  successo, e \const{MAP\_FAILED} (\texttt{(void *) -1}) per un errore, nel
+  qual caso \var{errno} assumerà uno dei valori:
   \begin{errlist}
     \item[\errcode{EACCES}] o \param{fd} non si riferisce ad un file regolare,
       o si è usato \const{MAP\_PRIVATE} ma \param{fd} non è aperto in lettura,
@@ -3966,13 +3965,19 @@ prototipo è:
       \const{MAP\_ANONYMOUS}.
     \item[\errcode{EINVAL}] i valori di \param{start}, \param{length} o
       \param{offset} non sono validi (o troppo grandi o non allineati sulla
-      dimensione delle pagine).
+      dimensione delle pagine), o \param{lengh} è zero (solo dal 2.6.12)
+      o \param{flags} contiene sia \const{MAP\_PRIVATE} che
+      \const{MAP\_SHARED} o nessuno dei due.
     \item[\errcode{ENFILE}] si è superato il limite del sistema sul numero di
       file aperti (vedi sez.~\ref{sec:sys_resource_limit}).
     \item[\errcode{ENODEV}] il filesystem di \param{fd} non supporta il memory
       mapping.
     \item[\errcode{ENOMEM}] non c'è memoria o si è superato il limite sul
       numero di mappature possibili.
+    \item[\errcode{EOVERFLOW}] su architettura a 32 bit con il supporto per i
+      \textit{large file} (che hanno una dimensione a 64 bit) il numero di
+      pagine usato per \param{lenght} aggiunto a quello usato
+      per \param{offset} eccede i 32 bit (\texttt{unsigned long}).
     \item[\errcode{EPERM}] l'argomento \param{prot} ha richiesto
       \const{PROT\_EXEC}, ma il filesystem di \param{fd} è montato con
       l'opzione \texttt{noexec}.
@@ -3982,14 +3987,14 @@ prototipo è:
 }
 \end{funcproto}
 
-
 La funzione richiede di mappare in memoria la sezione del file \param{fd} a
 partire da \param{offset} per \param{length} byte, preferibilmente
 all'indirizzo \param{start}. Il valore \param{start} viene normalmente
-considerato come un suggerimento, ma l'uso di un valore diverso da \val{NULL},
-in cui di rimette completamente al kernel la scelta dell'indirizzo, viene
-sconsigliato per ragioni di portabilità. Il valore di \param{offset} deve
-essere un multiplo della dimensione di una pagina di memoria.
+considerato come un suggerimento, ma l'uso di un qualunque valore diverso da
+\val{NULL}, in cui si rimette completamente al kernel la scelta
+dell'indirizzo, viene sconsigliato per ragioni di portabilità. Il valore
+di \param{offset} deve essere un multiplo della dimensione di una pagina di
+memoria.
 
 \begin{table}[htb]
   \centering
@@ -4012,25 +4017,18 @@ essere un multiplo della dimensione di una pagina di memoria.
 
 Il valore dell'argomento \param{prot} indica la protezione\footnote{come
   accennato in sez.~\ref{sec:proc_memory} 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 \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 una \itindex{segment~violation}
-  \textit{segment violation}, e la relativa emissione del segnale
-  \signal{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_prot}; 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,
-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
-come maschera binaria ottenuta dall'OR di uno o più dei valori riportati in
-tab.~\ref{tab:file_mmap_flag}.
-
-\begin{table}[htb]
+  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 una \textit{segment violation}, e la relativa
+  emissione del segnale \signal{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_prot}; il valore specificato
+deve essere compatibile con la modalità di accesso con cui si è aperto il
+file.
+
+\begin{table}[!htb]
   \centering
   \footnotesize
   \begin{tabular}[c]{|l|p{11cm}|}
@@ -4042,13 +4040,15 @@ tab.~\ref{tab:file_mmap_flag}.
                              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} (dal 2.4.20).\\
+                             richiesto \const{MAP\_FIXED} (dal kernel 2.4.20).\\
     \const{MAP\_ANON}      & Sinonimo di \const{MAP\_ANONYMOUS}, deprecato.\\
     \const{MAP\_ANONYMOUS} & La mappatura non è associata a nessun file. Gli
                              argomenti \param{fd} e \param{offset} sono
-                             ignorati.\\
+                             ignorati. L'uso di questo flag con
+                             \const{MAP\_SHARED} è stato implementato in Linux
+                             a partire dai kernel della serie 2.4.x.\\
     \const{MAP\_DENYWRITE} & In Linux viene ignorato per evitare
-                             \textit{DoS} \itindex{Denial~of~Service~(DoS)}
+                             \textit{DoS}
                              (veniva usato per segnalare che tentativi di
                              scrittura sul file dovevano fallire con
                              \errcode{ETXTBSY}).\\ 
@@ -4059,45 +4059,54 @@ tab.~\ref{tab:file_mmap_flag}.
                              \func{mmap} fallisce. Se si imposta questo flag il
                              valore di \param{start} deve essere allineato
                              alle dimensioni di una pagina.\\
-    \const{MAP\_GROWSDOWN} & Usato per gli \itindex{stack} \textit{stack}. 
+    \const{MAP\_GROWSDOWN} & Usato per gli \textit{stack}. 
                              Indica che la mappatura deve essere effettuata 
                              con gli indirizzi crescenti verso il basso.\\
-    \const{MAP\_HUGETLB}   & da trattare (dal 2.6.32).\\
-    \const{MAP\_LOCKED}    & Se impostato impedisce lo swapping delle pagine
-                             mappate (dal 2.5.37).\\
+    \const{MAP\_HUGETLB}   & Esegue la mappatura usando le cosiddette
+                             ``\textit{huge pages}'' (dal kernel 2.6.32).\\
+    \const{MAP\_LOCKED}    & Se impostato impedisce lo \textit{swapping} delle
+                             pagine mappate (dal kernel 2.5.37).\\
     \const{MAP\_NONBLOCK}  & Esegue un \textit{prefaulting} più limitato che
-                             non causa I/O (dal 2.5.46).\\
+                             non causa I/O (dal kernel 2.5.46).\\
     \const{MAP\_NORESERVE} & Si usa con \const{MAP\_PRIVATE}. Non riserva
-                             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 \signal{SIGSEGV}.\\
+                             delle pagine di \textit{swap} ad uso del meccanismo
+                             del \textit{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 \signal{SIGSEGV}.\\
+    \const{MAP\_POPULATE}  & Esegue il \textit{prefaulting} delle pagine di
+                             memoria necessarie alla mappatura (dal kernel
+                             2.5.46).\\ 
     \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} \itindex{copy~on~write} e 
-                             salvate su swap in caso di necessità. Non è
-                             specificato se i cambiamenti sul file originale
-                             vengano riportati sulla regione
-                             mappata. Incompatibile con \const{MAP\_SHARED}.\\
-    \const{MAP\_POPULATE}  & Esegue il \itindex{prefaulting}
-                             \textit{prefaulting} delle pagine di memoria
-                             necessarie alla mappatura (dal 2.5.46).\\
+                             accesso.  Incompatibile con \const{MAP\_SHARED}.\\
     \const{MAP\_SHARED}    & I cambiamenti sulla memoria mappata vengono
                              riportati sul file e saranno immediatamente
                              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{munmap}), e solo allora le modifiche saranno
-                             visibili per l'I/O convenzionale. Incompatibile
+                             file. Incompatibile
                              con \const{MAP\_PRIVATE}.\\ 
-    \const{MAP\_STACK}     & da trattare (dal 2.6.27).\\
-    \const{MAP\_UNINITIALIZED}& da trattare (dal 2.6.33).\\
+    \const{MAP\_STACK}     & Al momento è ignorato, è stato fornito (dal kernel
+                             2.6.27) a supporto della implementazione dei
+                             thread nelle \acr{glibc}, per allocare memoria in
+                             uno spazio utilizzabile come \textit{stack} per le
+                             architetture hardware che richiedono un
+                             trattamento speciale di quest'ultimo.\\
+    \const{MAP\_UNINITIALIZED}& Specifico per i sistemi embedded ed
+                             utilizzabile dal kernel 2.6.33 solo se è stata
+                             abilitata in fase di compilazione dello stesso
+                             l'opzione
+                             \texttt{CONFIG\_MMAP\_ALLOW\_UNINITIALIZED}. Se
+                             usato le pagine di memoria usate nella mappatura
+                             anonima non vengono cancellate; questo migliora
+                             le prestazioni sui sistemi con risorse minime, ma
+                             comporta la possibilità di rileggere i dati di
+                             altri processi che han chiuso una mappatura, per
+                             cui viene usato solo quando (come si suppone sia
+                             per i sistemi embedded) si ha il completo
+                             controllo dell'uso della memoria da parte degli
+                             utenti.\\ 
 %     \const{MAP\_DONTEXPAND}& Non consente una successiva espansione dell'area
 %                              mappata con \func{mremap}, proposto ma pare non
 %                              implementato.\\
@@ -4107,31 +4116,59 @@ tab.~\ref{tab:file_mmap_flag}.
   \label{tab:file_mmap_flag}
 \end{table}
 
-\footnotetext{l'uso di questo flag con \const{MAP\_SHARED} è stato
-  implementato in Linux a partire dai kernel della serie 2.4.x; esso consente
-  di creare segmenti di memoria condivisa e torneremo sul suo utilizzo in
-  sez.~\ref{sec:ipc_mmap_anonymous}.}
-
 % TODO trattare MAP_HUGETLB introdotto con il kernel 2.6.32, e modifiche
 % introdotte con il 3.8 per le dimensioni variabili delle huge pages
 
+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
+come maschera binaria ottenuta dall'OR di uno o più dei valori riportati in
+tab.~\ref{tab:file_mmap_flag}. Fra questi comunque deve sempre essere
+specificato o \const{MAP\_PRIVATE} o \const{MAP\_SHARED} per indicare la
+modalità con cui viene effettuata la mappatura.
+
+Esistono infatti due modalità alternative di eseguire la mappatura di un file;
+la più comune è \const{MAP\_SHARED} in cui la memoria è condivisa e le
+modifiche effettuate su di essa sono visibili a tutti i processi che hanno
+mappato lo stesso file. In questo caso le modifiche vengono anche riportate su
+disco, anche se questo può non essere immediato a causa della bufferizzazione:
+si potrà essere sicuri dell'aggiornamento solo in seguito alla chiamata di
+\func{msync} o \func{munmap}, e solo allora le modifiche saranno visibili sul
+file con l'I/O convenzionale.
+
+Con \const{MAP\_PRIVATE} invece viene creata una copia privata del file,
+questo non viene mai modificato e solo il processo chiamante ha accesso alla
+mappatura. Le modifiche eseguite dal processo sulla mappatura vengono
+effettuate utilizzando il meccanismo del \textit{copy on write}, mentenute in
+memoria e salvate su \textit{swap} in caso di necessità.  Non è specificato se
+i cambiamenti sul file originale vengano riportati sulla regione mappata.
+
+Gli altri valori di \func{flag} modificano le caratteristiche della
+mappatura. Fra questi il più rilevante è probabilmente \const{MAP\_ANONYMOUS}
+che consente di creare segmenti di memoria condivisa fra processi diversi
+senza appoggiarsi a nessun file (torneremo sul suo utilizzo in
+sez.~\ref{sec:ipc_mmap_anonymous}). In tal caso gli argomenti \param{fd}
+e \param{offset} vangono ignorati, anche se alcune implementazioni richiedono
+che invece \param{fd} sia $-1$, convenzione che è opportuno seguire se si ha a
+cuore la portabilità dei programmi.
+
 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 meccanismo della \index{memoria~virtuale}
-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 (\signal{SIGSEGV}),
-dato che i permessi sul segmento di memoria relativo non consentono questo
-tipo di accesso.
+tutto quanto è comunque basato sul meccanismo della 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 (\signal{SIGSEGV}), dato che i permessi sul segmento
+di memoria relativo non consentono questo tipo di accesso.
 
 È 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;
 questo però non tiene conto del fatto che, essendo basata sul meccanismo della
-\index{paginazione} 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.
+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.
 
 \begin{figure}[!htb] 
   \centering
@@ -4143,26 +4180,23 @@ 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.
-
-In questo caso è possibile accedere a quella zona di memoria che eccede le
-dimensioni specificate da \param{length}, senza ottenere un \signal{SIGSEGV}
-poiché essa è presente nello spazio di indirizzi del processo, anche se non è
-mappata sul file. Il comportamento del sistema è quello di restituire un
-valore nullo per quanto viene letto, e di non riportare su file quanto viene
-scritto.
+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{length}, senza
+ottenere un \signal{SIGSEGV} poiché essa è presente nello spazio di indirizzi
+del processo, anche se non è mappata sul file. Il comportamento del sistema è
+quello di restituire un valore nullo per quanto viene letto, e di non
+riportare su file quanto viene scritto.
 
 Un caso più complesso è quello che si viene a creare quando le dimensioni del
 file mappato sono più corte delle dimensioni della mappatura, oppure quando il
 file è stato troncato, dopo che è stato mappato, ad una dimensione inferiore a
-quella della mappatura in memoria.
-
-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
-sarà più possibile, ma il segnale emesso non sarà \signal{SIGSEGV}, ma
-\signal{SIGBUS}, come illustrato in fig.~\ref{fig:file_mmap_exceed}.
+quella della mappatura in memoria.  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 sarà più possibile, ma il segnale emesso non
+sarà \signal{SIGSEGV}, ma \signal{SIGBUS}, come illustrato in
+fig.~\ref{fig:file_mmap_exceed}.
 
 Non tutti i file possono venire mappati in memoria, dato che, come illustrato
 in fig.~\ref{fig:file_mmap_layout}, la mappatura introduce una corrispondenza
@@ -4205,50 +4239,54 @@ consentita la scrittura sul file (cioè per un file mappato con
 o in corrispondenza di una eventuale \func{msync}.
 
 Dato per i file mappati in memoria le operazioni di I/O sono gestite
-direttamente dalla \index{memoria~virtuale} memoria virtuale, occorre essere
-consapevoli delle interazioni che possono esserci con operazioni effettuate
-con l'interfaccia dei file di sez.~\ref{sec: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
+direttamente dalla memoria virtuale, occorre essere consapevoli delle
+interazioni che possono esserci con operazioni effettuate con l'interfaccia
+dei file ordinaria illustrata in sez.~\ref{sec: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 ordinaria queste modifiche
 potranno essere visibili o meno a seconda del momento in cui la memoria
 virtuale trasporterà dal disco in memoria quella sezione del file, perciò è
 del tutto imprevedibile il risultato della modifica di un file nei confronti
 del contenuto della memoria su cui è mappato.
 
-Per questo, è sempre sconsigliabile eseguire scritture su file attraverso
-l'interfaccia standard quando lo si è mappato in memoria, è invece possibile
-usare l'interfaccia standard per leggere un file mappato in memoria, purché si
-abbia una certa cura; infatti l'interfaccia dell'I/O mappato in memoria mette
-a disposizione la funzione \funcd{msync} per sincronizzare il contenuto della
-memoria mappata con il file su disco; il suo prototipo è:
-\begin{functions}  
-  \headdecl{unistd.h}
-  \headdecl{sys/mman.h} 
+Per questo è sempre sconsigliabile eseguire scritture su un file attraverso
+l'interfaccia ordinaria quando lo si è mappato in memoria, è invece possibile
+usare l'interfaccia ordinaria per leggere un file mappato in memoria, purché
+si abbia una certa cura; infatti l'interfaccia dell'I/O mappato in memoria
+mette a disposizione la funzione \funcd{msync} per sincronizzare il contenuto
+della memoria mappata con il file su disco; il suo prototipo è:
 
-  \funcdecl{int msync(const void *start, size\_t length, int flags)}
-  
-  Sincronizza i contenuti di una sezione di un file mappato in memoria.
-  
-  \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}
+\begin{funcproto}{
+%\fhead{unistd.h}
+\fhead{sys/mman.h}
+\fdecl{int msync(const void *start, size\_t length, int flags)}
+\fdesc{Sincronizza i contenuti di una sezione di un file mappato in memoria.} 
+}
+
+{La funzione ritorna $0$ in caso di successo e $-1$ per un errore, nel qual
+  caso \var{errno} assumerà uno dei valori: 
+  \begin{errlist}
+    \item[\errcode{EBUSY}] si è indicato \const{MS\_INVALIDATE} ma
+      nell'intervallo di memoria specificato è presente un \textit{memory lock}.
+    \item[\errcode{EFAULT}] l'intervallo indicato, o parte di esso, non
+      risulta mappato (prima del kernel 2.4.19).
     \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}
-  }
-\end{functions}
+    \item[\errcode{ENOMEM}] l'intervallo indicato, o parte di esso, non
+      risulta mappato (dal kernel 2.4.19).
+  \end{errlist}
+}
+\end{funcproto}
 
 La funzione esegue la sincronizzazione di quanto scritto nella sezione di
 memoria indicata da \param{start} e \param{offset}, scrivendo le modifiche sul
 file (qualora questo non sia già stato fatto).  Provvede anche ad aggiornare i
 relativi tempi di modifica. In questo modo si è sicuri che dopo l'esecuzione
-di \func{msync} le funzioni dell'interfaccia standard troveranno un contenuto
+di \func{msync} le funzioni dell'interfaccia ordinaria troveranno un contenuto
 del file aggiornato.
 
 
@@ -4279,28 +4317,28 @@ dei valori riportati in tab.~\ref{tab:file_mmap_msync}, di questi però
 infatti la funzione si limita ad inoltrare la richiesta di sincronizzazione al
 meccanismo della memoria virtuale, ritornando subito, mentre con il secondo
 attende che la sincronizzazione sia stata effettivamente eseguita. Il terzo
-flag fa sì che vengano invalidate, per tutte le mappature dello stesso file,
+valore fa sì che vengano invalidate, per tutte le mappature dello stesso file,
 le pagine di cui si è richiesta la sincronizzazione, così che esse possano
 essere immediatamente aggiornate con i nuovi valori.
 
 Una volta che si sono completate le operazioni di I/O si può eliminare la
 mappatura della memoria usando la funzione \funcd{munmap}, il suo prototipo è:
-\begin{functions}  
-  \headdecl{unistd.h}
-  \headdecl{sys/mman.h} 
 
-  \funcdecl{int munmap(void *start, size\_t length)}
-  
-  Rilascia la mappatura sulla sezione di memoria specificata.
+\begin{funcproto}{
+%\fhead{unistd.h}
+\fhead{sys/mman.h}
+\fdecl{int munmap(void *start, size\_t length)}
+\fdesc{Rilascia la mappatura sulla sezione di memoria specificata.} 
+}
 
-  \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}
+{La funzione ritorna $0$ in caso di successo e $-1$ per un errore, nel qual
+  caso \var{errno} assumerà uno dei valori: 
+  \begin{errlist}
     \item[\errcode{EINVAL}] l'intervallo specificato non ricade in una zona
       precedentemente mappata.
-    \end{errlist}
-  }
-\end{functions}
+  \end{errlist}
+}
+\end{funcproto}
 
 La funzione cancella la mappatura per l'intervallo specificato con
 \param{start} e \param{length}; ogni successivo accesso a tale regione causerà
@@ -4477,38 +4515,39 @@ partire dal quale la sezione di file indicata verrà rimappata. L'argomento
 valori di \func{mmap} (quelli di tab.~\ref{tab:file_mmap_prot}) ma di tutti i
 flag solo \const{MAP\_NONBLOCK} non viene ignorato.
 
+\itindbeg{prefaulting} 
+
 Insieme alla funzione \func{remap\_file\_pages} nel kernel 2.5.46 con sono
 stati introdotti anche due nuovi flag per \func{mmap}: \const{MAP\_POPULATE} e
 \const{MAP\_NONBLOCK}.  Il primo dei due consente di abilitare il meccanismo
-del \itindex{prefaulting} \textit{prefaulting}. Questo viene di nuovo in aiuto
-per migliorare le prestazioni in certe condizioni di utilizzo del
-\textit{memory mapping}. 
+del \textit{prefaulting}. Questo viene di nuovo in aiuto per migliorare le
+prestazioni in certe condizioni di utilizzo del \textit{memory mapping}.
 
 Il problema si pone tutte le volte che si vuole mappare in memoria un file di
-grosse dimensioni. Il comportamento normale del sistema della
-\index{memoria~virtuale} memoria virtuale è quello per cui la regione mappata
-viene aggiunta alla \itindex{page~table} \textit{page table} del processo, ma
-i dati verranno effettivamente utilizzati (si avrà cioè un
-\itindex{page~fault} \textit{page fault} che li trasferisce dal disco alla
-memoria) soltanto in corrispondenza dell'accesso a ciascuna delle pagine
-interessate dal \textit{memory mapping}. 
+grosse dimensioni. Il comportamento normale del sistema della memoria virtuale
+è quello per cui la regione mappata viene aggiunta alla \textit{page table}
+del processo, ma i dati verranno effettivamente utilizzati (si avrà cioè un
+\textit{page fault} che li trasferisce dal disco alla memoria) soltanto in
+corrispondenza dell'accesso a ciascuna delle pagine interessate dal
+\textit{memory mapping}.
 
 Questo vuol dire che il passaggio dei dati dal disco alla memoria avverrà una
 pagina alla volta con un gran numero di \itindex{page~fault} \textit{page
   fault}, chiaramente se si sa in anticipo che il file verrà utilizzato
-immediatamente, è molto più efficiente eseguire un \itindex{prefaulting}
-\textit{prefaulting} in cui tutte le pagine di memoria interessate alla
-mappatura vengono ``\textsl{popolate}'' in una sola volta, questo
-comportamento viene abilitato quando si usa con \func{mmap} il flag
-\const{MAP\_POPULATE}.
+immediatamente, è molto più efficiente eseguire un \textit{prefaulting} in cui
+tutte le pagine di memoria interessate alla mappatura vengono
+``\textsl{popolate}'' in una sola volta, questo comportamento viene abilitato
+quando si usa con \func{mmap} il flag \const{MAP\_POPULATE}.
 
 Dato che l'uso di \const{MAP\_POPULATE} comporta dell'I/O su disco che può
 rallentare l'esecuzione di \func{mmap} è stato introdotto anche un secondo
-flag, \const{MAP\_NONBLOCK}, che esegue un \itindex{prefaulting}
-\textit{prefaulting} più limitato in cui vengono popolate solo le pagine della
-mappatura che già si trovano nella cache del kernel.\footnote{questo può
-  essere utile per il linker dinamico, in particolare quando viene effettuato
-  il \textit{prelink} delle applicazioni.}
+flag, \const{MAP\_NONBLOCK}, che esegue un \textit{prefaulting} più limitato
+in cui vengono popolate solo le pagine della mappatura che già si trovano
+nella cache del kernel.\footnote{questo può essere utile per il linker
+  dinamico, in particolare quando viene effettuato il \textit{prelink} delle
+  applicazioni.}
+
+\itindend{prefaulting}
 
 Per i vantaggi illustrati all'inizio del paragrafo l'interfaccia del
 \textit{memory mapped I/O} viene usata da una grande varietà di programmi,
@@ -5381,11 +5420,10 @@ all'accesso al disco; il suo prototipo è:
 
 La funzione richiede che venga letto in anticipo il contenuto del file
 \param{fd} a partire dalla posizione \param{offset} e per un ammontare di
-\param{count} byte, in modo da portarlo in cache.  La funzione usa la
-\index{memoria~virtuale} memoria virtuale ed il meccanismo della
-\index{paginazione} paginazione per cui la lettura viene eseguita in blocchi
-corrispondenti alle dimensioni delle pagine di memoria, ed i valori di
-\param{offset} e \param{count} vengono arrotondati di conseguenza.
+\param{count} byte, in modo da portarlo in cache.  La funzione usa la memoria
+virtuale ed il meccanismo della paginazione per cui la lettura viene eseguita
+in blocchi corrispondenti alle dimensioni delle pagine di memoria, ed i valori
+di \param{offset} e \param{count} vengono arrotondati di conseguenza.
 
 La funzione estende quello che è un comportamento normale del kernel che
 quando si legge un file, aspettandosi che l'accesso prosegua, esegue sempre
@@ -5640,7 +5678,8 @@ livello di kernel.
 % http://kernelnewbies.org/Linux_2_6_23
 
 % TODO aggiungere FALLOC_FL_ZERO_RANGE e FALLOC_FL_COLLAPSE_RANGE, inseriti
-% nel kenrel 3.15 (sul secondo vedi http://lwn.net/Articles/589260/)
+% nel kernel 3.15 (sul secondo vedi http://lwn.net/Articles/589260/), vedi
+% anche http://lwn.net/Articles/629965/
 
 % TODO non so dove trattarli, ma dal 2.6.39 ci sono i file handle, vedi
 % http://lwn.net/Articles/432757/