Sistemati gli indici.
[gapil.git] / prochand.tex
index c005bbd5918d8a28fc0670c7e7ea1989288862f8..e57e8ca84558fd05cf2e11e27dab49b7a9eaad6b 100644 (file)
@@ -137,10 +137,12 @@ system call ed ad ogni interrupt,\footnote{pi
   occasioni. NDT completare questa parte.} (ma può essere anche attivato
 esplicitamente). Il timer di sistema provvede comunque a che esso sia invocato
 periodicamente, generando un interrupt periodico secondo la frequenza
-specificata dalla costante \macro{HZ}, definita in \file{asm/param.h}. Il
-valore usuale è 100\footnote{è così per tutte le architetture eccetto l'alpha,
-  per la quale è 1000} ed è espresso in Hertz. Si ha cioè un interrupt dal
-timer ogni centesimo di secondo.
+specificata dalla costante \macro{HZ}, definita in \file{asm/param.h}, ed il
+cui valore è espresso in Hertz.\footnote{Il valore usuale di questa costante è
+  100, per tutte le architetture eccetto l'alpha, per la quale è 1000. Occorre
+  fare attenzione a non confondere questo valore con quello dei clock tick
+  (vedi \secref{sec:sys_unix_time}).}
+%Si ha cioè un interrupt dal timer ogni centesimo di secondo.
 
 Ogni volta che viene eseguito, lo \textit{scheduler} effettua il calcolo delle
 priorità dei vari processi attivi (torneremo su questo in
@@ -377,7 +379,9 @@ int main(int argc, char *argv[])
 Normalmente la chiamata a \func{fork} può fallire solo per due ragioni, o ci
 sono già troppi processi nel sistema (il che di solito è sintomo che
 qualcos'altro non sta andando per il verso giusto) o si è ecceduto il limite
-sul numero totale di processi permessi all'utente (vedi \secref{sec:sys_xxx}).
+sul numero totale di processi permessi all'utente (vedi
+\secref{sec:sys_resource_limit}, ed in particolare
+\tabref{tab:sys_rlimit_values}).
 
 L'uso di \func{fork} avviene secondo due modalità principali; la prima è
 quella in cui all'interno di un programma si creano processi figli cui viene
@@ -412,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
-\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
@@ -474,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
-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
@@ -606,11 +611,11 @@ comune dopo l'esecuzione di una \func{fork} 
 \item la directory di lavoro e la directory radice (vedi
   \secref{sec:file_work_dir} e \secref{sec:file_chroot}).
 \item la maschera dei permessi di creazione (vedi \secref{sec:file_umask}).
-\item la maschera dei segnali bloccati (vedi \secref{sec:sig_sigpending}) e le
+\item la maschera dei segnali bloccati (vedi \secref{sec:sig_sigmask}) e le
   azioni installate (vedi \secref{sec:sig_gen_beha}).
 \item i segmenti di memoria condivisa agganciati al processo (vedi
-\secref{sec:ipc_xxx}). 
-\item i limiti sulle risorse (vedi \secref{sec:sys_xxx}).
+\secref{sec:ipc_shar_mem}). 
+\item i limiti sulle risorse (vedi \secref{sec:sys_resource_limit}).
 \item le variabili di ambiente (vedi \secref{sec:proc_environ}).
 \end{itemize*}
 le differenze fra padre e figlio dopo la \func{fork} invece sono:
@@ -619,8 +624,8 @@ le differenze fra padre e figlio dopo la \func{fork} invece sono:
 \item il \textit{process id}. 
 \item il \textit{parent process id} (quello del figlio viene settato al
   \acr{pid} del padre).
-\item i valori dei tempi di esecuzione (vedi \secref{sec:sys_xxx}) che
-  nel figlio sono posti a zero.
+\item i valori dei tempi di esecuzione della struttura \var{tms} (vedi
+  \secref{sec:sys_cpu_times}) che nel figlio sono posti a zero.
 \item i \textit{file lock} (vedi \secref{sec:file_locking}), che non
   vengono ereditati dal figlio.
 \item gli allarmi ed i segnali pendenti (vedi \secref{sec:sig_gen_beha}), che
