-Benché l'I/O asincrono preveda un meccanismo di notifica, l'interfaccia
-fornisce anche una apposita funzione, \funcd{aio\_suspend}, che permette di
-sospendere l'esecuzione del processo chiamante fino al completamento di una
-specifica operazione; il suo prototipo è:
-\begin{prototype}{aio.h}
-{int aio\_suspend(const struct aiocb * const list[], int nent, const struct
- timespec *timeout)}
-
- Attende, per un massimo di \param{timeout}, il completamento di una delle
- operazioni specificate da \param{list}.
-
- \bodydesc{La funzione restituisce 0 se una (o più) operazioni sono state
- completate, e -1 in caso di errore nel qual caso \var{errno} assumerà uno
- dei valori:
- \begin{errlist}
- \item[\errcode{EAGAIN}] nessuna operazione è stata completata entro
- \param{timeout}.
- \item[\errcode{ENOSYS}] la funzione non è implementata.
- \item[\errcode{EINTR}] la funzione è stata interrotta da un segnale.
- \end{errlist}
- }
-\end{prototype}
-
-La funzione permette di bloccare il processo fintanto che almeno una delle
-\param{nent} operazioni specificate nella lista \param{list} è completata, per
-un tempo massimo specificato da \param{timout}, o fintanto che non arrivi un
-segnale.\footnote{si tenga conto che questo segnale può anche essere quello
- utilizzato come meccanismo di notifica.} La lista deve essere inizializzata
-con delle strutture \struct{aiocb} relative ad operazioni effettivamente
-richieste, ma può contenere puntatori nulli, che saranno ignorati. In caso si
-siano specificati valori non validi l'effetto è indefinito. Un valore
-\val{NULL} per \param{timout} comporta l'assenza di timeout.
-
-Lo standard POSIX.1b infine ha previsto pure una funzione, \funcd{lio\_listio},
-che permette di effettuare la richiesta di una intera lista di operazioni di
-lettura o scrittura; il suo prototipo è:
-\begin{prototype}{aio.h}
- {int lio\_listio(int mode, struct aiocb * const list[], int nent, struct
- sigevent *sig)}
-
- Richiede l'esecuzione delle operazioni di I/O elencata da \param{list},
- secondo la modalità \param{mode}.
-
- \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{EAGAIN}] nessuna operazione è stata completata entro
- \param{timeout}.
- \item[\errcode{EINVAL}] si è passato un valore di \param{mode} non valido
- o un numero di operazioni \param{nent} maggiore di
- \const{AIO\_LISTIO\_MAX}.
- \item[\errcode{ENOSYS}] la funzione non è implementata.
- \item[\errcode{EINTR}] la funzione è stata interrotta da un segnale.
- \end{errlist}
- }
-\end{prototype}
-
-La funzione esegue la richiesta delle \param{nent} operazioni indicate nella
-lista \param{list} che deve contenere gli indirizzi di altrettanti
-\textit{control block} opportunamente inizializzati; in particolare dovrà
-essere specificato il tipo di operazione con il campo \var{aio\_lio\_opcode},
-che può prendere i valori:
-\begin{basedescript}{\desclabelwidth{2.0cm}}
-\item[\const{LIO\_READ}] si richiede una operazione di lettura.
-\item[\const{LIO\_WRITE}] si richiede una operazione di scrittura.
-\item[\const{LIO\_NOP}] non si effettua nessuna operazione.
-\end{basedescript}
-dove \const{LIO\_NOP} viene usato quando si ha a che fare con un vettore di
-dimensione fissa, per poter specificare solo alcune operazioni, o quando si
-sono dovute cancellare delle operazioni e si deve ripetere la richiesta per
-quelle non completate.
-
-L'argomento \param{mode} controlla il comportamento della funzione, se viene
-usato il valore \const{LIO\_WAIT} la funzione si blocca fino al completamento
-di tutte le operazioni richieste; se si usa \const{LIO\_NOWAIT} la funzione
-ritorna immediatamente dopo aver messo in coda tutte le richieste. In tal caso
-il chiamante può richiedere la notifica del completamento di tutte le
-richieste, impostando l'argomento \param{sig} in maniera analoga a come si fa
-per il campo \var{aio\_sigevent} di \struct{aiocb}.
-
-
-\section{Altre modalità di I/O avanzato}
-\label{sec:file_advanced_io}
-
-Oltre alle precedenti modalità di \textit{I/O multiplexing} e \textsl{I/O
- asincrono}, esistono altre funzioni che implementano delle modalità di
-accesso ai file più evolute rispetto alle normali funzioni di lettura e
-scrittura che abbiamo esaminato in sez.~\ref{sec:file_base_func}. In questa
-sezione allora prenderemo in esame le interfacce per l'\textsl{I/O mappato in
- memoria}, per l'\textsl{I/O vettorizzato} e altre funzioni di I/O avanzato.
-
-
-\subsection{File mappati in memoria}
-\label{sec:file_memory_map}
-
-\itindbeg{memory~mapping}
-Una modalità alternativa di I/O, che usa una interfaccia completamente diversa
-rispetto a quella classica vista in cap.~\ref{cha:file_unix_interface}, è il
-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.
- che lo ha allocato
-\begin{figure}[htb]
- \centering
- \includegraphics[width=12cm]{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}
-
-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}.
-
-L'uso del \textit{memory-mapping} 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
-\index{memoria~virtuale} memoria virtuale, la sezione di memoria mappata su
-cui si opera sarà a sua volta letta o scritta sul file una pagina alla volta e
-solo 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.