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
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
}
{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,
\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}.
}
\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 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.
+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
con gli indirizzi crescenti verso il basso.\\
\const{MAP\_HUGETLB} & Esegue la mappatura usando le cosiddette
``\textit{huge pages}'' (dal 2.6.32).\\
- \const{MAP\_LOCKED} & Se impostato impedisce lo swapping delle pagine
- mappate (dal 2.5.37).\\
+ \const{MAP\_LOCKED} & Se impostato impedisce lo \textit{swapping} delle
+ pagine mappate (dal 2.5.37).\\
\const{MAP\_NONBLOCK} & Esegue un \textit{prefaulting} più limitato che
non causa I/O (dal 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}
+ delle pagine di \textit{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
privata cui solo il processo chiamante ha
accesso. Le modifiche sono mantenute attraverso
il meccanismo del \textit{copy on write} e
- salvate su swap in caso di necessità. Non è
+ salvate su \textit{swap} in caso di necessità. Non è
specificato se i cambiamenti sul file originale
vengano riportati sulla regione
mappata. Incompatibile con \const{MAP\_SHARED}.\\
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.
+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
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