@@ -645,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.
 
-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.}
@@ -1015,15 +1020,14 @@ sulle risorse usate dal processo terminato e dai vari figli.  I prototipi di
 queste funzioni, che diventano accessibili definendo la costante
 \macro{\_USE\_BSD}, sono:
 \begin{functions}
-  \headdecl{sys/times.h} 
-  \headdecl{sys/types.h} 
-  \headdecl{sys/wait.h}        
-  \headdecl{sys/resource.h}
+  \headdecl{sys/times.h} \headdecl{sys/types.h} \headdecl{sys/wait.h}
+  \headdecl{sys/resource.h} 
+  
   \funcdecl{pid\_t wait4(pid\_t pid, int * status, int options, struct rusage
-    * rusage)} 
-  È identica a \func{waitpid} sia per comportamento che per i
-  valori dei parametri, ma restituisce in \param{rusage} un sommario delle
-  risorse usate dal processo (per i dettagli vedi \secref{sec:sys_xxx})
+    * rusage)}   
+  È identica a \func{waitpid} sia per comportamento che per i valori dei
+  parametri, ma restituisce in \param{rusage} un sommario delle risorse usate
+  dal processo.
 
   \funcdecl{pid\_t wait3(int *status, int options, struct rusage *rusage)}
   Prima versione, equivalente a \code{wait4(-1, \&status, opt, rusage)} è
@@ -1031,16 +1035,9 @@ queste funzioni, che diventano accessibili definendo la costante
 \end{functions}
 \noindent 
 la struttura \type{rusage} è definita in \file{sys/resource.h}, e viene
-utilizzata anche dalla funzione \func{getrusage} (vedi \secref{sec:sys_xxx})
-per ottenere le risorse di sistema usate da un processo; la sua definizione è
-riportata in \figref{fig:sys_rusage_struct}.
-
-In genere includere esplicitamente \file{<sys/time.h>} non è più
-necessario, ma aumenta la portabilità, e serve in caso si debba accedere
-ai campi di \var{rusage} definiti come \type{struct timeval}. La
-struttura è ripresa da BSD 4.3, attualmente (con il kernel 2.4.x) i soli
-campi che sono mantenuti sono: \var{ru\_utime}, \var{ru\_stime},
-\var{ru\_minflt}, \var{ru\_majflt}, e \var{ru\_nswap}.
+utilizzata anche dalla funzione \func{getrusage} (vedi
+\secref{sec:sys_resource_use}) per ottenere le risorse di sistema usate da un
+processo; la sua definizione è riportata in \figref{fig:sys_rusage_struct}.
 
 
 \subsection{Le funzioni \func{exec}}
@@ -1216,10 +1213,10 @@ la lista completa 
   \secref{sec:file_umask}) ed i \textit{lock} sui file (vedi
   \secref{sec:file_locking}).
 \item i segnali sospesi (\textit{pending}) e la maschera dei segnali (si veda
-  \secref{sec:sig_sigpending}).
-\item i limiti sulle risorse (vedi \secref{sec:sys_limits}).
+  \secref{sec:sig_sigmask}).
+\item i limiti sulle risorse (vedi \secref{sec:sys_resource_limit}).
 \item i valori delle variabili \var{tms\_utime}, \var{tms\_stime},
-  \var{tms\_cutime}, \var{tms\_ustime} (vedi \secref{sec:xxx_xxx}).
+  \var{tms\_cutime}, \var{tms\_ustime} (vedi \secref{sec:sys_cpu_times}).
 \end{itemize*}
 
 Inoltre i segnali che sono stati settati per essere ignorati nel processo
