X-Git-Url: https://gapil.gnulinux.it/gitweb/?p=gapil.git;a=blobdiff_plain;f=fileadv.tex;h=c91f34e72f1606437145dbab7c4b5833cc551311;hp=28cf2bf32512d5177bb88b216ceffdb4fdf16c39;hb=9a6d19e384fe9b1afbe4d9124ac34eaf7aa57562;hpb=5f4b8bbb1f57385f442b83d48fc8fbdc12ab30a3 diff --git a/fileadv.tex b/fileadv.tex index 28cf2bf..c91f34e 100644 --- a/fileadv.tex +++ b/fileadv.tex @@ -1,6 +1,6 @@ %% fileadv.tex %% -%% Copyright (C) 2000-2004 Simone Piccardi. Permission is granted to +%% Copyright (C) 2000-2005 Simone Piccardi. Permission is granted to %% copy, distribute and/or modify this document under the terms of the GNU Free %% Documentation License, Version 1.1 or any later version published by the %% Free Software Foundation; with the Invariant Sections being "Un preambolo", @@ -136,16 +136,16 @@ opportune macro di preprocessore: \headdecl{sys/time.h} \headdecl{sys/types.h} \headdecl{unistd.h} - \funcdecl{FD\_ZERO(fd\_set *set)} + \funcdecl{void \macro{FD\_ZERO}(fd\_set *set)} Inizializza l'insieme (vuoto). - \funcdecl{FD\_SET(int fd, fd\_set *set)} + \funcdecl{void \macro{FD\_SET}(int fd, fd\_set *set)} Inserisce il file descriptor \param{fd} nell'insieme. - \funcdecl{FD\_CLR(int fd, fd\_set *set)} + \funcdecl{void \macro{FD\_CLR}(int fd, fd\_set *set)} Rimuove il file descriptor \param{fd} nell'insieme. - \funcdecl{FD\_ISSET(int fd, fd\_set *set)} + \funcdecl{int \macro{FD\_ISSET}(int fd, fd\_set *set)} Controlla se il file descriptor \param{fd} è nell'insieme. \end{functions} @@ -173,7 +173,7 @@ sez.~\ref{sec:TCP_urgent_data}). Dato che in genere non si tengono mai sotto controllo fino a \const{FD\_SETSIZE} file contemporaneamente la funzione richiede di -specificare qual'è il numero massimo dei file descriptor indicati nei tre +specificare qual è il numero massimo dei file descriptor indicati nei tre insiemi precedenti. Questo viene fatto per efficienza, per evitare di passare e far controllare al kernel una quantità di memoria superiore a quella necessaria. Questo limite viene indicato tramite l'argomento \param{n}, che @@ -193,7 +193,7 @@ La funzione restituisce il numero di file descriptor pronti,\footnote{questo funzione è recente, ed esistono ancora alcune versioni di Unix che non si comportano in questo modo.} e ciascun insieme viene sovrascritto per indicare quali sono i file descriptor pronti per le operazioni ad esso -relative, in modo da poterli controllare con \const{FD\_ISSET}. Se invece si +relative, in modo da poterli controllare con \macro{FD\_ISSET}. Se invece si ha un timeout viene restituito un valore nullo e gli insiemi non vengono modificati. In caso di errore la funzione restituisce -1, ed i valori dei tre insiemi sono indefiniti e non si può fare nessun affidamento sul loro @@ -420,8 +420,8 @@ distinzione ha senso solo per i dati \textit{out-of-band} dei socket (vedi sez.~\ref{sec:TCP_urgent_data}), ma su questo e su come \func{poll} reagisce alle varie condizioni dei socket torneremo in sez.~\ref{sec:TCP_serv_poll}, dove vedremo anche un esempio del suo utilizzo. Si tenga conto comunque che le -costanti relative ai diversi tipi di dati (come \macro{POLLRDNORM} e -\macro{POLLRDBAND}) sono utilizzabili soltanto qualora si sia definita la +costanti relative ai diversi tipi di dati (come \const{POLLRDNORM} e +\const{POLLRDBAND}) sono utilizzabili soltanto qualora si sia definita la macro \macro{\_XOPEN\_SOURCE}.\footnote{e ci si ricordi di farlo sempre in testa al file, definirla soltanto prima di includere \file{sys/poll.h} non è sufficiente.} @@ -495,7 +495,7 @@ percentuale) sono diventati attivi. Tuttavia con l'implementazione classica dei segnali questa modalità di I/O presenta notevoli problemi, dato che non è possibile determinare, quando i -file descriptor sono più di uno, qual'è quello responsabile dell'emissione del +file descriptor sono più di uno, qual è quello responsabile dell'emissione del segnale. Inoltre dato che i segnali normali non si accodano (si ricordi quanto illustrato in sez.~\ref{sec:sig_notification}), in presenza di più file descriptor attivi contemporaneamente, più segnali emessi nello stesso momento @@ -736,7 +736,7 @@ esaurimento. Oltre alle operazioni di lettura e scrittura l'interfaccia POSIX.1b mette a disposizione un'altra operazione, quella di sincronizzazione dell'I/O, -compiuta dalla funzione \func{aio\_fsync}, che ha lo stesso effetto della +compiuta dalla funzione \funcd{aio\_fsync}, che ha lo stesso effetto della analoga \func{fsync}, ma viene eseguita in maniera asincrona; il suo prototipo è: \begin{prototype}{aio.h} @@ -946,7 +946,7 @@ prototipi sono: \end{errlist} ed inoltre \errval{EISDIR}, \errval{ENOMEM}, \errval{EFAULT} (se non sono stato allocati correttamente i buffer specificati nei campi - \func{iov\_base}), più tutti gli ulteriori errori che potrebbero avere le + \var{iov\_base}), più tutti gli ulteriori errori che potrebbero avere le usuali funzioni di lettura e scrittura eseguite su \param{fd}.} \end{functions} @@ -982,29 +982,34 @@ rispetto a quella classica vista in cap.~\ref{cha:file_unix_interface}, cosiddetto \textit{memory-mapped I/O}, che, attraverso il meccanismo della \textsl{paginazione}\index{paginazione} usato dalla memoria virtuale (vedi sez.~\ref{sec:proc_mem_gen}), permette di \textsl{mappare} il contenuto di un -file in una sezione dello spazio di indirizzi del processo. Il meccanismo è -illustrato in fig.~\ref{fig:file_mmap_layout}, una sezione del file viene -riportata direttamente nello spazio degli indirizzi del programma. Tutte le -operazioni su questa zona verranno riportate indietro sul file dal meccanismo -della memoria virtuale\index{memoria~virtuale} che trasferirà il contenuto di -quel segmento sul file invece che nella swap, per cui si può parlare tanto di -file mappato in memoria, quanto di memoria mappata su file. +file in una sezione dello spazio di indirizzi del processo. + +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}. \begin{figure}[htb] \centering - \includegraphics[width=7.cm]{img/mmap_layout} + \includegraphics[width=14cm]{img/mmap_layout} \caption{Disposizione della memoria di un processo quando si esegue la mappatura in memoria di un file.} \label{fig:file_mmap_layout} \end{figure} -Tutto questo comporta una notevole semplificazione delle operazioni di I/O, in -quanto non sarà più necessario utilizzare dei buffer intermedi su cui -appoggiare i dati da traferire, ma questi potranno essere acceduti -direttamente nella sezione di memoria mappata; inoltre questa interfaccia è -più efficiente delle usuali funzioni di I/O, in quanto permette di caricare in -memoria solo le parti del file che sono effettivamente usate ad un dato -istante. +L'uso del \textit{memory-mappung} comporta una notevole semplificazione delle +operazioni di I/O, in quanto non sarà più necessario utilizzare dei buffer +intermedi su cui appoggiare i dati da traferire, poiché questi potranno essere +acceduti direttamente nella sezione di memoria mappata; inoltre questa +interfaccia è più efficiente delle usuali funzioni di I/O, in quanto permette +di caricare in memoria solo le parti del file che sono effettivamente usate ad +un dato istante. Infatti, dato che l'accesso è fatto direttamente attraverso la memoria virtuale,\index{memoria~virtuale} la sezione di memoria mappata su cui si @@ -1012,15 +1017,18 @@ opera sar 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. 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 memoria su cui possono esserne lette delle porzioni. - -L'interfaccia prevede varie funzioni per la gestione del \textit{memory mapped - I/O}, la prima di queste è \funcd{mmap}, che serve ad eseguire la mappatura -in memoria di un file; il suo prototipo è: +salvate sullo 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 +memoria su cui possono esserne lette delle porzioni. + +L'interfaccia POSIX implementata da Linux prevede varie funzioni 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{functions} \headdecl{unistd.h} @@ -1094,7 +1102,7 @@ specificato come maschera binaria ottenuta dall'OR di uno o pi riportati in tab.~\ref{tab:file_mmap_flag}; 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, +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 @@ -1119,7 +1127,7 @@ tab.~\ref{tab:file_mmap_flag}. 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{unmap}), e solo allora le modifiche saranno + \func{munmap}), e solo allora le modifiche saranno visibili per l'I/O convenzionale. Incompatibile con \const{MAP\_PRIVATE}. \\ \const{MAP\_PRIVATE} & I cambiamenti sulla memoria mappata non vengono @@ -1539,14 +1547,14 @@ anche se richiesto attraverso un file descriptor, agisce sempre su un file; perciò le informazioni relative agli eventuali \textit{file lock} sono mantenute a livello di inode\index{inode},\footnote{in particolare, come accennato in fig.~\ref{fig:file_flock_struct}, i \textit{file lock} sono - mantenuti un una \textit{linked list}\index{linked list} di strutture - \struct{file\_lock}. La lista è referenziata dall'indirizzo di partenza - mantenuto dal campo \var{i\_flock} della struttura \struct{inode} (per le - definizioni esatte si faccia riferimento al file \file{fs.h} nei sorgenti - del kernel). Un bit del campo \var{fl\_flags} di specifica se si tratta di - un lock in semantica BSD (\const{FL\_FLOCK}) o POSIX (\const{FL\_POSIX}).} -dato che questo è l'unico riferimento in comune che possono avere due processi -diversi che aprono lo stesso file. + mantenuti un una \textit{linked~list}\index{\textit{linked list}} di + strutture \struct{file\_lock}. La lista è referenziata dall'indirizzo di + partenza mantenuto dal campo \var{i\_flock} della struttura \struct{inode} + (per le definizioni esatte si faccia riferimento al file \file{fs.h} nei + sorgenti del kernel). Un bit del campo \var{fl\_flags} di specifica se si + tratta di un lock in semantica BSD (\const{FL\_FLOCK}) o POSIX + (\const{FL\_POSIX}).} dato che questo è l'unico riferimento in comune che +possono avere due processi diversi che aprono lo stesso file. \begin{figure}[htb] \centering @@ -1793,7 +1801,8 @@ questo caso la titolarit voce nella file table, ma con il valore del \acr{pid} del processo. Quando si richiede un lock il kernel effettua una scansione di tutti i lock -presenti sul file\footnote{scandisce cioè la linked list delle strutture +presenti sul file\footnote{scandisce cioè la + \index{\textit{linked~list}}\textit{linked list} delle strutture \struct{file\_lock}, scartando automaticamente quelle per cui \var{fl\_flags} non è \const{FL\_POSIX}, così che le due interfacce restano ben separate.} per verificare se la regione richiesta non si sovrappone ad @@ -1877,7 +1886,7 @@ POSIX), e la variabile \var{cmd} che specifica la modalit lock (bloccante o meno), a seconda dell'opzione \cmd{-b}. Il programma inizia col controllare (\texttt{\small 11--14}) che venga passato -un parametro (il file da bloccare), che sia stato scelto (\texttt{\small +un argomento (il file da bloccare), che sia stato scelto (\texttt{\small 15--18}) il tipo di lock, dopo di che apre (\texttt{\small 19}) il file, uscendo (\texttt{\small 20--23}) in caso di errore. A questo punto il comportamento dipende dalla semantica scelta; nel caso sia BSD occorre