X-Git-Url: https://gapil.gnulinux.it/gitweb/?p=gapil.git;a=blobdiff_plain;f=fileadv.tex;h=a0081db8104795adcfdc0829904498a81ecfee75;hp=0e0c2b3fa6c2027f11e5c698040729e81a355fba;hb=ac81c727c99557158560acfa2f575874b56aa521;hpb=6a27b6ddf1f27d332f1de65b7c4ac0e1293c2174 diff --git a/fileadv.tex b/fileadv.tex index 0e0c2b3..a0081db 100644 --- a/fileadv.tex +++ b/fileadv.tex @@ -831,7 +831,7 @@ cosiddetto \textit{memory-mapped I/O}, che, attraverso il meccanismo della file in una sezione dello spazio di indirizzi del processo. Il meccanismo è illustrato in \figref{fig:file_mmap_layout}; una sezione del file viene riportata direttamente nello spazio degli indirizzi del programma. Tutte le -operazioni su questo zona verranno riportate indietro sul file dal meccanismo +operazioni su questa zona verranno riportate indietro sul file dal meccanismo della memoria virtuale che trasferirà il contenuto di quel segmento sul file invece che nella swap. @@ -872,7 +872,7 @@ in memoria di un file; il suo prototipo \headdecl{unistd.h} \headdecl{sys/mman.h} - \funcdecl{void * mmap(void *start, size\_t length, int prot, int flags, int + \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}. @@ -1008,12 +1008,59 @@ 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 su multipli delle dimensioni di una pagina, -qualora esso sia più corto la parte restante è 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. +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{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 @@ -1026,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