@@ -1858,11 +1855,11 @@ semplicemente l'allocazione della risorsa \textsl{tempo di esecuzione}, la cui
 assegnazione sarà governata dai meccanismi di scelta delle priorità che
 restano gli stessi indipendentemente dal numero di processori.
 
-I processi non devono solo eseguire del codice, ad esempio molto spesso
-saranno impegnati in operazioni di I/O, possono venire bloccati da un comando
-dal terminale, sospesi per un certo periodo di tempo. In tutti questi casi la
-CPU diventa disponibile ed è compito dello kernel provvedere a mettere in
-esecuzione un altro processo.
+Si tenga conto poi che i processi non devono solo eseguire del codice: ad
+esempio molto spesso saranno impegnati in operazioni di I/O, o potranno
+venire bloccati da un comando dal terminale, o sospesi per un certo periodo di
+tempo.  In tutti questi casi la CPU diventa disponibile ed è compito dello
+kernel provvedere a mettere in esecuzione un altro processo.
 
 Tutte queste possibilità sono caratterizzate da un diverso \textsl{stato} del
 processo, in Linux un processo può trovarsi in uno degli stati riportati in
@@ -1892,7 +1889,7 @@ fintanto che esso si trova in uno qualunque degli altri stati.
     \hline
   \end{tabular}
   \caption{Elenco dei possibili stati di un processo in Linux, nella colonna
-    \texttt{STAT} si è riportata la corripondente lettera usata dal comando 
+    \texttt{STAT} si è riportata la corrispondente lettera usata dal comando 
     \cmd{ps} nell'omonimo campo.}
   \label{tab:proc_proc_states}
 \end{table}
@@ -2019,7 +2016,7 @@ funzione \func{getpriority}, derivata da BSD, il cui prototipo 
 \begin{prototype}{sys/resource.h}
 {int getpriority(int which, int who)}
   
-  Restituisce la priorità per l'insieme dei processi specificati.
+Restituisce il valore di \var{nice} per l'insieme dei processi specificati.
 
   \bodydesc{La funzione ritorna la priorità in caso di successo e -1 in caso di
     errore, nel qual caso \var{errno} può assumere i valori:
@@ -2084,12 +2081,12 @@ settare la priorit
 \end{prototype}
 
 La funzione setta la priorità al valore specificato da \param{prio} per tutti
-i processi indicati dagli argomenti \parm{which} e \param{who}.  La gestione
+i processi indicati dagli argomenti \param{which} e \param{who}.  La gestione
 dei permessi dipende dalle varie implementazioni; in Linux, secondo le
 specifiche dello standard SUSv3, e come avviene per tutti i sistemi che
 derivano da SYSV, è richiesto che il real o l'effective user id del processo
 chiamante corrispondano al real user id (e solo quello) del processo di cui si
-vuole cambiare la prorità; per i sistemi derivati da BSD invece (SunOS,
+vuole cambiare la priorità; per i sistemi derivati da BSD invece (SunOS,
 Ultrix, *BSD) la corrispondenza può essere anche con l'effective user id.
 
 
@@ -2097,20 +2094,239 @@ Ultrix, *BSD) la corrispondenza pu
 \subsection{Il meccanismo di \textit{scheduling real-time}}
 \label{sec:proc_real_time}
 
-
 Come spiegato in \secref{sec:proc_sched} lo standard POSIX.1b ha introdotto le
-priorità assolute per permettere la gestione di processi real-time; benché
-Linux non sia un sistema operativo real-time,\footnote{a meno che non si siano
-  installate le patch di RTLinux o RTAI, con i quali è possibile ottenere un
-  sistema effettivamente hard real-time.} è stata comunque implementata anche
-una politica di scheduling corrispondente a questo meccanismo.
+priorità assolute per permettere la gestione di processi real-time. In realtà
+nel caso di Linux non si tratta di un vero hard real-time, in quanto in
+presenza di eventuali interrupt il kernel interrompe l'esecuzione di un
+processo qualsiasi sia la sua priorità,\footnote{questo a meno che non si
+  siano installate le patch di RTLinux o RTAI, con i quali è possibile
+  ottenere un sistema effettivamente hard real-time. In tal caso infatti gli
+  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\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,
+nessun altro processo potrà essere eseguito, ed esso sarà mantenuto in
+esecuzione permanentemente assorbendo tutta la CPU e senza nessuna possibilità
+di riottenere l'accesso al sistema. Per questo motivo è sempre opportuno,
+quando si lavora con processi che usano priorità assolute, tenere attiva una
+shell cui si sia assegnata la massima priorità assoluta, in modo da poter
+essere comunque in grado di rientrare nel sistema.
+
+Quando c'è un processo con priorità assoluta lo scheduler lo metterà in
+esecuzione prima di ogni processo normale. In caso di più processi sarà
+eseguito per primo quello con priorità assoluta più alta. Quando ci sono più
+processi con la stessa priorità assoluta questi vengono tenuti in una coda
+tocca al kernel decidere quale deve essere eseguito. 
+
+
+
+Il meccanismo con cui vengono gestiti questi processi dipende dalla politica
+di scheduling che si è scelto; lo standard ne prevede due:
+\begin{basedescript}{\desclabelwidth{3cm}\desclabelstyle{\nextlinelabel}}
+\item[\textit{FIFO}] il processo viene eseguito fintanto che non cede
+  volontariamente la CPU, si blocca, finisce o viene interrotto da un processo
+  a priorità più alta.
+\item[\textit{Round Robin}] ciascun processo viene eseguito a turno per un
+  certo periodo di tempo (una \textit{time slice}). Solo i processi con la
+  stessa priorità ed in stato \textit{runnable} entrano nel circolo.
+\end{basedescript}
+
+La funzione per settare le politiche di scheduling (sia real-time che
+ordinarie) ed i relativi parametri è \func{sched\_setscheduler}; il suo
+prototipo è:
+\begin{prototype}{sched.h}
+{int sched\_setscheduler(pid\_t pid, int policy, const struct sched\_param *p)}
+  Setta priorità e politica di scheduling per il processo \param{pid}.
+
+  \bodydesc{La funzione ritorna la priorità in caso di successo e -1 in caso di
+    errore, nel qual caso \var{errno} può assumere i valori:
+    \begin{errlist}
+    \item[\macro{ESRCH}] il processo \param{pid} non esiste.
+    \item[\macro{EINVAL}] il valore di \param{policy} non esiste o il relativo
+      valore di \param{p} non è valido.
+    \item[\macro{EPERM}] il processo non ha i privilegi per attivare la
+      politica richiesta (vale solo per \macro{SCHED\_FIFO} e
+      \macro{SCHED\_RR}).
+  \end{errlist}}
+\end{prototype}
+
+La funzione esegue il settaggio per il processo specificato; un valore nullo
+di \param{pid} esegue il settaggio per il processo corrente, solo un processo
+con i privilegi di amministratore può settare delle priorità assolute diverse
+da zero. La politica di scheduling è specificata dall'argomento \param{policy}
+i cui possibili valori sono riportati in \tabref{tab:proc_sched_policy}; un
+valore negativo per \param{policy} mantiene la politica di scheduling
+corrente.
+
+\begin{table}[htb]
+  \centering
+  \footnotesize
+  \begin{tabular}[c]{|c|l|}
+    \hline
+    \textbf{Policy}  & \textbf{Significato} \\
+    \hline
+    \hline
+    \macro{SCHED\_FIFO} & Scheduling real-time con politica \textit{FIFO} \\
+    \macro{SCHED\_RR}   & Scheduling real-time con politica \textit{Round
+    Robin} \\
+    \macro{SCHED\_OTHER}& Scheduling ordinario\\
+    \hline
+  \end{tabular}
+  \caption{Valori dell'argomento \param{policy}  per la funzione
+    \func{sched\_setscheduler}. }
+  \label{tab:proc_sched_policy}
+\end{table}
+
+Il valore della priorità è passato attraverso la struttura \var{sched\_param}
+(riportata in \figref{fig:sig_sched_param}), il cui solo campo attualmente
+definito è \var{sched\_priority}, che nel caso delle priorità assolute deve
+essere specificato nell'intervallo fra 1 e 99 (il valore zero è legale, ma
+indica i processi normali). Lo standard POSIX.1b prevede comunque che questi
+due valori possano essere ottenuti per ciascuna politica di scheduling dalle
+funzioni \func{sched\_get\_priority\_max} e \func{sched\_get\_priority\_min},
+i cui prototipi sono:
+\begin{functions}
+  \headdecl{sched.h}
+  
+  \funcdecl{int sched\_get\_priority\_max(int policy)} Legge il valore
+  massimo della priorità statica per la politica di scheduling \param{policy}.
+
+  
+  \funcdecl{int sched\_get\_priority\_min(int policy)} Legge il valore minimo
+  della priorità statica per la politica di scheduling \param{policy}.
+  
+  \bodydesc{La funzioni ritornano il valore della priorità in caso di successo
+    e -1 in caso di errore, nel qual caso \var{errno} può assumere i valori:
+    \begin{errlist}
+    \item[\macro{EINVAL}] il valore di \param{policy} è invalido.
+  \end{errlist}}
+\end{functions}
 
-In realtà non si tratta di un vero hard real-time, in quanto la presenza di
-eventuali interrupt o di page fault può sempre interrompere l'esecuzione di un
-processo, in questo modo comunque si potrà dare .
 
+I processi con politica di scheduling \macro{SCHED\_OTHER} devono specificare
+un valore nullo (altrimenti si avrà un errore \macro{EINVAL}), questo valore
+infatti non ha niente a che vedere con la priorità dinamica determinata dal
+valore di \var{nice}, che deve essere settato con le funzioni viste in
+precedenza.
 
+\begin{figure}[!htb]
+  \footnotesize \centering
+  \begin{minipage}[c]{15cm}
+    \begin{lstlisting}[labelstep=0]{}%,frame=,indent=1cm]{}
+struct sched_param {
+    int sched_priority;
+};
+    \end{lstlisting}
+  \end{minipage} 
+  \normalsize 
+  \caption{La struttura \var{sched\_param}.} 
+  \label{fig:sig_sched_param}
+\end{figure}
+
+Il kernel mantiene i processi con la stessa priorità assoluta in una lista, ed
+esegue sempre il primo della lista, mentre un nuovo processo che torna in
+stato \textit{runnable} viene sempre inserito in coda alla lista. Se la
+politica scelta è \macro{SCHED\_FIFO} quando il processo viene eseguito viene
+automaticamente rimesso in coda alla lista, e la sua esecuzione continua
+fintanto che non viene bloccato da una richiesta di I/O, o non rilascia
+volontariamente la CPU (in tal caso, tornando nello stato \textit{runnable}
+sarà reinserito in coda alla lista); l'esecuzione viene ripresa subito solo
+nel caso che esso sia stato interrotto da un processo a priorità più alta.
+
+La priorità assoluta può essere riletta indietro dalla funzione
+\func{sched\_getscheduler}, il cui prototipo è:
+\begin{prototype}{sched.h}
+{int sched\_getscheduler(pid\_t pid)}
+  Legge la politica di scheduling per il processo \param{pid}.
+  
+  \bodydesc{La funzione ritorna la politica di scheduling in caso di successo
+    e -1 in caso di errore, nel qual caso \var{errno} può assumere i valori:
+    \begin{errlist}
+    \item[\macro{ESRCH}] il processo \param{pid} non esiste.
+    \item[\macro{EINVAL}] il valore di \param{pid} è negativo.
+  \end{errlist}}
+\end{prototype}
+
+La funzione restituisce il valore (secondo la quanto elencato in
+\tabref{tab:proc_sched_policy}) della politica di scheduling per il processo
+specificato; se \param{pid} è nullo viene restituito quello del processo
+chiamante.
+
+Se si intende operare solo sulla priorità assoluta di un processo si possono
+usare le funzioni \func{sched\_setparam} e \func{sched\_getparam}, i cui
+prototipi sono:
+  
+\begin{functions}
+  \headdecl{sched.h}
+
+  \funcdecl{int sched\_setparam(pid\_t pid, const struct sched\_param *p)}
+  Setta la priorità assoluta del processo \param{pid}.
+
+
+  \funcdecl{int sched\_getparam(pid\_t pid, struct sched\_param *p)}
+  Legge la priorità assoluta del processo \param{pid}.
+
+  \bodydesc{La funzione ritorna la priorità  in caso di successo
+    e -1 in caso di errore, nel qual caso \var{errno} può assumere i valori:
+    \begin{errlist}
+    \item[\macro{ESRCH}] il processo \param{pid} non esiste.
+    \item[\macro{EINVAL}] il valore di \param{pid} è negativo.
+  \end{errlist}}
+\end{functions}
+
+L'uso di \func{sched\_setparam} che è del tutto equivalente a
+\func{sched\_setscheduler} con \param{priority} uguale a -1. Come per
+\func{sched\_setscheduler} specificando 0 come valore di \param{pid} si opera
+sul processo corrente. La disponibilità di entrambe le funzioni può essere
+verificata controllando la macro \macro{\_POSIX\_PRIORITY\_SCHEDULING} che è
+definita nell'header \macro{sched.h}.
+
+L'ultima funzione che permette di leggere le informazioni relative ai processi
+real-time è \func{sched\_rr\_get\_interval}, che permette di ottenere la
+lunghezza della \textit{time slice} usata dalla politica \textit{round robin};
+il suo prototipo è:
+\begin{prototype}{sched.h}
+  {int sched\_rr\_get\_interval(pid\_t pid, struct timespec *tp)} Legge in
+  \param{tp} la durata della \textit{time slice} per il processo \param{pid}.
+  
+  \bodydesc{La funzione ritorna 0in caso di successo e -1 in caso di errore,
+    nel qual caso \var{errno} può assumere i valori:
+    \begin{errlist}
+    \item[\macro{ESRCH}] il processo \param{pid} non esiste.
+    \item[\macro{ENOSYS}] la system call non è stata implementata.
+  \end{errlist}}
+\end{prototype}
+
+La funzione restituisce il valore dell'intervallo di tempo usato per la
+politica \textit{round robin} in una struttura \var{timespec}, (la cui
+definizione si può trovare in \figref{fig:sys_timeval_struct}).
+
+
+Come accennato ogni processo che usa lo scheduling real-time può rilasciare
+volontariamente la CPU; questo viene fatto attraverso la funzione
+\func{sched\_yield}, il cui prototipo è:
+\begin{prototype}{sched.h}
+  {int sched\_yield(void)} 
+  
+  Rilascia volontariamente l'esecuzione.
+  
+  \bodydesc{La funzione ritorna 0 in caso di successo e -1 in caso di errore,
+    nel qual caso \var{errno} viene settata opportunamente.}
+\end{prototype}
 
+La funzione fa si che il processo rilasci la CPU, in modo da essere rimesso in
+coda alla lista dei processi da eseguire, e permettere l'esecuzione di un
+altro processo; se però il processo è l'unico ad essere presente sulla coda
+l'esecuzione non sarà interrotta. In genere usano questa funzione i processi
+in modalità \textit{fifo}, per permettere l'esecuzione degli altri processi
+con pari priorità quando la sezione più urgente è finita.
 
 
 \section{Problematiche di programmazione multitasking}
@@ -2140,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
-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.
 
@@ -2174,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