Sistemati gli indici.
authorSimone Piccardi <piccardi@gnulinux.it>
Tue, 9 Jul 2002 17:29:24 +0000 (17:29 +0000)
committerSimone Piccardi <piccardi@gnulinux.it>
Tue, 9 Jul 2002 17:29:24 +0000 (17:29 +0000)
fileadv.tex
filedir.tex
fileunix.tex
intro.tex
process.tex
prochand.tex
signal.tex
system.tex

index 067e1ff04970e5009e230935f97f2a1f5a527a7f..744237990b07fc99dc9948e48d0e189b80d4f2bb 100644 (file)
@@ -84,11 +84,56 @@ Attende che un certo insieme di file descriptor cambi stato.
 \end{prototype}
 
 La funzione mette il processo in stato di \textit{sleep} (vedi
 \end{prototype}
 
 La funzione mette il processo in stato di \textit{sleep} (vedi
-\ref{tab:proc_proc_states})
+\tabref{tab:proc_proc_states}) fintanto che non viene rilevate dell'attività
+sull'insieme dei file descriptor specificati (\param{readfds},
+\param{writefds} e \param{exceptfds}), per un tempo massimo specificato da
+\param{timeout}. 
+
+Per specificare quali file descriptor si intende selezionare, la funzione usa
+un particolare oggetto, il \textit{file descriptor set}, identificato dal tipo
+\type{fd\_set}, che serve ad identificare un insieme di file descriptor, in
+maniera analoga a come un \textit{signal set} (vedi \secref{sec:sig_sigset})
+identifica un insieme di segnali. Per la manipolazione di questi \textit{file
+  descriptor set} si possono usare delle opportune macro di preprocessore:
+\begin{functions}
+  \headdecl{sys/select.h}
+  \funcdecl{FD\_ZERO(fd\_set *set)}
+  Inizializza l'insieme (vuoto).
+
+  \funcdecl{FD\_SET(int fd, fd\_set *set)}
+  Inserisce il file descriptor \param{fd} nell'insieme.
+
+  \funcdecl{FD\_CLR(int fd, fd\_set *set)}
+  Rimuove il file descriptor \param{fd} nell'insieme.
+  
+  \funcdecl{FD\_ISSET(int fd, fd\_set *set)}
+  Controlla se il file descriptor \param{fd} è nell'insieme.
+\end{functions}
 
 
+In genere un \textit{file descriptor set} può contenere fino ad un massimo di
+\macro{FD\_SETSIZE} file descriptor.  Questo a seconda del sistema può essere
+il limite del numero massimo di file aperti\footnote{ad esempio in Linux, fino
+  alla serie 2.0.x, c'era un limite di 256 file per processo.}, ma quando,
+come nelle versioni più recenti del kernel, questo limite non c'è un massimo,
+esso indica le dimensioni in munero di bit utilizzabili per l'insieme.
 
 
 
 
-il cui prototipo è:
+La funzione richiede di specificare tre insiemi distinti di file descriptor;
+il primo, \param{readfds}, verrà osservato per rilevare la disponibilità di
+input in lettura, il secondo, \param{writefds} per verificare la possibilità
+di scrivere ed il terzo, \param{exceptfds}, per verificare l'esistenza di
+eccezioni. I corrispondenti valori dei \textit{file descriptor set} saranno
+modificati di conseguenza per mostrare quale dei file descriptor ha cambiato
+stato.
+
+
+
+
+
+Come accennato l'interfaccia di \func{select} è una estensione aggiunta BSD, e
+poi entrata a far parte di POSIX; allo stesso tempo System V aveva introdotto
+una interfaccia alternativa, basata sulla funzione \func{poll}, il cui
+prototipo è:
 \begin{prototype}{sys/poll.h}
   {int poll(struct pollfd *ufds, unsigned int nfds, int timeout)}
 
 \begin{prototype}{sys/poll.h}
   {int poll(struct pollfd *ufds, unsigned int nfds, int timeout)}
 
@@ -97,7 +142,9 @@ specificati da \param{ufds}.
   
 \bodydesc{La funzione restituisce il numero di file descriptor con attività in
   caso di successo, o 0 se c'è stato un timeout; in caso di errore viene
   
 \bodydesc{La funzione restituisce il numero di file descriptor con attività in
   caso di successo, o 0 se c'è stato un timeout; in caso di errore viene
-  restituito  -1 ed \var{errno} viene .}
+  restituito  -1 ed \var{errno} viene settata ai valori:
+
+.}
 \end{prototype}
 
 
 \end{prototype}
 
 
@@ -145,11 +192,12 @@ diversi. In quell'occasione si 
 in \textit{append mode}, quando più processi scrivono contemporaneamente sullo
 stesso file non è possibile determinare la sequenza in cui essi opereranno.
 
 in \textit{append mode}, quando più processi scrivono contemporaneamente sullo
 stesso file non è possibile determinare la sequenza in cui essi opereranno.
 
-Questo causa la possibilità di race condition; in generale le situazioni più
-comuni sono due: l'interazione fra un processo che scrive e altri che leggono,
-in cui questi ultimi possono leggere informazioni scritte solo in maniera
-parziale o incompleta; o quella in cui diversi processi scrivono, mescolando
-in maniera imprevedebile il loro output sul file.
+Questo causa la possibilità di race condition\index{race condition}; in
+generale le situazioni più comuni sono due: l'interazione fra un processo che
+scrive e altri che leggono, in cui questi ultimi possono leggere informazioni
+scritte solo in maniera parziale o incompleta; o quella in cui diversi
+processi scrivono, mescolando in maniera imprevedebile il loro output sul
+file.
 
 In tutti questi casi il \textit{file locking} è la tecnica che permette di
 evitare le race condition, attraverso una serie di funzioni che permettono di
 
 In tutti questi casi il \textit{file locking} è la tecnica che permette di
 evitare le race condition, attraverso una serie di funzioni che permettono di
index 66b1f99ca40ccf2688b6763c1dbf59ff0e16af10..c389a7de87d5ac351a71c5d31fb5cb79e8b9c501 100644 (file)
@@ -793,7 +793,8 @@ POSIX definisce la funzione \func{tempfile}, il cui prototipo 
 automaticamente cancellato alla sua chiusura o all'uscita dal programma. Lo
 standard non specifica in quale directory verrà aperto il file, ma le
 \acr{glibc} prima tentano con \macro{P\_tmpdir} e poi con \file{/tmp}. Questa
 automaticamente cancellato alla sua chiusura o all'uscita dal programma. Lo
 standard non specifica in quale directory verrà aperto il file, ma le
 \acr{glibc} prima tentano con \macro{P\_tmpdir} e poi con \file{/tmp}. Questa
-funzione è rientrante e non soffre di problemi di \textit{race condition}.
+funzione è rientrante e non soffre di problemi di \textit{race
+  condition}\index{race condition}.
 
 Alcune versioni meno recenti di Unix non supportano queste funzioni; in questo
 caso si possono usare le vecchie funzioni \func{mktemp} e \func{mkstemp} che
 
 Alcune versioni meno recenti di Unix non supportano queste funzioni; in questo
 caso si possono usare le vecchie funzioni \func{mktemp} e \func{mkstemp} che
@@ -814,12 +815,13 @@ il suo prototipo 
 \end{prototype}
 \noindent dato che \param{template} deve poter essere modificata dalla
 funzione non si può usare una stringa costante.  Tutte le avvertenze riguardo
 \end{prototype}
 \noindent dato che \param{template} deve poter essere modificata dalla
 funzione non si può usare una stringa costante.  Tutte le avvertenze riguardo
-alle possibili \textit{race condition} date per \func{tmpnam} continuano a
-valere; inoltre in alcune vecchie implementazioni il valore di usato per
-sostituire le \code{XXXXXX} viene formato con il \acr{pid} del processo più
-una lettera, il che mette a disposizione solo 26 possibilità diverse per il
-nome del file, e rende il nome temporaneo facile da indovinare. Per tutti
-questi motivi la funzione è deprecata e non dovrebbe mai essere usata.
+alle possibili \textit{race condition}\index{race condition} date per
+\func{tmpnam} continuano a valere; inoltre in alcune vecchie implementazioni
+il valore di usato per sostituire le \code{XXXXXX} viene formato con il
+\acr{pid} del processo più una lettera, il che mette a disposizione solo 26
+possibilità diverse per il nome del file, e rende il nome temporaneo facile da
+indovinare. Per tutti questi motivi la funzione è deprecata e non dovrebbe mai
+essere usata.
 
 
 
 
 
 
@@ -865,8 +867,8 @@ In OpenBSD 
 \end{prototype}
 \noindent la directory è creata con permessi \code{0700} (al solito si veda
 \capref{cha:file_unix_interface} per i dettagli); dato che la creazione della
 \end{prototype}
 \noindent la directory è creata con permessi \code{0700} (al solito si veda
 \capref{cha:file_unix_interface} per i dettagli); dato che la creazione della
-directory è sempre esclusiva i precedenti problemi di \textit{race condition}
-non si pongono.
+directory è sempre esclusiva i precedenti problemi di \textit{race
+  condition}\index{race condition} non si pongono.
 
 
 \section{La manipolazione delle caratteristiche dei files}
 
 
 \section{La manipolazione delle caratteristiche dei files}
index 56e70435f4d2934b1e1abdeffe54b4ce5e82e703..37b090626418cd83b16726298ba994c89f3418b4 100644 (file)
@@ -3,11 +3,12 @@
 
 
 Esamineremo in questo capitolo la prima delle due interfacce di programmazione
 
 
 Esamineremo in questo capitolo la prima delle due interfacce di programmazione
-per i file, quella dei \textit{file descriptor}, nativa di Unix. Questa è
-l'interfaccia di basso livello provvista direttamente dalle system call, che
-non prevede funzionalità evolute come la bufferizzazione o funzioni di lettura
-o scrittura formattata, e sulla quale è costruita anche l'interfaccia definita
-dallo standard ANSI C che affronteremo al \capref{cha:files_std_interface}.
+per i file, quella dei \textit{file descriptor}\index{file descriptor},
+nativa di Unix. Questa è l'interfaccia di basso livello provvista direttamente
+dalle system call, che non prevede funzionalità evolute come la
+bufferizzazione o funzioni di lettura o scrittura formattata, e sulla quale è
+costruita anche l'interfaccia definita dallo standard ANSI C che affronteremo
+al \capref{cha:files_std_interface}.
 
 
 
 
 
 
@@ -33,10 +34,10 @@ terminate le operazioni, il file dovr
 canale di comunicazione impedendo ogni ulteriore operazione.
 
 All'interno di ogni processo i file aperti sono identificati da un intero non
 canale di comunicazione impedendo ogni ulteriore operazione.
 
 All'interno di ogni processo i file aperti sono identificati da un intero non
-negativo, chiamato appunto \textit{file descriptor}. Quando un file viene
-aperto la funzione \func{open} restituisce questo numero, tutte le ulteriori
-operazioni saranno compiute specificando questo stesso valore come argomento
-alle varie funzioni dell'interfaccia.
+negativo, chiamato appunto \textit{file descriptor}\index{file descriptor}.
+Quando un file viene aperto la funzione \func{open} restituisce questo numero,
+tutte le ulteriori operazioni saranno compiute specificando questo stesso
+valore come argomento alle varie funzioni dell'interfaccia.
 
 Per capire come funziona il meccanismo occorre spiegare a grandi linee come è
 che il kernel gestisce l'interazione fra processi e file.  Il kernel mantiene
 
 Per capire come funziona il meccanismo occorre spiegare a grandi linee come è
 che il kernel gestisce l'interazione fra processi e file.  Il kernel mantiene
@@ -56,8 +57,8 @@ particolare:
 \item una tabella che contiene un puntatore alla relativa voce nella
   \textit{file table} per ogni file aperto.
 \end{itemize*}
 \item una tabella che contiene un puntatore alla relativa voce nella
   \textit{file table} per ogni file aperto.
 \end{itemize*}
-il \textit{file descriptor} in sostanza è l'intero positivo che indicizza
-quest'ultima tabella.
+il \textit{file descriptor}\index{file descriptor} in sostanza è l'intero
+positivo che indicizza quest'ultima tabella.
 
 La \textit{file table} è una tabella che contiene una voce per ciascun file
 che è stato aperto nel sistema. In Linux è costituita da strutture di tipo
 
 La \textit{file table} è una tabella che contiene una voce per ciascun file
 che è stato aperto nel sistema. In Linux è costituita da strutture di tipo
@@ -87,23 +88,23 @@ varie strutture di dati sulla quale essa 
 \end{figure}
 Ritorneremo su questo schema più volte, dato che esso è fondamentale per
 capire i dettagli del funzionamento dell'interfaccia dei \textit{file
 \end{figure}
 Ritorneremo su questo schema più volte, dato che esso è fondamentale per
 capire i dettagli del funzionamento dell'interfaccia dei \textit{file
-  descriptor}.
+  descriptor}\index{file descriptor}.
 
 
 \subsection{I file standard}
 \label{sec:file_std_descr}
 
 
 
 \subsection{I file standard}
 \label{sec:file_std_descr}
 
