due system call, \func{vmsplice} e \func{tee}, che utilizzano la stessa
infrastruttura e si basano sullo stesso concetto di manipolazione e
trasferimento di dati attraverso un buffer in kernel space; benché queste non
-attengono strettamente ad operazioni di trasferiemento dati fra file
+attengono strettamente ad operazioni di trasferimento dati fra file
descriptor, le tratteremo qui.
La prima funzione, \funcd{vmsplice}, è la più simile a \func{splice} e come
a sez.~\ref{sec:ipc_unix}), mentre per indicare quali zone di memoria devono
essere trasferita si deve utilizzare un vettore di strutture \struct{iovec}
(vedi fig.~\ref{fig:file_iovec}), con le stesse con cui le si usano per l'I/O
-vettorizzato; le dimensioni del sudetto vettore devono essere passate
+vettorizzato; le dimensioni del suddetto vettore devono essere passate
nell'argomento \param{nr\_segs} che indica il numero di segmenti di memoria da
trasferire. Sia per il vettore che per il valore massimo di \param{nr\_segs}
valgono le stesse limitazioni illustrate in sez.~\ref{sec:file_multiple_io}.
In caso di successo la funzione ritorna il numero di byte trasferiti sulla
pipe, in generale (se i dati una volta creati non devono essere riutilizzati)
è opportuno utilizzare il flag \const{SPLICE\_F\_GIFT}; questo fa si che il
-kernel possa rimuovere le relative pagine dallo spazio degli indifizzi del
+kernel possa rimuovere le relative pagine dallo spazio degli indirizzi del
processo, e scaricarle nella cache, così che queste possono essere utilizzate
immediatamente senza necessità di eseguire una copia dei dati che contengono.
impostato il flag \const{SPLICE\_F\_NONBLOCK}, in tal caso infatti si
avrebbe un errore di \errcode{EAGAIN}.} Un esempio di realizzazione del
comando \texttt{tee} usando questa funzione, ripreso da quello fornito nella
-pagina di manuale e dall'esempio allegato al pacth originale, è riportato in
+pagina di manuale e dall'esempio allegato al patch originale, è riportato in
fig.~\ref{fig:tee_example}. Il programma consente di copiare il contenuto
dello standard input sullo standard output e su un file specificato come
argomento, il codice completo si trova nel file \texttt{tee.c} dei sorgenti
controllare (\texttt{\small 11--14}) che sia stato fornito almeno un argomento
(il nome del file su cui scrivere), di aprirlo ({\small 15--19}) e che sia lo
standard input (\texttt{\small 20--27}) che lo standard output (\texttt{\small
- 28--35}) corripondano ad una \textit{pipe}.
+ 28--35}) corrispondano ad una \textit{pipe}.
Il ciclo principale (\texttt{\small 37--58}) inizia con la chiamata a
\func{tee} che duplica il contenuto dello standard input sullo standard output
\textit{caching}.
Una prima funzione che può essere utilizzata per modificare la gestione
-ordinaria dell'I/O su file è \funcd{readahead}, che consente di richiedere la
-lettura del contenuto di un file sulla cache, così che le seguenti operazioni
-di lettura non debbano bloccarsi nell'I/O su disco, il suo prototipo è:
+ordinaria dell'I/O su file è \funcd{readahead},\footnote{questa è una funzione
+ specifica di Linux, introdotta con il kernel 2.4.13, e non deve essere usata
+ se si vogliono scrivere programmi portabili.} che consente di richiedere una
+lettura anticipata del contenuto dello stesso in modo da riempire la memoria
+di cache, così che le seguenti operazioni di lettura non debbano bloccarsi
+nell'I/O su disco, il suo prototipo è:
\begin{functions}
\headdecl{fcntl.h}
- \funcdecl{ssize_t readahead(int fd, off64_t *offset, size_t count)}
+ \funcdecl{ssize\_t readahead(int fd, off64\_t *offset, size\_t count)}
Legge il contenuto di un file nella cache di memoria.
\bodydesc{La funzione restituisce 0 in caso di successo e $-1$ in caso di
errore, nel qual caso \var{errno} assumerà uno dei valori:
\begin{errlist}
- \item[\errcode{EBADF}] .
- \item[\errcode{EINVAL}] .
+ \item[\errcode{EBADF}] \param{fd} non è valido o non è aperto in lettura.
+ \item[\errcode{EINVAL}] \param{fd} si riferisce ad un tipo di file che non
+ supporta l'operazione (come una pipe o un socket)..
\end{errlist}
}
\end{functions}
+La funzione richiede che sul file \param{fd}, a partire dalla posizione
+\param{offset}, venga letto in anticipo il contenuto, portandolo nella cache
+della memoria virtuale, per un ammontare di \param{count} bytes. La funzione
+usa la memoria virtuale ed il meccanismo della paginazione per cui la lettura
+verrà eseguita in blocchi corrispondenti alle dimensioni delle pagine di
+memoria, ed i valori di \param{offset} e \param{count} arrotondati di
+conseguenza.
+
+La funzione esegue la lettura bloccandosi fintanto che questa non viene
+completata. La posizione corrente sul file non viene modificata ed
+indipendentemente da quanto indicato con \param{count} la lettura dei dati si
+interromperà una volta raggiunta la fine del file.
+
+Si può utilizzare questa funzione per velocizzare le operazioni di lettura
+all'interno del programma tutte le volte che si conosce in anticipo quanti
+dati saranno necessari in seguito. Si potrà così concentrare in un unico
+momento (ad esempio in fase di inizializzazione) la lettura, così da ottenere
+una migliore risposta nelle operazioni successive.
+
+Il concetto di \func{readahead} viene generalizzato da
+\funcd{posix\_fadvise},\footnote{al contario di \func{readahead} la funzione è
+ definita nello standard POSIX.1-2001 (anche se l'argomento \param{len} è
+ stato modificato da \ctyp{size\_t} a \ctyp{off\_t} nella revisione
+ POSIX.1-2003 TC5), però è disponibile su Linux a partire dai kernel della
+ serie 2.6.} che consente di ``\textsl{avvisare}'' il kernel sulle modalità
+con cui si intende accedere nel futuro ad una certa porzione di un file, così
+che esso possa provvedere le opportune ottimizzazioni; il suo prototipo è:
+\begin{functions}
+ \headdecl{fcntl.h}
+
+ \funcdecl{int posix\_fadvise(int fd, off\_t offset, off\_t len, int advice)}
+
+ Dichiara al kernel le future modalità di accesso ad un file.
+
+ \bodydesc{La funzione restituisce 0 in caso di successo e $-1$ in caso di
+ errore, nel qual caso \var{errno} assumerà uno dei valori:
+ \begin{errlist}
+ \item[\errcode{EBADF}] \param{fd} non è valido o non è aperto in lettura.
+ \item[\errcode{EINVAL}] \param{fd} si riferisce ad un tipo di file che non
+ supporta l'operazione (come una pipe o un socket)..
+ \end{errlist}
+ }
+\end{functions}
+
+
+
% TODO documentare \func{posix\_fadvise}
% TODO documentare \func{readahead}
% LocalWords: EPOLLHUP EPOLLET EPOLLONESHOT shot maxevents ctlv ALL DONT HPUX
% LocalWords: FOLLOW ONESHOT ONLYDIR FreeBSD EIO caching sysctl instances name
% LocalWords: watches IGNORED ISDIR OVERFLOW overflow UNMOUNT queued cookie ls
-% LocalWords: NUL sizeof casting printevent nread limits sysconf SC wrapper
+% LocalWords: NUL sizeof casting printevent nread limits sysconf SC wrapper Di
% LocalWords: splice result argument DMA controller zerocopy Linus Larry Voy
-% LocalWords: Jens Anxboe vmsplice seek ESPIPE GIFT TCP CORK MSG splicecp
+% LocalWords: Jens Anxboe vmsplice seek ESPIPE GIFT TCP CORK MSG splicecp nr
+% LocalWords: nwrite segs patch readahead
%%% Local Variables: