Altre info su mmap
[gapil.git] / fileadv.tex
index 352848103526fdfe126feaa641a78bf27dab824d..a0081db8104795adcfdc0829904498a81ecfee75 100644 (file)
@@ -1008,28 +1008,60 @@ come maschera binaria ottenuta dall'OR di uno o pi
 \footnotetext{L'uso di questo flag con \macro{MAP\_SHARED} è
   stato implementato in Linux a partire dai kernel della serie 2.4.x.}
 
-
-Un file viene sempre mappato in memoria su multipli delle dimensioni di una
-pagina, ma non è detto che le sue dimensioni siano allineate ai confini di una
-pagina; in \figref{fig:file_mmap_boundary} sono illustrate le varie
-possibilità. La mappatura alloca comunque un numero di pagine sufficienti a
-contenere tutta la sezione di file richiesta, la memoria che 
-
-è riempita con
-zeri; eventuali scritture in quella zona di memoria non vengono riportate sul
-file. Se le dimensioni del file cambiano (esso viene esteso o troncato), non è
-specificato quale effetto viene a aversi sulle pagine di memoria che
-corrispondono alle regioni aggiunte o tolte. La situazione è illustrata in
-\figref{fig:file_mmap_boundary},
+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. 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 \macro{SIGSEGV}, dato che i permessi sul segmento
+di memoria relativo non consentono questo tipo di accesso.
+
+È invece assai più complessa la questione relativa agli accessi al di fuori
+della regione di cui si è richiesta la mappatura. In generale infatti si è
+portati a ritenere che anch'essi dovrebbero dar luogo all'emissione di un
+segnale di \macro{SIGSEGV}; questo però non tiene conto del fatto che essendo
+basata sul meccanismo della paginazione, una mappatura non può che essere
+eseguita su un segmento di memoria di dimensioni uguali ad un multiplo di
+quelle di una pagina.  In generale dette dimensioni potranno non corrispondere
+alle dimensioni effettive del file o della sezione che si vuole mappare. Il
+caso più comune che si presenta è quello illustrato in
+\figref{fig:file_mmap_boundary}, in cui la sezione di file non rientra nei
+confini di una pagina: in tal caso verrà mappato su un segmento di memoria che
+si estende fino al bordo della pagina successiva.
 
 \begin{figure}[htb]
   \centering
   \includegraphics[width=10cm]{img/mmap_boundary}
-  \caption{Effetti delle interazioni fra mappatura in memoria e dimensioni
-  effettive del file.}
+  \caption{Schema della mappatura in memoria di una sezione di file di
+    dimensioni non corripondenti al bordo di una pagina.}
   \label{fig:file_mmap_boundary}
 \end{figure}
 
+Si ha così una situazione in cui sarà possibile accedere, senza ottenere un
+\macro{SIGSEGV}, a quella zona di memoria che eccede le dimensioni specificate
+da \param{lenght}, dato che essa è presente nello spazio di indirizzi del
+processo, anche se non è mappata sul file. In questo caso quello che succede è
+che gli accessi in lettura restituiranno dei valori nulli, mentre gli accessi
+in scrittura non avranno alcun effetto e non saranno scritti sul file.
+
+Un caso più complesso è quello illustrato in \figref{fig:file_mmap_exceed},
+che avviene quando le dimensioni del file sono più corte di quelle su cui si
+vuole effettuare la mappatura, oppure quando il file è stato troncato da un
+altro processo ad una dimensione inferiore.
+
+\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 tal caso per la parte del file esistente vale esattamente quanto detto in
+precedenza, mentre per la parte di memoria che eccede il bordo della pagina,
+ma inferiore alle dimensioni richiete con \param{length}, si avrà il segnale
+\macro{SIGBUS}.
+
 Si tenga presente che non tutti i file possono venire mappati in memoria, la
 mappatura infatti introduce una corrispondenza biunivoca fra una sezione di un
 file ed una sezione di memoria, pertanto si può parlare tanto di file mappato
@@ -1041,15 +1073,14 @@ ricordi quanto esposto in \secref{sec:file_vfs_work}), ma esistono anche casi
 (un esempio è l'interfaccia ponte PCI-VME del chip Universe) di dispositivi
 che sono utilizzabili praticamente solo con questa interfaccia.
 
-Dato che, passando attraverso una \func{fork}, lo spazio di indirizzi viene
-sempre copiato, i file mappati in memoria verranno ereditati in maniera
-trasparente dal processo figlio, mantenendo gli stessi attributi avuti nel
-padre; così se si è usato \macro{MAP\_SHARED} padre e figlio accederanno allo
-stesso file in maniera condivisa, mentre se si è usato \macro{MAP\_PRIVATE}
-ciascuno di essi manterrà una sua versione privata indipendente. Non c'è
-invece nessun passaggio attraverso una \func{exec}, dato che quest'ultima
-sostituisce tutto lo spazio degli indirizzi di un processo con quello di un
-nuovo programma.
+Dato che passando attraverso una \func{fork} lo spazio di indirizzi viene
+copiato, i file mappati in memoria verranno ereditati in maniera trasparente
+dal processo figlio, mantenendo gli stessi attributi avuti nel padre; così se
+si è usato \macro{MAP\_SHARED} padre e figlio accederanno allo stesso file in
+maniera condivisa, mentre se si è usato \macro{MAP\_PRIVATE} ciascuno di essi
+manterrà una sua versione privata indipendente. Non c'è invece nessun
+passaggio attraverso una \func{exec}, dato che quest'ultima sostituisce tutto
+lo spazio degli indirizzi di un processo con quello di un nuovo programma.
 
 Quando si effettua la mappatura di un file vengono pure modificati i tempi ad
 esso associati (si ricordi quanto esposto in \secref{sec:file_file_times}). Il