-Come accennato i \textit{file descriptor} non sono altro che un indice nella
-tabella dei file aperti di ciascun processo; per questo motivo essi vengono
-assegnati in successione tutte le volte che si apre un nuovo file (se non ne è
-stato chiuso nessuno in precedenza).
+Come accennato i \textit{file descriptor}\index{file descriptor} non sono
+altro che un indice nella tabella dei file aperti di ciascun processo; per
+questo motivo essi vengono assegnati in successione tutte le volte che si apre
+un nuovo file (se non ne è stato chiuso nessuno in precedenza).
 
 In tutti i sistemi unix-like esiste una convenzione generale per cui ogni
 processo viene lanciato con almeno tre file aperti. Questi, per quanto appena
 
 In tutti i sistemi unix-like esiste una convenzione generale per cui ogni
 processo viene lanciato con almeno tre file aperti. Questi, per quanto appena
-detto, avranno come \textit{file descriptor} i valori 0, 1 e 2.  Benché questa
-sia soltanto una convenzione, essa è seguita dalla gran parte delle
-applicazioni, e non aderirvi potrebbe portare a gravi problemi di
-interoperabilità.
+detto, avranno come \textit{file descriptor}\index{file descriptor} i valori
+0, 1 e 2.  Benché questa sia soltanto una convenzione, essa è seguita dalla
+gran parte delle applicazioni, e non aderirvi potrebbe portare a gravi
+problemi di interoperabilità.
 
 Il primo file è sempre associato a quello che viene chiamato \textit{standard
   input}. È cioè il file da cui il processo si aspetta di ricevere i dati in
 
 Il primo file è sempre associato a quello che viene chiamato \textit{standard
   input}. È cioè il file da cui il processo si aspetta di ricevere i dati in
