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
ad eseguire la mappatura in memoria di un file, è \funcd{mmap}; il suo
prototipo è:
-
\begin{funcproto}{
\fhead{unistd.h}
\fhead{sys/mman.h}
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
+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.
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
+ 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}
\const{MAP\_GROWSDOWN} & Usato per gli \itindex{stack} \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
+ \const{MAP\_HUGETLB} & Esegue la mappatura usando le cosiddette
+ ``\textit{huge pages}'' (dal 2.6.32).\\
+ \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
+ 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 l'emissione di
- un \signal{SIGSEGV}.\\
+ 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\_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 è
+ il meccanismo del \textit{copy on write} e
+ 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}.\\
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,
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
% 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/