accadere che \func{select} riporti il relativo file descriptor come
leggibile, ma una successiva \func{read} si blocchi.} il secondo,
\param{writefds}, per verificare la possibilità effettuare una scrittura ed il
-terzo,
-\param{exceptfds}, per verificare l'esistenza di eccezioni (come i dati
+terzo, \param{exceptfds}, per verificare l'esistenza di eccezioni (come i dati
urgenti \itindex{out-of-band} su un socket, vedi
sez.~\ref{sec:TCP_urgent_data}).
immediato (e può essere utilizzato per impiegare \func{poll} in modalità
\textsl{non-bloccante}).
-\begin{figure}[!htb]
- \footnotesize \centering
- \begin{minipage}[c]{15cm}
- \includestruct{listati/pollfd.h}
- \end{minipage}
- \normalsize
- \caption{La struttura \structd{pollfd}, utilizzata per specificare le
- modalità di controllo di un file descriptor alla funzione \func{poll}.}
- \label{fig:file_pollfd}
-\end{figure}
-
Per ciascun file da controllare deve essere inizializzata una struttura
\struct{pollfd} nel vettore indicato dall'argomento \param{ufds}. La
struttura, la cui definizione è riportata in fig.~\ref{fig:file_pollfd},
\var{revents}) non è necessario reinizializzare tutte le volte il valore delle
strutture \struct{pollfd} a meno di non voler cambiare qualche condizione.
+\begin{figure}[!htb]
+ \footnotesize \centering
+ \begin{minipage}[c]{15cm}
+ \includestruct{listati/pollfd.h}
+ \end{minipage}
+ \normalsize
+ \caption{La struttura \structd{pollfd}, utilizzata per specificare le
+ modalità di controllo di un file descriptor alla funzione \func{poll}.}
+ \label{fig:file_pollfd}
+\end{figure}
+
Le costanti che definiscono i valori relativi ai bit usati nelle maschere
binarie dei campi \var{events} e \var{revents} sono riportati in
tab.~\ref{tab:file_pollfd_flags}, insieme al loro significato. Le si sono
indica un errore nella chiamata, il cui codice viene riportato al solito
tramite \var{errno}.
+L'uso di \func{poll} consente di superare alcuni dei problemi illustrati in
+precedenza per \func{select}; anzitutto, dato che in questo caso si usa un
+vettore di strutture \struct{pollfd} di dimensione arbitraria, non esiste il
+limite introdotto dalle dimesioni massime di un \itindex{file~descriptor~set}
+\textit{file descriptor set} e la dimensione dei dati passati al kernel
+dipende solo dal numero dei file descriptor che si vogliono controllare, non
+dal loro valore.\footnote{anche se usando dei bit un \textit{file descriptor
+ set} può essere più efficiente di un vettore di strutture \struct{pollfd},
+ qualora si debba osservare un solo file descriptor con un valore molto alto
+ ci si troverà ad utilizzare inutilmente un maggiore quantitativo di
+ memoria.}
+
+Inoltre con \func{select} lo stesso \itindex{file~descriptor~set} \textit{file
+ descriptor set} è usato sia in ingresso che in uscita, e questo significa
+che tutte le volte che si vuole ripetere l'operazione occorre reinizializzarlo
+da capo. Questa operazione, che può essere molto onerosa se i file descriptor
+da tenere sotto osservazione sono molti, non è invece necessaria con
+\func{poll}.
+
Abbiamo visto in sez.~\ref{sec:file_select} come lo standard POSIX preveda una
variante di \func{select} che consente di gestire correttamente la ricezione
dei segnali nell'attesa su un file descriptor. Con l'introduzione di una
implementazione reale di \func{pselect} nel kernel 2.6.16, è stata aggiunta
-anche una analoga funzione che svolga lo stesso ruolo per \func{poll}.
+anche una analoga funzione che svolga lo stesso ruolo per \func{poll}.
In questo caso si tratta di una estensione che è specifica di Linux e non è
prevista da nessuno standard; essa può essere utilizzata esclusivamente se si
risultati illustrati in precedenza.
-% TODO accennare a ppoll vedi articolo LWN http://lwn.net/Articles/176750/
+\subsection{L'interfaccia di \textit{epoll}}
+\label{sec:file_epoll}
+
+\itindbeg{epoll}
+
+Nonostante \func{poll} presenti alcuni vantaggi rispetto a \func{select},
+anche questa funzione non è molto efficiente quando deve essere utilizzata con
+un gran numero di file descriptor,\footnote{in casi del genere \func{select}
+ viene scartata a priori, perché può avvenire che il numero di file
+ descriptor ecceda le dimensioni massime di un \itindex{file~descriptor~set}
+ \textit{file descriptor set}.} in particolare nel caso in cui solo pochi di
+questi diventano attivi. Il problema in questo caso è che il tempo impiegato
+da \func{poll} a trasferire i dati da e verso il kernel è proporzionale al
+numero di file descriptor osservati, non a quelli che presentano attività.
+
+Quando ci sono decine di migliaia di file descriptor osservati e migliaia di
+eventi al secondo,\footnote{il caso classico è quello di un server web di un
+ sito con molti accessi.} l'uso di \func{poll} comporta la necessità di
+trasferire avanti ed indietro da user space a kernel space la lunga lista
+delle strutture \struct{pollfd} migliaia di volte al secondo. A questo poi si
+aggiunge il fatto che la maggior parte del tempo di esecuzione sarà impegnato
+ad eseguire una scansione su tutti i file descriptor tenuti sotto controllo
+per determinare quali di essi (in genere una piccola percentuale) sono
+diventati attivi. In una situazione come questa l'uso delle funzioni classiche
+dell'interfaccia dell'\textit{I/O multiplexing} viene a costituire un collo di
+bottiglia che degrada irrimediabilmente le prestazioni.
-%\subsection{L'interfaccia di \textit{epoll}}
-%\label{sec:file_epoll}
-% placeholder ...
+Per risolvere questo tipo di situazioni è stata creata una nuova
+interfaccia,\footnote{l'interfaccia è stata creata da Davide Libernzi, ed è
+ stata introdotta per la prima volta nel kernel 2.5.44, ma la sua forma
+ definitiva è stata raggiunta nel kernel 2.5.66.} detta \textit{epoll}, il
+cui concetto fondamentale è quello di restituire solamente le informazioni
+relative ai file descriptor osservati che presentano una attività, evitando
+così tutti le problematiche appena illustrate.
+
+
+
+
+
+\itindend{epoll}
% TODO epoll
+%
\section{L'accesso \textsl{asincrono} ai file}
\label{sec:file_asyncronous_access}
accesso ai file; per questo motivo Stevens chiama questa modalità
\textit{signal driven I/O}.
-In questo modo si può evitare l'uso delle funzioni \func{poll} o \func{select}
-che, quando vengono usate con un numero molto grande di file descriptor, non
-hanno buone prestazioni. % TODO aggiungere cenno a epoll quando l'avrò scritta
- In tal caso infatti la maggior parte del loro tempo
-di esecuzione è impegnato ad eseguire una scansione su tutti i file descriptor
-tenuti sotto controllo per determinare quali di essi (in genere una piccola
-percentuale) sono diventati attivi.
+Questa è un'altra modalità di gestione I/O, alternativa all'uso di
+\itindex{epoll} \textit{epoll}, che consente di evitare l'uso delle funzioni
+\func{poll} o \func{select} che, come illustrato in sez.~\ref{sec:file_epoll},
+quando vengono usate con un numero molto grande di file descriptor, non hanno
+buone prestazioni.
Tuttavia con l'implementazione classica dei segnali questa modalità di I/O
presenta notevoli problemi, dato che non è possibile determinare, quando i
\index{file!inotify|)}
-
+% TODO inserire anche eventfd (vedi http://lwn.net/Articles/233462/)
\itindend{memory~mapping}
-\subsection{L'I/O diretto fra file descriptor con \func{sendfile}}
-\label{sec:file_sendfile}
+\subsection{L'I/O diretto fra file descriptor}
+\label{sec:file_sendfile_splice}
Uno dei problemi
\href{http://www.cs.helsinki.fi/linux/linux-kernel/2001-03/0200.html}
{\texttt{http://www.cs.helsinki.fi/linux/linux-kernel/2001-03/0200.html}}
-% TODO documentare la funzione sendfile
+% TODO documentare la funzione sendfile
+% TODO documentare le funzioni tee e splice
+% http://kerneltrap.org/node/6505 e http://lwn.net/Articles/178199/ e
+% http://lwn.net/Articles/179492/
+% e http://en.wikipedia.org/wiki/Splice_(system_call)
% i raw device