@@ -292,9 +293,9 @@ sempre il file descriptor con il valore pi
 
 \footnotetext[2]{la man page di \func{open} segnala che questa opzione è
   difettosa su NFS, e che i programmi che la usano per stabilire un file di
 
 \footnotetext[2]{la man page di \func{open} segnala che questa opzione è
   difettosa su NFS, e che i programmi che la usano per stabilire un file di
-  lock possono incorrere in una race condition.  Si consiglia come alternativa
-  di usare un file con un nome univoco e la funzione \func{link} per
-  verificarne l'esistenza.}  
+  lock possono incorrere in una race condition\index{race condition}.  Si
+  consiglia come alternativa di usare un file con un nome univoco e la
+  funzione \func{link} per verificarne l'esistenza.}
 
 \footnotetext[3]{\textit{Denial of Service}, si chiamano così attacchi miranti
   ad impedire un servizio causando una qualche forma di carico eccessivo per
 
 \footnotetext[3]{\textit{Denial of Service}, si chiamano così attacchi miranti
   ad impedire un servizio causando una qualche forma di carico eccessivo per
@@ -477,8 +478,8 @@ Si tenga presente inoltre che usare \macro{SEEK\_END} non assicura affatto che
 successiva scrittura avvenga alla fine del file, infatti se questo è stato
 aperto anche da un altro processo che vi ha scritto, la fine del file può
 essersi spostata, ma noi scriveremo alla posizione settata in precedenza.
 successiva scrittura avvenga alla fine del file, infatti se questo è stato
 aperto anche da un altro processo che vi ha scritto, la fine del file può
 essersi spostata, ma noi scriveremo alla posizione settata in precedenza.
-(questa è una potenziale sorgente di \textit{race condition}, vedi
-\secref{sec:file_atomic}).
+(questa è una potenziale sorgente di 
+\textit{race condition}\index{race condition}, vedi \secref{sec:file_atomic}).
 
 Non tutti i file supportano la capacità di eseguire una \func{lseek}, in
 questo caso la funzione ritorna l'errore \macro{EPIPE}. Questo, oltre che per
 
 Non tutti i file supportano la capacità di eseguire una \func{lseek}, in
 questo caso la funzione ritorna l'errore \macro{EPIPE}. Questo, oltre che per
@@ -764,12 +765,14 @@ utilizzare meccanismi di sincronizzazione pi
 Un caso tipico di necessità di accesso condiviso in scrittura è quello in cui
 vari processi devono scrivere alla fine di un file (ad esempio un file di
 log). Come accennato in \secref{sec:file_lseek} settare la posizione alla fine
 Un caso tipico di necessità di accesso condiviso in scrittura è quello in cui
 vari processi devono scrivere alla fine di un file (ad esempio un file di
 log). Come accennato in \secref{sec:file_lseek} settare la posizione alla fine
-del file e poi scrivere può condurre ad una \textit{race condition}: infatti
-può succedere che un secondo processo scriva alla fine del file fra la
-\func{lseek} e la \func{write}; in questo caso, come abbiamo appena visto, il
-file sarà esteso, ma il nostro primo processo avrà ancora la posizione
-corrente settata con la \func{lseek} che non corrisponde più alla fine del
-file, e la successiva \func{write} sovrascriverà i dati del secondo processo.
+del file e poi scrivere può condurre ad una 
+\textit{race condition}\index{race condition}: 
+infatti può succedere che un secondo processo scriva alla fine
+del file fra la \func{lseek} e la \func{write}; in questo caso, come abbiamo
+appena visto, il file sarà esteso, ma il nostro primo processo avrà ancora la
+posizione corrente settata con la \func{lseek} che non corrisponde più alla
+fine del file, e la successiva \func{write} sovrascriverà i dati del secondo
+processo.
 
 Il problema è che usare due system call in successione non è un'operazione
 atomica; il problema è stato risolto introducendo la modalità
 
 Il problema è che usare due system call in successione non è un'operazione
 atomica; il problema è stato risolto introducendo la modalità
@@ -783,8 +786,8 @@ Un altro caso tipico in cui 
 creare un file di lock, bloccandosi se il file esiste. In questo caso la
 sequenza logica porterebbe a verificare prima l'esistenza del file con una
 \func{stat} per poi crearlo con una \func{creat}; di nuovo avremmo la
 creare un file di lock, bloccandosi se il file esiste. In questo caso la
 sequenza logica porterebbe a verificare prima l'esistenza del file con una
 \func{stat} per poi crearlo con una \func{creat}; di nuovo avremmo la
-possibilità di una race condition da parte di un altro processo che crea lo
-stesso file fra il controllo e la creazione. 
+possibilità di una race condition\index{race condition} da parte di un altro
+processo che crea lo stesso file fra il controllo e la creazione.
 
 Per questo motivo sono stati introdotti pe \func{open} i due flag
 \macro{O\_CREAT} e \macro{O\_EXCL}. In questo modo l'operazione di controllo
 
 Per questo motivo sono stati introdotti pe \func{open} i due flag
 \macro{O\_CREAT} e \macro{O\_EXCL}. In questo modo l'operazione di controllo
index 6b7be35e4d4bcff7a39e750c2e29460aa771096c..73f676134373a863bd0f15792e9a5c372173ccbf 100644 (file)
--- a/intro.tex
+++ b/intro.tex
@@ -61,12 +61,12 @@ soltanto attraverso delle opportune chiamate al sistema che restituiranno il
 controllo al kernel.
 
 La memoria viene sempre gestita dal kernel attraverso il meccanismo della
 controllo al kernel.
 
 La memoria viene sempre gestita dal kernel attraverso il meccanismo della
-\textsl{memoria virtuale}, che consente di assegnare a ciascun processo uno
-spazio di indirizzi ``virtuale'' (vedi \secref{sec:proc_memory}) che il kernel
-stesso, con l'ausilio della unità di gestione della memoria, si incaricherà di
-rimappare automaticamente sulla memoria disponibile, salvando su disco quando
-necessario (nella cosiddetta area di \textit{swap}) le pagine di memoria in
-eccedenza.
+\textsl{memoria virtuale}\index{memoria virtuale}, che consente di assegnare a
+ciascun processo uno spazio di indirizzi ``virtuale'' (vedi
+\secref{sec:proc_memory}) che il kernel stesso, con l'ausilio della unità di
+gestione della memoria, si incaricherà di rimappare automaticamente sulla
+memoria disponibile, salvando su disco quando necessario (nella cosiddetta
+area di \textit{swap}) le pagine di memoria in eccedenza.
 
 Le periferiche infine vengono viste in genere attraverso un'interfaccia
 astratta che permette di trattarle come fossero file, secondo il concetto per
 
 Le periferiche infine vengono viste in genere attraverso un'interfaccia
 astratta che permette di trattarle come fossero file, secondo il concetto per
index e3a4774786115eb7561fadeb0e0d914856dc4385..b6afd42cc09f5300e25ce23a689a1d3da1eee227 100644 (file)
@@ -291,8 +291,9 @@ servono. Questo meccanismo 
 \textit{paging}), ed è uno dei compiti principali del kernel.
 
 Quando un processo cerca di accedere ad una pagina che non è nella memoria
 \textit{paging}), ed è uno dei compiti principali del kernel.
 
 Quando un processo cerca di accedere ad una pagina che non è nella memoria
-reale, avviene quello che viene chiamato un \textit{page fault}\index{page
-  fault}; l'hardware di gestione della memoria genera un'interruzione e passa
+reale, avviene quello che viene chiamato un 
+\textit{page fault}\index{page fault}; 
+l'hardware di gestione della memoria genera un'interruzione e passa
 il controllo al kernel il quale sospende il processo e si incarica di mettere
 in RAM la pagina richiesta (effettuando tutte le operazioni necessarie per
 reperire lo spazio necessario), per poi restituire il controllo al processo.
 il controllo al kernel il quale sospende il processo e si incarica di mettere
 in RAM la pagina richiesta (effettuando tutte le operazioni necessarie per
 reperire lo spazio necessario), per poi restituire il controllo al processo.
@@ -319,14 +320,15 @@ tentativo di accedere ad un indirizzo non allocato 
 commette quando si è manipolato male un puntatore e genera quello che viene
 chiamato un \textit{segmentation fault}. Se si tenta cioè di leggere o
 scrivere da un indirizzo per il quale non esiste un'associazione della pagina
 commette quando si è manipolato male un puntatore e genera quello che viene
 chiamato un \textit{segmentation fault}. Se si tenta cioè di leggere o
 scrivere da un indirizzo per il quale non esiste un'associazione della pagina
-virtuale, il kernel risponde al relativo \textit{page fault}
+virtuale, il kernel risponde al relativo \textit{page fault}\index{page fault}
 mandando un segnale \macro{SIGSEGV} al processo, che normalmente ne causa la
 terminazione immediata.
 
 mandando un segnale \macro{SIGSEGV} al processo, che normalmente ne causa la
 terminazione immediata.
 
-È pertanto importante capire come viene strutturata la memoria virtuale di un
-processo. Essa viene divisa in \textsl{segmenti}, cioè un insieme contiguo di
-indirizzi virtuali ai quali il processo può accedere. Solitamente un
-programma C viene suddiviso nei seguenti segmenti:
+È pertanto importante capire come viene strutturata \textsl{la memoria
+  virtuale}\index{page fault} di un processo. Essa viene divisa in
+\textsl{segmenti}, cioè un insieme contiguo di indirizzi virtuali ai quali il
+processo può accedere.  Solitamente un programma C viene suddiviso nei
+seguenti segmenti:
 
 \begin{enumerate}
 \item Il segmento di testo o \textit{text segment}. Contiene il codice del
 
 \begin{enumerate}
 \item Il segmento di testo o \textit{text segment}. Contiene il codice del
@@ -654,13 +656,13 @@ implementare una sua versione delle routine di allocazione.
 % \label{sec:proc_mem_malloc_custom}
 
 
 % \label{sec:proc_mem_malloc_custom}
 
 
-\subsection{Il controllo della memoria virtuale}  
+\subsection{Il controllo della memoria virtuale\index{memoria virtuale}}  
 \label{sec:proc_mem_lock}
 
 \label{sec:proc_mem_lock}
 
-Come spiegato in \secref{sec:proc_mem_gen} il kernel gestisce la memoria in
-maniera trasparente ai processi, decidendo quando rimuovere pagine dalla
-memoria per metterle nello swap, sulla base dell'utilizzo corrente da parte
-dei vari processi.
+Come spiegato in \secref{sec:proc_mem_gen} il kernel gestisce la memoria
+virtuale in maniera trasparente ai processi, decidendo quando rimuovere pagine
+dalla memoria per metterle nello swap, sulla base dell'utilizzo corrente da
+parte dei vari processi.
 
 Nell'uso comune un processo non deve preoccuparsi di tutto ciò, in quanto il
 meccanismo della paginazione\index{paginazione} riporta in RAM, ed in maniera
 
 Nell'uso comune un processo non deve preoccuparsi di tutto ciò, in quanto il
 meccanismo della paginazione\index{paginazione} riporta in RAM, ed in maniera
@@ -708,14 +710,14 @@ comporta anche la fine dell'uso della sua memoria virtuale, e quindi anche di
 tutti i suoi \textit{memory lock}.
 
 I \textit{memory lock} non sono ereditati dai processi figli.\footnote{ma
 tutti i suoi \textit{memory lock}.
 
 I \textit{memory lock} non sono ereditati dai processi figli.\footnote{ma
-  siccome Linux usa il \textit{copy on write} (vedi \secref{sec:proc_fork})
-  gli indirizzi virtuali del figlio sono mantenuti sullo stesso segmento di
-  RAM del padre, quindi fintanto che un figlio non scrive su un segmento, può
-  usufruire del memory lock del padre.}  Siccome la presenza di un
-\textit{memory lock} riduce la memoria disponibile al sistema, con un impatto
-su tutti gli altri processi, solo l'amministratore ha la capacità di bloccare
-una pagina. Ogni processo può però sbloccare le pagine relative alla propria
-memoria.
+  siccome Linux usa il \textit{copy on write}\index{copy on write} (vedi
+  \secref{sec:proc_fork}) gli indirizzi virtuali del figlio sono mantenuti
+  sullo stesso segmento di RAM del padre, quindi fintanto che un figlio non
+  scrive su un segmento, può usufruire del memory lock del padre.}  Siccome la
+presenza di un \textit{memory lock} riduce la memoria disponibile al sistema,
+con un impatto su tutti gli altri processi, solo l'amministratore ha la
+capacità di bloccare una pagina. Ogni processo può però sbloccare le pagine
+relative alla propria memoria.
 
 Il sistema pone dei limiti all'ammontare di memoria di un processo che può
 essere bloccata e al totale di memoria fisica che può dedicare a questo, lo
 
 Il sistema pone dei limiti all'ammontare di memoria di un processo che può
 essere bloccata e al totale di memoria fisica che può dedicare a questo, lo
@@ -787,11 +789,12 @@ esempio limitandosi a tutte le pagine allocate a partire da un certo momento.
 
 In ogni caso un processo real-time che deve entrare in una sezione critica
 deve provvedere a riservare memoria sufficiente prima dell'ingresso, per
 
 In ogni caso un processo real-time che deve entrare in una sezione critica
 deve provvedere a riservare memoria sufficiente prima dell'ingresso, per
-scongiurare in partenza un eventuale page fault causato dal meccanismo di
-\textit{copy on write}.  Infatti se nella sezione critica si va ad utilizzare
-memoria che non è ancora stata riportata in RAM si potrebbe avere un page
-fault durante l'esecuzione della stessa, con conseguente rallentamento
-(probabilmente inaccettabile) dei tempi di esecuzione.
+scongiurare in partenza un eventuale page fault\index{page fault} causato dal
+meccanismo di \textit{copy on write}\index{copy on write}.  Infatti se nella
+sezione critica si va ad utilizzare memoria che non è ancora stata riportata
+in RAM si potrebbe avere un page fault durante l'esecuzione della stessa, con
+conseguente rallentamento (probabilmente inaccettabile) dei tempi di
+esecuzione.
 
 In genere si ovvia a questa problematica chiamando una funzione che ha
 allocato una quantità sufficientemente ampia di variabili automatiche, in modo
 
 In genere si ovvia a questa problematica chiamando una funzione che ha
 allocato una quantità sufficientemente ampia di variabili automatiche, in modo
index 1d805c02fedc0e55c0b4fe1d48c4d60d0e4e2b5e..e57e8ca84558fd05cf2e11e27dab49b7a9eaad6b 100644 (file)
@@ -416,8 +416,8 @@ degli eventuali tempi di attesa in secondi (eseguiti tramite la funzione
 descrizione delle opzioni); il codice completo, compresa la parte che gestisce
 le opzioni a riga di comando, è disponibile nel file \file{ForkTest.c},
 distribuito insieme agli altri sorgenti degli esempi su
 descrizione delle opzioni); il codice completo, compresa la parte che gestisce
 le opzioni a riga di comando, è disponibile nel file \file{ForkTest.c},
 distribuito insieme agli altri sorgenti degli esempi su
-\href{http://firenze.linux.it/~piccardi/gapil_source.tgz}
-{\texttt{http://firenze.linux.it/\~~\hspace{-2.0mm}piccardi/gapil\_source.tgz}}.
+\href{http://gapil.firenze.linux.it/gapil_source.tgz}
+{\texttt{http://gapil.firenze.linux.it/gapil\_source.tgz}}.
 
 Decifrato il numero di figli da creare, il ciclo principale del programma
 (\texttt{\small 24--40}) esegue in successione la creazione dei processi figli
 
 Decifrato il numero di figli da creare, il ciclo principale del programma
 (\texttt{\small 24--40}) esegue in successione la creazione dei processi figli
@@ -478,8 +478,9 @@ Pertanto non si pu
 istruzioni del codice fra padre e figli, né sull'ordine in cui questi potranno
 essere messi in esecuzione. Se è necessaria una qualche forma di precedenza
 occorrerà provvedere ad espliciti meccanismi di sincronizzazione, pena il
 istruzioni del codice fra padre e figli, né sull'ordine in cui questi potranno
 essere messi in esecuzione. Se è necessaria una qualche forma di precedenza
 occorrerà provvedere ad espliciti meccanismi di sincronizzazione, pena il
-rischio di incorrere nelle cosiddette \textit{race condition} \index{race
-  condition} (vedi \secref{sec:proc_race_cond}.
+rischio di incorrere nelle cosiddette 
+\textit{race condition}\index{race condition} 
+(vedi \secref{sec:proc_race_cond}).
 
 Si noti inoltre che essendo i segmenti di memoria utilizzati dai singoli
 processi completamente separati, le modifiche delle variabili nei processi
 
 Si noti inoltre che essendo i segmenti di memoria utilizzati dai singoli
 processi completamente separati, le modifiche delle variabili nei processi
@@ -649,10 +650,10 @@ padre, che costituiva un inutile appesantimento in tutti quei casi in cui la
 \func{fork} veniva fatta solo per poi eseguire una \func{exec}. La funzione
 venne introdotta in BSD per migliorare le prestazioni.
 
 \func{fork} veniva fatta solo per poi eseguire una \func{exec}. La funzione
 venne introdotta in BSD per migliorare le prestazioni.
 
-Dato che Linux supporta il \textit{copy on write} la perdita di prestazioni è
-assolutamente trascurabile, e l'uso di questa funzione (che resta un caso
-speciale della funzione \func{clone}), è deprecato; per questo eviteremo di
-trattarla ulteriormente.
+Dato che Linux supporta il \textit{copy on write}\index{copy on write} la
+perdita di prestazioni è assolutamente trascurabile, e l'uso di questa
+funzione (che resta un caso speciale della funzione \func{clone}), è
+deprecato; per questo eviteremo di trattarla ulteriormente.
 
 
 \subsection{La conclusione di un processo.}
 
 
 \subsection{La conclusione di un processo.}
@@ -2103,11 +2104,11 @@ processo qualsiasi sia la sua priorit
   interrupt vengono intercettati dall'interfaccia real-time, e gestiti
   direttamente qualora ci sia la necessità di avere un processo con priorità
   più elevata di un \textit{interrupt handler}.} mentre con l'incorrere in un
   interrupt vengono intercettati dall'interfaccia real-time, e gestiti
   direttamente qualora ci sia la necessità di avere un processo con priorità
   più elevata di un \textit{interrupt handler}.} mentre con l'incorrere in un
-page fault si possono avere ritardi non previsti. Se l'ultimo problema può
-essere aggirato attraverso l'uso delle funzioni di controllo della memoria
-virtuale (vedi \secref{sec:proc_mem_lock}), il primo non è superabile e può
-comportare ritardi non prevedibili riguardo ai tempi di esecuzione di
-qualunque processo.
+page fault\index{page fault} si possono avere ritardi non previsti. Se
+l'ultimo problema può essere aggirato attraverso l'uso delle funzioni di
+controllo della memoria virtuale (vedi \secref{sec:proc_mem_lock}), il primo
+non è superabile e può comportare ritardi non prevedibili riguardo ai tempi di
+esecuzione di qualunque processo.
 
 In ogni caso occorre usare le priorità assolute con molta attenzione: se si dà
 ad un processo una priorità assoluta e questo finisce in un loop infinito,
 
 In ogni caso occorre usare le priorità assolute con molta attenzione: se si dà
 ad un processo una priorità assoluta e questo finisce in un loop infinito,
@@ -2355,7 +2356,8 @@ di interruzione in una fase intermedia.
 In un ambiente multitasking il concetto è essenziale, dato che un processo può
 essere interrotto in qualunque momento dal kernel che mette in esecuzione un
 altro processo o dalla ricezione di un segnale; occorre pertanto essere
 In un ambiente multitasking il concetto è essenziale, dato che un processo può
 essere interrotto in qualunque momento dal kernel che mette in esecuzione un
 altro processo o dalla ricezione di un segnale; occorre pertanto essere
-accorti nei confronti delle possibili \textit{race condition} (vedi
+accorti nei confronti delle possibili 
+\textit{race condition}\index{race condition} (vedi
 \secref{sec:proc_race_cond}) derivanti da operazioni interrotte in una fase in
 cui non erano ancora state completate.
 
 \secref{sec:proc_race_cond}) derivanti da operazioni interrotte in una fase in
 cui non erano ancora state completate.
 
@@ -2389,7 +2391,8 @@ condiviso, onde evitare problemi con le ottimizzazioni del codice.
 
 
 
 
 
 
-\subsection{Le \textit{race condition} e i \textit{deadlock}}
+\subsection{Le \textit{race condition}\index{race condition} e i 
+  \textit{deadlock}}
 \label{sec:proc_race_cond}
 
 Si definiscono \textit{race condition} tutte quelle situazioni in cui processi
 \label{sec:proc_race_cond}
 
 Si definiscono \textit{race condition} tutte quelle situazioni in cui processi
index 246c308c1f36bb0ab62cfe6ca999cdd6fdd5ed10..1ab3bd6aa8b1d9d510f83eecbc1fd3c7430cf7b2 100644 (file)
@@ -120,8 +120,8 @@ int sig_handler()
 Questa è la ragione per cui l'implementazione dei segnali secondo questa
 semantica viene chiamata \textsl{inaffidabile}; infatti la ricezione del
 segnale e la reinstallazione del suo manipolatore non sono operazioni
 Questa è la ragione per cui l'implementazione dei segnali secondo questa
 semantica viene chiamata \textsl{inaffidabile}; infatti la ricezione del
 segnale e la reinstallazione del suo manipolatore non sono operazioni
-atomiche, e sono sempre possibili delle race condition (sull'argomento vedi
-quanto detto in \secref{sec:proc_multi_prog}).
+atomiche, e sono sempre possibili delle race condition\index{race condition}
+(sull'argomento vedi quanto detto in \secref{sec:proc_multi_prog}).
 
 Un'altro problema è che in questa semantica non esiste un modo per bloccare i
 segnali quando non si vuole che arrivino; i processi possono ignorare il
 
 Un'altro problema è che in questa semantica non esiste un modo per bloccare i
 segnali quando non si vuole che arrivino; i processi possono ignorare il
@@ -242,7 +242,8 @@ Un programma pu
 \secref{sec:sig_sigaction}). Se si è installato un manipolatore sarà
 quest'ultimo ad essere eseguito alla notifica del segnale.  Inoltre il sistema
 farà si che mentre viene eseguito il manipolatore di un segnale, quest'ultimo
 \secref{sec:sig_sigaction}). Se si è installato un manipolatore sarà
 quest'ultimo ad essere eseguito alla notifica del segnale.  Inoltre il sistema
 farà si che mentre viene eseguito il manipolatore di un segnale, quest'ultimo
-venga automaticamente bloccato (così si possono evitare race condition).
+venga automaticamente bloccato (così si possono evitare race
+condition\index{race condition}).
 
 Nel caso non sia stata specificata un'azione, viene utilizzata l'azione
 standard che (come vedremo in \secref{sec:sig_standard}) è propria di ciascun
 
 Nel caso non sia stata specificata un'azione, viene utilizzata l'azione
 standard che (come vedremo in \secref{sec:sig_standard}) è propria di ciascun
@@ -411,9 +412,9 @@ tipologia, verr
 \label{sec:sig_prog_error}
 
 Questi segnali sono generati quando il sistema, o in certi casi direttamente
 \label{sec:sig_prog_error}
 
 Questi segnali sono generati quando il sistema, o in certi casi direttamente
-l'hardware (come per i page fault non validi) rileva un qualche errore
-insanabile nel programma in esecuzione. In generale la generazione di questi
-segnali significa che il programma ha dei gravi problemi (ad esempio ha
+l'hardware (come per i \textit{page fault} non validi) rileva un qualche
+errore insanabile nel programma in esecuzione. In generale la generazione di
+questi segnali significa che il programma ha dei gravi problemi (ad esempio ha
 dereferenziato un puntatore non valido o ha eseguito una operazione aritmetica
 proibita) e l'esecuzione non può essere proseguita.
 
 dereferenziato un puntatore non valido o ha eseguito una operazione aritmetica
 proibita) e l'esecuzione non può essere proseguita.
 
@@ -1472,8 +1473,9 @@ tutti gli stati di terminazione sono stati ricevuti.
 
 Le funzioni esaminate finora fanno riferimento ad alle modalità più elementari
 della gestione dei segnali; non si sono pertanto ancora prese in
 
 Le funzioni esaminate finora fanno riferimento ad alle modalità più elementari
 della gestione dei segnali; non si sono pertanto ancora prese in
-considerazione le tematiche più complesse, collegate alle varie race condition
-che i segnali possono generare e alla natura asincrona degli stessi.
+considerazione le tematiche più complesse, collegate alle varie race
+condition\index{race condition} che i segnali possono generare e alla natura
+asincrona degli stessi.
 
 Affronteremo queste problematiche in questa sezione, partendo da un esempio
 che le evidenzi, per poi prendere in esame le varie funzioni che permettono di
 
 Affronteremo queste problematiche in questa sezione, partendo da un esempio
 che le evidenzi, per poi prendere in esame le varie funzioni che permettono di
@@ -1540,13 +1542,13 @@ unsigned int sleep(unsigned int seconds)
 
 Questo codice però, a parte il non gestire il caso in cui si è avuta una
 precedente chiamata a \func{alarm} (che si è tralasciato per brevità),
 
 Questo codice però, a parte il non gestire il caso in cui si è avuta una
 precedente chiamata a \func{alarm} (che si è tralasciato per brevità),
-presenta una pericolosa race condition.  Infatti se il processo viene
-interrotto fra la chiamata di \func{alarm} e \func{pause} può capitare (ad
-esempio se il sistema è molto carico) che il tempo di attesa scada prima
-dell'esecuzione quest'ultima, cosicché essa sarebbe eseguita dopo l'arrivo di
-\macro{SIGALRM}. In questo caso ci si troverebbe di fronte ad un deadlock, in
-quanto \func{pause} non verrebbe mai più interrotta (se non in caso di un
-altro segnale).
+presenta una pericolosa race condition\index{race condition}.  Infatti se il
+processo viene interrotto fra la chiamata di \func{alarm} e \func{pause} può
+capitare (ad esempio se il sistema è molto carico) che il tempo di attesa
+scada prima dell'esecuzione quest'ultima, cosicché essa sarebbe eseguita dopo
+l'arrivo di \macro{SIGALRM}. In questo caso ci si troverebbe di fronte ad un
+deadlock, in quanto \func{pause} non verrebbe mai più interrotta (se non in
+caso di un altro segnale).
 
 Questo problema può essere risolto (ed è la modalità con cui veniva fatto in
 SVr2) usando la funzione \func{longjmp} (vedi \secref{sec:proc_longjmp}) per
 
 Questo problema può essere risolto (ed è la modalità con cui veniva fatto in
 SVr2) usando la funzione \func{longjmp} (vedi \secref{sec:proc_longjmp}) per
@@ -1650,10 +1652,10 @@ quale potr
 segnale, e prendere le relative azioni conseguenti (\texttt{\small 6-11}).
 
 Questo è il tipico esempio di caso, già citato in \secref{sec:proc_race_cond},
 segnale, e prendere le relative azioni conseguenti (\texttt{\small 6-11}).
 
 Questo è il tipico esempio di caso, già citato in \secref{sec:proc_race_cond},
-in cui si genera una race condition; se infatti il segnale arriva
-immediatamente dopo l'esecuzione del controllo (\texttt{\small 6}) ma prima
-della cancellazione del flag (\texttt{\small 7}), la sua occorrenza sarà
-perduta.
+in cui si genera una race condition\index{race condition}; se infatti il
+segnale arriva immediatamente dopo l'esecuzione del controllo (\texttt{\small
+  6}) ma prima della cancellazione del flag (\texttt{\small 7}), la sua
+occorrenza sarà perduta.
 
 Questi esempi ci mostrano che per una gestione effettiva dei segnali occorrono
 funzioni più sofisticate di quelle illustrate finora, che hanno origine dalla
 
 Questi esempi ci mostrano che per una gestione effettiva dei segnali occorrono
 funzioni più sofisticate di quelle illustrate finora, che hanno origine dalla
@@ -2048,15 +2050,15 @@ occorre ricordare che qualunque modifica alla maschera dei segnali viene
 perduta alla conclusione del terminatore. 
 
 Benché con l'uso di \func{sigprocmask} si possano risolvere la maggior parte
 perduta alla conclusione del terminatore. 
 
 Benché con l'uso di \func{sigprocmask} si possano risolvere la maggior parte
-dei casi di race condition restano aperte alcune possibilità legate all'uso di
-\func{pause}; il caso è simile a quello del problema illustrato nell'esempio
-di \secref{fig:sig_sleep_incomplete}, e cioè la possibilità che il processo
-riceva il segnale che si intende usare per uscire dallo stato di attesa
-invocato con \func{pause} immediatamente prima dell'esecuzione di
-quest'ultima. Per poter effettuare atomicamente la modifica della maschera dei
-segnali (di solito attivandone uno specifico) insieme alla sospensione del
-processo lo standard POSIX ha previsto la funzione \func{sigsuspend}, il cui
-prototipo è:
+dei casi di race condition\index{race condition} restano aperte alcune
+possibilità legate all'uso di \func{pause}; il caso è simile a quello del
+problema illustrato nell'esempio di \secref{fig:sig_sleep_incomplete}, e cioè
+la possibilità che il processo riceva il segnale che si intende usare per
+uscire dallo stato di attesa invocato con \func{pause} immediatamente prima
+dell'esecuzione di quest'ultima. Per poter effettuare atomicamente la modifica
+della maschera dei segnali (di solito attivandone uno specifico) insieme alla
+sospensione del processo lo standard POSIX ha previsto la funzione
+\func{sigsuspend}, il cui prototipo è:
 \begin{prototype}{signal.h}
 {int sigsuspend(const sigset\_t *mask)} 
   
 \begin{prototype}{signal.h}
 {int sigsuspend(const sigset\_t *mask)} 
   
@@ -2146,10 +2148,10 @@ fine (\texttt{\small 27}), e al contempo si prepara la maschera dei segnali
 \var{sleep\_mask} per riattivare \macro{SIGALRM} all'esecuzione di
 \func{sigsuspend}.  
 
 \var{sleep\_mask} per riattivare \macro{SIGALRM} all'esecuzione di
 \func{sigsuspend}.  
 
-In questo modo non sono più possibili race condition dato che \macro{SIGALRM}
-viene disabilitato con \func{sigprocmask} fino alla chiamata di
-\func{sigsuspend}. Questo metodo è assolutamente generale e può essere
-applicato a qualunque altra situazione in cui si deve attendere per un
+In questo modo non sono più possibili race condition\index{race conditionx}
+dato che \macro{SIGALRM} viene disabilitato con \func{sigprocmask} fino alla
+chiamata di \func{sigsuspend}. Questo metodo è assolutamente generale e può
+essere applicato a qualunque altra situazione in cui si deve attendere per un
 segnale, i passi sono sempre i seguenti:
 \begin{enumerate}
 \item Leggere la maschera dei segnali corrente e bloccare il segnale voluto
 segnale, i passi sono sempre i seguenti:
 \begin{enumerate}
 \item Leggere la maschera dei segnali corrente e bloccare il segnale voluto
index ced0465ec599e1b6ef9f623e0efad98413b554ce..04d92db60aecd39c7851efcc225352d34551bede 100644 (file)
@@ -1395,12 +1395,13 @@ rispettivamente il tempo impiegato dal processo nell'eseguire le istruzioni in
 user space, e quello impiegato dal kernel nelle system call eseguite per conto
 del processo.
 
 user space, e quello impiegato dal kernel nelle system call eseguite per conto
 del processo.
 
-Gli altri tre campi servono a quantificare l'uso della memoria virtuale e
-corrispondono rispettivamente al numero di \textit{page fault}\index{page
-  fault} (vedi \secref{sec:proc_mem_gen}) avvenuti senza richiedere I/O (i
-cosiddetti \textit{minor page fault}), a quelli che invece han richiesto I/O
-(detti invece \textit{major page fault}) ed al numero di volte che il processo
-è stato completamente tolto dalla memoria per essere inserito nello swap.
+Gli altri tre campi servono a quantificare l'uso della memoria
+virtuale\index{memoria virtuale} e corrispondono rispettivamente al numero di
+\textit{page fault}\index{page fault} (vedi \secref{sec:proc_mem_gen})
+avvenuti senza richiedere I/O (i cosiddetti \textit{minor page fault}), a
+quelli che invece han richiesto I/O (detti invece \textit{major page fault})
+ed al numero di volte che il processo è stato completamente tolto dalla
+memoria per essere inserito nello swap.
 
 In genere includere esplicitamente \file{<sys/time.h>} non è più necessario,
 ma aumenta la portabilità, e serve comunque quando, come nella maggior parte
 
 In genere includere esplicitamente \file{<sys/time.h>} non è più necessario,
 ma aumenta la portabilità, e serve comunque quando, come nella maggior parte
@@ -1568,12 +1569,12 @@ mantenuti attraverso una \func{exec} (vedi \secref{sec:proc_exec}).
 
 La gestione della memoria è già stata affrontata in dettaglio in
 \secref{sec:proc_memory}; abbiamo visto allora che il kernel provvede il
 
 La gestione della memoria è già stata affrontata in dettaglio in
 \secref{sec:proc_memory}; abbiamo visto allora che il kernel provvede il
-meccanismo della memoria virtuale attraverso la divisione della memoria fisica
-in pagine.
+meccanismo della memoria virtuale\index{memoria virtuale} attraverso la
+divisione della memoria fisica in pagine.
 
 In genere questo è del tutto trasparente al singolo processo, ma in certi
 
 In genere questo è del tutto trasparente al singolo processo, ma in certi
-casi, come per l'I/O mappato in memoria (vedi \ref{sec:file_memory_map}) che
-usa lo stesso meccanismo per accedere ai file, è necessario conoscere le
+casi, come per l'I/O mappato in memoria (vedi \secref{sec:file_memory_map})
+che usa lo stesso meccanismo per accedere ai file, è necessario conoscere le
 dimensioni delle pagine usate dal kernel. Lo stesso vale quando si vuole
 gestire in maniera ottimale l'interazione della memoria allocata con il
 meccanismo della paginazione.
 dimensioni delle pagine usate dal kernel. Lo stesso vale quando si vuole
 gestire in maniera ottimale l'interazione della memoria allocata con il
 meccanismo della paginazione.
@@ -1586,7 +1587,7 @@ dover fornire binari diversi per ogni possibile modello, 
 utilizzare una funzione. 
 
 In genere questa dimensione può essere ottenuta attraverso una chiamata a
 utilizzare una funzione. 
 
 In genere questa dimensione può essere ottenuta attraverso una chiamata a
-\func{sysconf} come \func{sysconf(\_SC\_PAGESIZE)}, ma in BSD 4.2 è stata
+\func{sysconf} come \code{sysconf(\_SC\_PAGESIZE)}, ma in BSD 4.2 è stata
 introdotta una apposita funzione, \func{getpagesize}, che restituisce la
 dimensione delle pagine di memoria; il suo prototipo è:
 \begin{prototype}{unistd.h}{int getpagesize(void)}
 introdotta una apposita funzione, \func{getpagesize}, che restituisce la
 dimensione delle pagine di memoria; il suo prototipo è:
 \begin{prototype}{unistd.h}{int getpagesize(void)}