Completata revisione del capitolo sulla gestione dei processi.
authorSimone Piccardi <piccardi@gnulinux.it>
Sat, 7 Jan 2012 20:48:04 +0000 (20:48 +0000)
committerSimone Piccardi <piccardi@gnulinux.it>
Sat, 7 Jan 2012 20:48:04 +0000 (20:48 +0000)
process.tex
prochand.tex
signal.tex

index c7c6756c22454091f1059b18659e8e1273ce2fac..5e5fa6e55f8ff76ec56905945a01656994077e57 100644 (file)
@@ -904,7 +904,7 @@ rispettivi prototipi sono:
 }
 {Entrambe le funzioni restituiscono il puntatore alla zona di memoria allocata
 in caso di successo e \val{NULL} in caso di fallimento, nel qual caso
-  \var{errno} assumerà il valore \errval{ENOMEM}.}
+  \var{errno} assumerà il valore \errcode{ENOMEM}.}
 \end{funcproto}
 
 In genere si usano \func{malloc} e \func{calloc} per allocare dinamicamente
@@ -968,7 +968,7 @@ suo prototipo è:
 \fdesc{Cambia la dimensione di un'area di memoria precedentemente allocata.}
 }  {La funzione ritorna il puntatore alla zona di memoria allocata in caso
   di successo e \val{NULL} per un errore, nel qual caso \var{errno}
-  assumerà il valore \errval{ENOMEM}.}
+  assumerà il valore \errcode{ENOMEM}.}
 \end{funcproto}
 
 La funzione vuole come primo argomento il puntatore restituito da una
@@ -1155,7 +1155,7 @@ prototipo è:
 \fdesc{Sposta la fine del segmento dati del processo.} 
 }
 {La funzione ritorna $0$ in caso di successo e $-1$ per un errore,
-  nel qual caso \var{errno} assumerà il valore \errval{ENOMEM}.}
+  nel qual caso \var{errno} assumerà il valore \errcode{ENOMEM}.}
 \end{funcproto}
 
 La funzione è un'interfaccia all'omonima \textit{system call} ed imposta
@@ -1186,7 +1186,7 @@ Una seconda funzione per la manipolazione diretta delle dimensioni
 }
 {La funzione ritorna il puntatore all'inizio della nuova zona di memoria
   allocata in caso di successo e \val{NULL} per un errore, nel qual
-  caso \var{errno} assumerà il valore \errval{ENOMEM}.}
+  caso \var{errno} assumerà il valore \errcode{ENOMEM}.}
 \end{funcproto}
 
 La funzione incrementa la dimensione dello \itindex{heap} \textit{heap} di un
index 1683f0a0b24689d64beb220d381b9b94c1b766cb..d2b4391dcdbb637decd39a3e7eeb40a153d5f560 100644 (file)
@@ -1302,8 +1302,8 @@ basta dire che al ritorno di \func{waitid} verranno avvalorati i seguenti
 campi:
 \begin{basedescript}{\desclabelwidth{2.0cm}}
 \item[\var{si\_pid}] con il \acr{pid} del figlio.
-\item[\var{si\_uid}] con l'user-ID reale (vedi sez.~\ref{sec:proc_perms}) del
-  figlio.
+\item[\var{si\_uid}] con l'\textsl{user-ID reale} (vedi
+  sez.~\ref{sec:proc_perms}) del figlio.
 \item[\var{si\_signo}] con \signal{SIGCHLD}.
 \item[\var{si\_status}] con lo stato di uscita del figlio o con il segnale che
   lo ha terminato, fermato o riavviato.
@@ -1809,13 +1809,13 @@ funzioni di lettura, queste sono \funcd{getuid}, \funcd{geteuid},
 \fhead{unistd.h}
 \fhead{sys/types.h}
 \fdecl{uid\_t getuid(void)}
-\fdesc{Legge l'\textsl{user-ID reale} del processo corrente.} 
+\fdesc{Legge l'\acr{uid} reale del processo corrente.} 
 \fdecl{uid\_t geteuid(void)}
-\fdesc{Legge l'\textsl{user-ID effettivo} del processo corrente.} 
+\fdesc{Legge l'\acr{uid} effettivo del processo corrente.} 
 \fdecl{gid\_t getgid(void)}
-\fdesc{Legge il \textsl{group-ID reale} del processo corrente.} 
+\fdesc{Legge il \acr{gid} reale del processo corrente.} 
 \fdecl{gid\_t getegid(void)}
-\fdesc{Legge il \textsl{group-ID effettivo} del processo corrente.}
+\fdesc{Legge il \acr{gid} effettivo del processo corrente.}
 }
 {Le funzioni ritornano i rispettivi identificativi del processo corrente, e
   non sono previste condizioni di errore.}
@@ -1866,8 +1866,8 @@ Le due funzioni più comuni che vengono usate per cambiare identità (cioè
 utente e gruppo di appartenenza) ad un processo sono rispettivamente
 \funcd{setuid} e \funcd{setgid}; come accennato in
 sez.~\ref{sec:proc_access_id} in Linux esse seguono la semantica POSIX che
-prevede l'esistenza dell'\textit{user-ID salvato} e del \textit{group-ID
-  salvato}; i loro prototipi sono:
+prevede l'esistenza dell'\acr{uid} salvato e del \acr{gid} salvato; i loro
+prototipi sono:
 
 \begin{funcproto}{ 
 \fhead{unistd.h}
@@ -1878,7 +1878,7 @@ prevede l'esistenza dell'\textit{user-ID salvato} e del \textit{group-ID
 \fdesc{Imposta il \acr{gid} del processo corrente.} 
 }
 {Le funzioni ritornano $0$ in caso di successo e $-1$ per un errore, nel qual
-caso \var{errno} può assumere solo il valore \errval{EPERM}.
+caso \var{errno} può assumere solo il valore \errcode{EPERM}.
 }
 \end{funcproto}
 
@@ -1955,7 +1955,7 @@ i privilegi di amministratore, in tal caso infatti l'esecuzione di una
 processo, rendendo impossibile riguadagnare i privilegi di amministratore.
 Questo comportamento è corretto per l'uso che ne fa \cmd{login} una volta che
 crea una nuova shell per l'utente, ma quando si vuole cambiare soltanto
-l'\textsl{user-ID effettivo} del processo per cedere i privilegi occorre
+l'\acr{uid} effettivo del processo per cedere i privilegi occorre
 ricorrere ad altre funzioni.
 
 Le due funzioni \funcd{setreuid} e \funcd{setregid} derivano da BSD che, non
@@ -1972,7 +1972,7 @@ supportando (almeno fino alla versione 4.3+BSD) gli identificatori del gruppo
 \fdesc{Imposta \acr{gid} reale e \acr{gid} effettivo del processo corrente.} 
 }
 {Le funzioni ritornano $0$ in caso di successo e $-1$ per un errore, nel qual
-caso \var{errno} può assumere solo il valore \errval{EPERM}.
+caso \var{errno} può assumere solo il valore \errcode{EPERM}.
 }
 \end{funcproto}
 
@@ -2024,7 +2024,7 @@ Unix, esse vengono usate per cambiare gli identificatori del gruppo
 \fdesc{Imposta il \acr{gid} effettivo del processo corrente.} 
 }
 {Le funzioni ritornano $0$ in caso di successo e $-1$ per un errore, nel qual
-caso \var{errno} può assumere solo il valore \errval{EPERM}.
+caso \var{errno} può assumere solo il valore \errcode{EPERM}.
 }
 \end{funcproto}
 
@@ -2051,7 +2051,7 @@ un completo controllo su tutti e tre i gruppi di identificatori
 \fdesc{Imposta il \acr{gid} reale, effettivo e salvato del processo corrente.} 
 }
 {Le funzioni ritornano $0$ in caso di successo e $-1$ per un errore, nel qual
-caso \var{errno} può assumere solo il valore \errval{EPERM}.
+caso \var{errno} può assumere solo il valore \errcode{EPERM}.
 }
 \end{funcproto}
 
@@ -2082,7 +2082,7 @@ identificatori; i loro prototipi sono:
 \fdesc{Legge il \acr{gid} reale, effettivo e salvato del processo corrente.} 
 }
 {Le funzioni ritornano $0$ in caso di successo e $-1$ per un errore, nel qual
-  caso \var{errno} può assumere solo il valore \errval{EFAULT} se gli
+  caso \var{errno} può assumere solo il valore \errcode{EFAULT} se gli
   indirizzi delle variabili di ritorno non sono validi.  }
 \end{funcproto}
 
@@ -2648,7 +2648,7 @@ nella distribuzione della CPU ai processi. Infatti se viene comunque calcolata
 una priorità dinamica per i processi che non ricevono la CPU così che anche
 essi possano essere messi in esecuzione, un alto valore di \textit{nice}
 corrisponde comunque ad una \textit{time-slice} molto piccola che non cresce
-comunque, per cui un processo a bassa priorità avra davvero scarse possibilità
+comunque, per cui un processo a bassa priorità avrà davvero scarse possibilità
 di essere eseguito in presenza di processi attivi a priorità più alta.
 
 
@@ -2913,7 +2913,7 @@ caso \var{errno} assumerà uno dei valori:
 \end{funcproto}
 
 Le funzioni richiedono di indicare nell'argomento \param{pid} il processo su
-cui operare e usano l'argomento \param{param} per mantenre il valore della
+cui operare e usano l'argomento \param{param} per mantenere il valore della
 priorità dinamica. Questo è ancora una struttura \struct{sched\_param} ed
 assume gli stessi valori già visti per \func{sched\_setscheduler}.
 
@@ -3089,9 +3089,11 @@ che permette di impostare su quali processori far eseguire un determinato
 processo attraverso una \textsl{maschera di affinità}. La corrispondente
 funzione di libreria è \funcd{sched\_setaffinity} ed il suo prototipo è:
 
+\index{insieme~di~processori|(}
+
 \begin{funcproto}{ 
 \fhead{sched.h}
-\fdecl{int sched\_setaffinity (pid\_t pid, size\_t cpusetsize, 
+\fdecl{int sched\_setaffinity (pid\_t pid, size\_t setsize, 
   cpu\_set\_t *mask)}
 \fdesc{Imposta la maschera di affinità di un processo.} 
 }
@@ -3133,9 +3135,9 @@ questa viene ereditata attraverso una \func{fork}, in questo modo diventa
 possibile legare automaticamente un gruppo di processi ad un singolo
 processore.
 
-Nell'uso comune, almeno con i kernel della serie 2.6.x, l'uso di questa
-funzione non è necessario, in quanto è lo scheduler stesso che provvede a
-mantenere al meglio l'affinità di processore. Esistono però esigenze
+Nell'uso comune, almeno con i kernel successivi alla serie 2.6.x, l'uso di
+questa funzione non è necessario, in quanto è lo scheduler stesso che provvede
+mantenere al meglio l'affinità di processore. Esistono però esigenze
 particolari, ad esempio quando un processo (o un gruppo di processi) è
 utilizzato per un compito importante (ad esempio per applicazioni
 \textit{real-time} o la cui risposta è critica) e si vuole la massima
@@ -3155,54 +3157,164 @@ serializzati nell'accesso ad una risorsa) possono esserci sufficienti vantaggi
 nell'evitare la perdita della cache da rendere conveniente l'uso dell'affinità
 di processore.
 
-Per facilitare l'uso dell'argomento \param{mask} le \acr{glibc} hanno
-introdotto un apposito dato di tipo, \type{cpu\_set\_t},\footnote{questa è una
-  estensione specifica delle \acr{glibc}, da attivare definendo la macro
+Dato che il numero di processori può variare a seconda delle architetture, per
+semplificare l'uso dell'argomento \param{mask} le \acr{glibc} hanno introdotto
+un apposito dato di tipo, \type{cpu\_set\_t},\footnote{questa è una estensione
+  specifica delle \acr{glibc}, da attivare definendo la macro
   \macro{\_GNU\_SOURCE}, non esiste infatti una standardizzazione per questo
   tipo di interfaccia e POSIX al momento non prevede nulla al riguardo.} che
-permette di identificare un insieme di processori. Il dato è una maschera
-binaria: in generale è un intero a 32 bit in cui ogni bit corrisponde ad un
-processore, ma dato che per architetture particolari il numero di bit di un
-intero può non essere sufficiente, è stata creata questa che è una interfaccia
-generica che permette di usare a basso livello un tipo di dato qualunque
-rendendosi indipendenti dal numero di bit e dalla loro disposizione.
-
-Questa interfaccia, oltre alla definizione del tipo di dato apposito, prevede
-anche una serie di macro di preprocessore per la manipolazione dello stesso,
-che consentono di svuotare un insieme, aggiungere o togliere un processore da
-esso o verificare se vi è già presente:
+permette di identificare un insieme di processori. Il dato è normalmente una
+maschera binaria: nei casi più comuni potrebbe bastare un intero a 32 bit, in
+cui ogni bit corrisponde ad un processore, ma oggi esistono architetture in
+cui questo numero può non essere sufficiente, e per questo è stato creato
+questo \itindex{tipo!opaco} tipo opaco e una interfaccia di gestione che
+permette di usare a basso livello un tipo di dato qualunque rendendosi
+indipendenti dal numero di bit e dalla loro disposizione.  Per questo le
+funzioni richiedono anche che oltre all'insieme di processori si indichi anche
+la dimensione dello stesso con l'argomento \param{setsize}, per il quale,
+se non si usa l'allocazione dinamica che vedremo a breve, ed è in genere
+sufficiente passare il valore \code{sizeof(cpu\_set\_t)}.
+
+L'interfaccia di gestione degli insiemi di processori, oltre alla definizione
+del tipo \type{cpu\_set\_t}, prevede una serie di macro di preprocessore per
+la manipolazione degli stessi. Quelle di base, che consentono rispettivamente
+di svuotare un insieme, di aggiungere o togliere un processore o di verificare
+se esso è già presente in un insieme, sono le seguenti:
 
 {\centering
 \vspace{3pt}
 \begin{funcbox}{ 
 \fhead{sched.h}
 \fdecl{void \macro{CPU\_ZERO}(cpu\_set\_t *set)}
-\fdesc{Inizializza l'insieme vuoto \param{set}.} 
+\fdesc{Inizializza un insieme di processori vuoto \param{set}.} 
 \fdecl{void \macro{CPU\_SET}(int cpu, cpu\_set\_t *set)}
-\fdesc{Inserisce il processore \param{cpu} nell'insieme \param{set}.} 
+\fdesc{Inserisce il processore \param{cpu} nell'insieme di processori \param{set}.} 
 \fdecl{void \macro{CPU\_CLR}(int cpu, cpu\_set\_t *set)}
-\fdesc{Rimuove il processore \param{cpu} nell'insieme \param{set}.} 
+\fdesc{Rimuove il processore \param{cpu} nell'insieme di processori \param{set}.} 
 \fdecl{int \macro{CPU\_ISSET}(int cpu, cpu\_set\_t *set)}
-\fdesc{Controlla se il processore \param{cpu} è nell'insieme \param{set}.} 
+\fdesc{Controlla se il processore \param{cpu} è nell'insieme di processori \param{set}.} 
+}
+\end{funcbox}}
+
+Queste macro che sono ispirate dalle analoghe usate per gli insiemi di
+\textit{file descriptor} (vedi sez.~\ref{sec:file_select}) e sono state
+introdotte con la versione 2.3.3 della \acr{glibc}. Tutte richiedono che si
+specifichi il numero di una CPU nell'argomento \param{cpu}, ed un insieme su
+cui operare. L'unica che ritorna un risultato è \macro{CPU\_ISSET}, che
+restituisce un intero da usare come valore logico (zero se la CPU non è
+presente, diverso da zero se è presente).
+
+Si tenga presente che trattandosi di macro l'argomento \param{cpu} può essere
+valutato più volte. Questo significa ad esempio che non si può usare al suo
+posto una funzione o un'altra macro, altrimenti queste verrebbero eseguite più
+volte, l'argomento cioè non deve avere \textsl{effetti collaterali} (in gergo
+\itindex{side!effects} \textit{side effects}).\footnote{nel linguaggio C si
+  parla appunto di \textit{side effects} quando si usano istruzioni la cui
+  valutazione comporta effetti al di fuori dell'istruzione stessa, come il
+  caso indicato in cui si passa una funzione ad una macro che usa l'argomento
+  al suo interno più volte, o si scrivono espressioni come \code{a=a++} in cui
+  non è chiaro se prima avvenga l'incremento e poi l'assegnazione, ed il cui
+  risultato dipende dall'implementazione del compilatore.}
+
+Le CPU sono numerate da zero (che indica la prima disponibile) fino ad
+un numero massimo che dipende dalla architettura hardware. La costante
+\const{CPU\_SETSIZE} indica il numero massimo di processori che possono far
+parte di un insieme (al momento vale sempre 1024), e costituisce un limite
+massimo al valore dell'argomento \param{cpu}.
+Dalla versione 2.6 della \acr{glibc} alle precedenti macro è stata aggiunta,
+per contare il numero di processori in un insieme, l'ulteriore:
+
+{\centering
+\vspace{3pt}
+\begin{funcbox}{ 
+\fhead{sched.h}
+\fdecl{int \macro{CPU\_COUNT}(cpu\_set\_t *set)}
+\fdesc{Conta il numero di processori presenti nell'insieme \param{set}.} 
+}
+\end{funcbox}}
+
+A partire dalla versione 2.7 della \acr{glibc} sono state introdotte altre
+macro che consentono ulteriori manipolazioni, in particolare si possono
+compiere delle operazioni logiche sugli insiemi di processori con:
+
+{\centering
+\vspace{3pt}
+\begin{funcbox}{ 
+\fhead{sched.h}
+\fdecl{void \macro{CPU\_AND}(cpu\_set\_t *destset, cpu\_set\_t *srcset1, cpu\_set\_t *srcset2)}
+\fdesc{Esegue l'AND logico di due insiemi di processori.} 
+\fdecl{void \macro{CPU\_OR}(cpu\_set\_t *destset, cpu\_set\_t *srcset1, cpu\_set\_t *srcset2)}
+\fdesc{Esegue l'OR logico di due insiemi di processori.} 
+\fdecl{void \macro{CPU\_XOR}(cpu\_set\_t *destset, cpu\_set\_t *srcset1, cpu\_set\_t *srcset2)}
+\fdesc{Esegue lo XOR logico di due insiemi di processori.} 
+\fdecl{int \macro{CPU\_EQUAL}(cpu\_set\_t *set1, cpu\_set\_t *set2)}
+\fdesc{Verifica se due insiemi di processori sono uguali.} 
 }
 \end{funcbox}}
 
-% TODO trattare le altre 
+Le prime tre macro richiedono due insiemi di partenza, \param{srcset1}
+e \param{srcset2} e forniscono in un terzo insieme \param{destset} (che può
+essere anche lo stesso di uno dei precedenti) il risultato della rispettiva
+operazione logica sui contenuti degli stessi. In sostanza con \macro{CPU\_AND}
+si otterrà come risultato l'insieme che contiene le CPU presenti in entrambi
+gli insiemi di partenza, con \macro{CPU\_OR} l'insieme che contiene le CPU
+presenti in uno qualunque dei due insiemi di partenza, e con \macro{CPU\_XOR}
+l'insieme che contiene le CPU presenti presenti in uno solo dei due insiemi di
+partenza. Infine \macro{CPU\_EQUAL} confronta due insiemi ed è l'unica che
+restituisce un intero, da usare come valore logico che indica se sono
+identici o meno.
+
+Inoltre, sempre a partire dalla versione 2.7 della \acr{glibc}, è stata
+introdotta la possibilità di una allocazione dinamica degli insiemi di
+processori, per poterli avere di dimensioni corrispondenti al numero di CPU
+effettivamente in gioco, senza dover fare riferimento necessariamente alla
+precedente dimensione preimpostata di 1024. Per questo motivo sono state
+definite tre ulteriori macro, che consentono rispettivamente di allocare,
+disallocare ed ottenere la dimensione in byte di un insieme di processori:
 
-Oltre a queste macro, simili alle analoghe usate per gli insiemi di
-\textit{file descriptor} (vedi sez.~\ref{sec:file_select}) è definita la
-costante \const{CPU\_SETSIZE} che indica il numero massimo di processori che
-possono far parte dell'insieme, e che costituisce un limite massimo al valore
-dell'argomento \param{cpu}.
+{\centering
+\vspace{3pt}
+\begin{funcbox}{ 
+\fhead{sched.h}
+\fdecl{cpu\_set\_t * \macro{CPU\_ALLOC}(num\_cpus)}
+\fdesc{Alloca dinamicamente un insieme di processori di dimensione voluta.} 
+\fdecl{void \macro{CPU\_FREE}(cpu\_set\_t *set)}
+\fdesc{Disalloca un insieme di processori allocato dinamicamente.} 
+\fdecl{size\_t \macro{CPU\_ALLOC\_SIZE}(num\_cpus)}
+\fdesc{Ritorna la dimensione di un insieme di processori allocato dinamicamente.} 
+}
+\end{funcbox}}
 
-In generale la maschera di affinità è preimpostata in modo che un processo
-possa essere eseguito su qualunque processore, se può comunque leggere il
-valore per un processo specifico usando la funzione
-\funcd{sched\_getaffinity}, il suo prototipo è:
+La prima macro, \macro{CPU\_ALLOC}, restituisce il puntatore ad un insieme di
+processori in grado di contenere almeno \param{num\_cpus} che viene allocato
+dinamicamente. Ogni insieme così allocato dovrà essere disallocato con
+\macro{CPU\_FREE} passandogli un puntatore ottenuto da una precedente
+\macro{CPU\_ALLOC}. La terza macro, \macro{CPU\_ALLOC\_SIZE}, consente di
+ottenere la dimensione in byte di un insieme allocato dinamicamente che
+contenga \param{num\_cpus} processori.
+
+Dato che le dimensioni effettive possono essere diverse le macro di gestione e
+manipolazione che abbiamo trattato in precedenza non si applicano agli insiemi
+allocati dinamicamente, per i quali dovranno sono state definite altrettante
+macro equivalenti contraddistinte dal suffisso \texttt{\_S}, che effettuano le
+stesse operazioni, ma richiedono in più un argomento
+aggiuntivo \param{setsize} che deve essere assegnato al valore ottenuto con
+\macro{CPU\_ALLOC\_SIZE}. Questo stesso valore deve essere usato per l'omonimo
+argomento delle funzioni \func{sched\_setaffinity} o \func{sched\_getaffinity}
+quando si vuole usare per l'argomento che indica la maschera di affinità un
+insieme di processori allocato dinamicamente.
+
+\index{insieme~di~processori|)}
+
+A meno di non aver utilizzato \func{sched\_setaffinity}, in condizioni
+ordinarie la maschera di affinità di un processo è preimpostata dal sistema in
+modo che esso possa essere eseguito su qualunque processore. Se ne può
+comunque ottenere il valore usando la funzione \funcd{sched\_getaffinity}, il
+cui prototipo è:
 
 \begin{funcproto}{ 
 \fhead{sched.h}
-\fdecl{int sched\_getaffinity (pid\_t pid, size\_t cpusetsize, 
+\fdecl{int sched\_getaffinity (pid\_t pid, size\_t setsize, 
   cpu\_set\_t *mask)}
 \fdesc{Legge la maschera di affinità di un processo.} 
 }
@@ -3210,7 +3322,7 @@ valore per un processo specifico usando la funzione
 caso \var{errno} assumerà uno dei valori:
 \begin{errlist}
 \item[\errcode{ESRCH}] il processo \param{pid} non esiste.
-\item[\errcode{EINVAL}] \param{cpusetsize} è più piccolo delle dimensioni
+\item[\errcode{EINVAL}] \param{setsize} è più piccolo delle dimensioni
   della maschera di affinità usata dal kernel.
 \end{errlist}
 ed inoltre anche \errval{EFAULT} nel suo significato generico.}
@@ -3219,19 +3331,13 @@ ed inoltre anche \errval{EFAULT} nel suo significato generico.}
 La funzione restituirà all'indirizzo specificato da \param{mask} il valore
 della maschera di affinità del processo indicato dall'argomento \param{pid}
 (al solito un valore nullo indica il processo corrente) così da poterla
-riutilizzare per una successiva reimpostazione. L'argomento \param{cpusetsize}
-indica la dimensione dell'argomento \param{mask} ed è in genere sufficiente
-passare il valore \code{sizeof(cpu\_set\_t)}.
+riutilizzare per una successiva reimpostazione.
 
 È chiaro che queste funzioni per la gestione dell'affinità hanno significato
 soltanto su un sistema multiprocessore, esse possono comunque essere
 utilizzate anche in un sistema con un processore singolo, nel qual caso però
 non avranno alcun risultato effettivo.
 
-% TODO trattare i cpuset, che attiene anche a NUMA, e che possono essere usati
-% per associare l'uso di gruppi di processori a gruppi di processi (vedi
-% manpage omonima)
-% TODO trattare getcpu, che attiene anche a NUMA
 
 \itindend{scheduler}
 \itindend{CPU~affinity}
@@ -3243,38 +3349,46 @@ non avranno alcun risultato effettivo.
 A lungo l'unica priorità usata per i processi è stata quella relativa
 all'assegnazione dell'uso del processore. Ma il processore non è l'unica
 risorsa che i processi devono contendersi, un'altra, altrettanto importante
-per le prestazioni, è quella dell'accesso a disco. Per questo motivo sono
-stati introdotti diversi \textit{I/O scheduler} in grado di distribuire in
-maniera opportuna questa risorsa ai vari processi. Fino al kernel 2.6.17 era
-possibile soltanto differenziare le politiche generali di gestione, scegliendo
-di usare un diverso \textit{I/O scheduler}; a partire da questa versione, con
-l'introduzione dello \textit{scheduler} CFQ (\textit{Completely Fair Queuing})
-è divenuto possibile, qualora si usi questo \textit{scheduler}, impostare
-anche delle diverse priorità di accesso per i singoli processi.\footnote{al
-  momento (kernel 2.6.31), le priorità di I/O sono disponibili soltanto per
-  questo \textit{scheduler}.}
-
-La scelta dello \textit{scheduler} di I/O si può fare in maniera generica a
-livello di avvio del kernel assegnando il nome dello stesso al parametro
-\texttt{elevator}, mentre se ne può indicare uno per l'accesso al singolo
-disco scrivendo nel file \texttt{/sys/block/\textit{dev}/queue/scheduler}
-(dove \texttt{\textit{dev}} è il nome del dispositivo associato al disco); gli
-\textit{scheduler} disponibili sono mostrati dal contenuto dello stesso file
-che riporta fra parentesi quadre quello attivo, il default in tutti i kernel
-recenti è proprio il \texttt{cfq},\footnote{nome con cui si indica appunto lo
-  \textit{scheduler} CFQ.} che supporta le priorità. Per i dettagli sulle
-caratteristiche specifiche degli altri \textit{scheduler}, la cui discussione
-attiene a problematiche di ambito sistemistico, si consulti la documentazione
-nella directory \texttt{Documentation/block/} dei sorgenti del kernel.
+per le prestazioni, è quella dell'accesso a disco. Per questo motivo nello
+sviluppo del kernel sono stati introdotti diversi \textit{I/O scheduler} in
+grado di distribuire in maniera opportuna questa risorsa ai vari processi.
+
+Fino al kernel 2.6.17 era possibile soltanto differenziare le politiche
+generali di gestione, scegliendo di usare un diverso \textit{I/O scheduler}. A
+partire da questa versione, con l'introduzione dello \textit{scheduler} CFQ
+(\textit{Completely Fair Queuing}) è divenuto possibile, qualora si usi questo
+\textit{scheduler}, impostare anche delle diverse priorità di accesso per i
+singoli processi.\footnote{al momento (kernel 2.6.31), le priorità di I/O sono
+  disponibili soltanto per questo \textit{scheduler}.}
+
+La scelta di uno \textit{scheduler} di I/O si può fare in maniera generica per
+tutto il sistema all'avvio del kernel con il parametro di avvio
+\texttt{elevator},\footnote{per la trattazione dei parametri di avvio del
+  kernel si rimanda al solito alla sez.~5.3 di \cite{AGL}.} cui assegnare il
+nome dello \textit{scheduler}, ma se ne può anche indicare uno specifico per
+l'accesso al singolo disco scrivendo nel file
+\texttt{/sys/block/\textit{<dev>}/queue/scheduler} (dove
+\texttt{\textit{<dev>}} è il nome del dispositivo associato al disco).
+
+Gli \textit{scheduler} disponibili sono mostrati dal contenuto dello stesso
+file che riporta fra parentesi quadre quello attivo, il default in tutti i
+kernel recenti è proprio il \texttt{cfq},\footnote{nome con cui si indica
+  appunto lo \textit{scheduler} CFQ.} che supporta le priorità. Per i dettagli
+sulle caratteristiche specifiche degli altri \textit{scheduler}, la cui
+discussione attiene a problematiche di ambito sistemistico, si consulti la
+documentazione nella directory \texttt{Documentation/block/} dei sorgenti del
+kernel.
 
 Una volta che si sia impostato lo \textit{scheduler} CFQ ci sono due
 specifiche system call, specifiche di Linux, che consentono di leggere ed
 impostare le priorità di I/O.\footnote{se usate in corrispondenza ad uno
   \textit{scheduler} diverso il loro utilizzo non avrà alcun effetto.} Dato
 che non esiste una interfaccia diretta nelle \acr{glibc} per queste due
-funzioni occorrerà invocarle tramite la funzione \func{syscall} (come
-illustrato in sez.~\ref{sec:proc_syscall}). Le due funzioni sono
-\funcd{ioprio\_get} ed \funcd{ioprio\_set}; i rispettivi prototipi sono:
+funzioni\footnote{almeno al momento della scrittura di questa sezione, con la
+  versione 2.11 della \acr{glibc}.} occorrerà invocarle tramite la funzione
+\func{syscall} (come illustrato in sez.~\ref{sec:proc_syscall}). Le due
+funzioni sono \funcd{ioprio\_get} ed \funcd{ioprio\_set}; i rispettivi
+prototipi sono:
 
 \begin{funcproto}{ 
 \fhead{linux/ioprio.h}
@@ -3287,8 +3401,8 @@ illustrato in sez.~\ref{sec:proc_syscall}). Le due funzioni sono
   successo e $-1$ per un errore, nel qual caso \var{errno} assumerà uno dei
   valori:
 \begin{errlist}
-\item[\errcode{ESRCH}] non esiste un processo corrisponente alle indicazioni.
-\item[\errcode{EINVAL}] i valori di \param{which} o di \param{iprio} non
+\item[\errcode{ESRCH}] non esiste un processo corrispondente alle indicazioni.
+\item[\errcode{EINVAL}] i valori di \param{which} o di \param{ioprio} non
   sono validi. 
 \item[\errcode{EPERM}] non si hanno i privilegi per eseguire
   l'impostazione (solo per \func{ioprio\_set}). 
@@ -3332,17 +3446,6 @@ di \textit{scheduling} lo prevede, la priorità del processo all'interno della
 classe stessa. Questo stesso formato viene utilizzato per indicare il valore
 della priorità da impostare con l'argomento \param{ioprio} di
 \func{ioprio\_set}.
-
-Per la gestione dei valori che esprimono le priorità di I/O sono state
-definite delle opportune macro di preprocessore, riportate in
-tab.~\ref{tab:IOsched_class_macro}. I valori delle priorità si ottengono o si
-impostano usando queste macro.  Le prime due si usano con il valore restituito
-da \func{ioprio\_get} e per ottenere rispettivamente la classe di
-\textit{scheduling}\footnote{restituita dalla macro con i valori di
-  tab.~\ref{tab:IOsched_class}.} e l'eventuale valore della priorità. La terza
-macro viene invece usata per creare un valore di priorità da usare come
-argomento di \func{ioprio\_set} per eseguire una impostazione.
-
 \begin{table}[htb]
   \centering
   \footnotesize
@@ -3369,11 +3472,16 @@ argomento di \func{ioprio\_set} per eseguire una impostazione.
   \label{tab:IOsched_class_macro}
 \end{table}
 
-Le classi di \textit{scheduling} previste dallo \textit{scheduler} CFQ sono
-tre, e ricalcano tre diverse modalità di distribuzione delle risorse analoghe
-a quelle già adottate anche nel funzionamento dello \textit{scheduler} del
-processore. Ciascuna di esse è identificata tramite una opportuna costante,
-secondo quanto riportato in tab.~\ref{tab:IOsched_class}.
+
+Per la gestione dei valori che esprimono le priorità di I/O sono state
+definite delle opportune macro di preprocessore, riportate in
+tab.~\ref{tab:IOsched_class_macro}. I valori delle priorità si ottengono o si
+impostano usando queste macro.  Le prime due si usano con il valore restituito
+da \func{ioprio\_get} e per ottenere rispettivamente la classe di
+\textit{scheduling}\footnote{restituita dalla macro con i valori di
+  tab.~\ref{tab:IOsched_class}.} e l'eventuale valore della priorità. La terza
+macro viene invece usata per creare un valore di priorità da usare come
+argomento di \func{ioprio\_set} per eseguire una impostazione.
 
 \begin{table}[htb]
   \centering
@@ -3392,6 +3500,12 @@ secondo quanto riportato in tab.~\ref{tab:IOsched_class}.
   \label{tab:IOsched_class}
 \end{table}
 
+Le classi di \textit{scheduling} previste dallo \textit{scheduler} CFQ sono
+tre, e ricalcano tre diverse modalità di distribuzione delle risorse analoghe
+a quelle già adottate anche nel funzionamento dello \textit{scheduler} del
+processore. Ciascuna di esse è identificata tramite una opportuna costante,
+secondo quanto riportato in tab.~\ref{tab:IOsched_class}.
+
 La classe di priorità più bassa è \const{IOPRIO\_CLASS\_IDLE}; i processi in
 questa classe riescono ad accedere a disco soltanto quando nessun altro
 processo richiede l'accesso. Occorre pertanto usarla con molta attenzione,
@@ -3441,13 +3555,6 @@ questo caso non ci sono effetti sugli altri processi questo limite è stato
 rimosso a partire dal kernel 2.6.25.
 
 %TODO verificare http://lwn.net/Articles/355987/
-
-%TODO trattare le funzionalità per il NUMA
-% vedi man numa e, mbind, get_mempolicy, set_mempolicy, 
-% le pagine di manuale relative
-% vedere anche dove metterle...
-
-
 \section{Funzioni di gestione avanzata}
 \label{sec:proc_advanced_control}
 
@@ -3475,8 +3582,9 @@ funzione è \funcd{prctl} ed il suo prototipo è:\footnote{la funzione non è
 
 \begin{funcproto}{ 
 \fhead{sys/prctl.h}
-\fdecl{int prctl(int option, unsigned long arg2, unsigned long arg3,
-    unsigned long arg4, unsigned long arg5)}
+\fdecl{int prctl(int option, unsigned long arg2, unsigned long arg3, unsigned
+  long arg4, \\
+\phantom{int prctl(}unsigned long arg5)}
 \fdesc{Esegue una operazione speciale sul processo corrente.} 
 }
 {La funzione ritorna $0$ o un valore positivo dipendente dall'operazione in
@@ -3491,27 +3599,32 @@ primo, il valore di ritorno in caso di successo, il tipo di errore restituito
 in \var{errno} dipendono dall'operazione eseguita, indicata tramite il primo
 argomento, \param{option}. Questo è un valore intero che identifica
 l'operazione, e deve essere specificato con l'uso di una delle costanti
-predefinite del seguente elenco, che illustra quelle disponibili al momento:
+predefinite del seguente elenco, che illustra quelle disponibili al
+momento:\footnote{alla stesura di questa sezione, cioè con il kernel 3.2.}
 
 \begin{basedescript}{\desclabelstyle{\pushlabel}}
 \item[\const{PR\_CAPBSET\_READ}] Controlla la disponibilità di una delle
-  \textit{capabilities} (vedi sez.~\ref{sec:proc_capabilities}). La funzione
-  ritorna 1 se la capacità specificata nell'argomento \param{arg2} (con una
-  delle costanti di tab.~\ref{tab:proc_capabilities}) è presente nel
-  \textit{capabilities bounding set} del processo e zero altrimenti,
-  se \param{arg2} non è un valore valido si avrà un errore di \errval{EINVAL}.
-  Introdotta a partire dal kernel 2.6.25.
+  \itindex{capabilities} \textit{capabilities} (vedi
+  sez.~\ref{sec:proc_capabilities}). La funzione ritorna 1 se la capacità
+  specificata nell'argomento \param{arg2} (con una delle costanti di
+  tab.~\ref{tab:proc_capabilities}) è presente nel \textit{capabilities
+    bounding set} del processo e zero altrimenti, se \param{arg2} non è un
+  valore valido si avrà un errore di \errval{EINVAL}.  Introdotta a partire
+  dal kernel 2.6.25.
+
 \item[\const{PR\_CAPBSET\_DROP}] Rimuove permanentemente una delle
-  \textit{capabilities} (vedi sez.~\ref{sec:proc_capabilities}) dal processo e
-  da tutti i suoi discendenti. La funzione cancella la capacità specificata
+  \itindex{capabilities} \textit{capabilities} (vedi
+  sez.~\ref{sec:proc_capabilities}) dal processo e da tutti i suoi
+  discendenti. La funzione cancella la capacità specificata
   nell'argomento \param{arg2} con una delle costanti di
-  tab.~\ref{tab:proc_capabilities} dal \textit{capabilities bounding set} del
-  processo. L'operazione richiede i privilegi di amministratore (la capacità
-  \const{CAP\_SETPCAP}), altrimenti la chiamata fallirà con un errore di
-  \errval{EPERM}; se il valore di \param{arg2} non è valido o se il supporto
-  per le \textit{file capabilities} non è stato compilato nel kernel la
-  chiamata fallirà con un errore di \errval{EINVAL}. Introdotta a partire dal
-  kernel 2.6.25.
+  tab.~\ref{tab:proc_capabilities} dal \textit{capabilities bounding set}
+  \itindex{capabilities~bounding~set} del processo. L'operazione richiede i
+  privilegi di amministratore (la capacità \const{CAP\_SETPCAP}), altrimenti
+  la chiamata fallirà con un errore di \errcode{EPERM}; se il valore
+  di \param{arg2} non è valido o se il supporto per le \textit{file
+    capabilities} non è stato compilato nel kernel la chiamata fallirà con un
+  errore di \errval{EINVAL}. Introdotta a partire dal kernel 2.6.25.
+
 \item[\const{PR\_SET\_DUMPABLE}] Imposta il flag che determina se la
   terminazione di un processo a causa di un segnale per il quale è prevista la
   generazione di un file di \itindex{core~dump} \textit{core dump} (vedi
@@ -3521,65 +3634,79 @@ predefinite del seguente elenco, che illustra quelle disponibili al momento:
   per sovrascriverne altri) viene cancellato quando si mette in esecuzione un
   programma con i bit \acr{suid} e \acr{sgid} attivi (vedi
   sez.~\ref{sec:file_special_perm}) o con l'uso delle funzioni per la modifica
-  degli \textit{user-ID} dei processi (vedi
-  sez.~\ref{sec:proc_setuid}). L'operazione è stata introdotta a partire dal
-  kernel 2.3.20, fino al kernel 2.6.12 e per i kernel successivi al 2.6.17 era
-  possibile usare solo un valore 0 di \param{arg2} per disattivare il flag ed
-  un valore 1 per attivarlo, nei kernel dal 2.6.13 al 2.6.17 è stato
-  supportato anche il valore 2, che causava la generazione di un
-  \itindex{core~dump} \textit{core dump} leggibile solo
-  dall'amministratore.\footnote{la funzionalità è stata rimossa per motivi di
-    sicurezza, in quanto consentiva ad un utente normale di creare un file di
-    \textit{core dump} appartenente all'amministratore in directory dove
-    l'utente avrebbe avuto permessi di accesso.}
+  degli \acr{uid} dei processi (vedi sez.~\ref{sec:proc_setuid}). 
+
+  L'operazione è stata introdotta a partire dal kernel 2.3.20, fino al kernel
+  2.6.12 e per i kernel successivi al 2.6.17 era possibile usare solo un
+  valore 0 di \param{arg2} per disattivare il flag ed un valore 1 per
+  attivarlo. Nei kernel dal 2.6.13 al 2.6.17 è stato supportato anche il
+  valore 2, che causava la generazione di un \itindex{core~dump} \textit{core
+    dump} leggibile solo dall'amministratore, ma questa funzionalità è stata
+  rimossa per motivi di sicurezza, in quanto consentiva ad un utente normale
+  di creare un file di \textit{core dump} appartenente all'amministratore in
+  directory dove l'utente avrebbe avuto permessi di accesso.
+
 \item[\const{PR\_GET\_DUMPABLE}] Ottiene come valore di ritorno della funzione
   lo stato corrente del flag che controlla la effettiva generazione dei
   \itindex{core~dump} \textit{core dump}. Introdotta a partire dal kernel
   2.3.20.
-\item[\const{PR\_SET\_ENDIAN}] Imposta la \textit{endianness} del processo
-  chiamante secondo il valore fornito in \param{arg2}. I valori possibili sono
-  sono: \const{PR\_ENDIAN\_BIG} (\textit{big endian}),
-  \const{PR\_ENDIAN\_LITTLE} (\textit{little endian}), e
-  \const{PR\_ENDIAN\_PPC\_LITTLE} (lo pseudo \textit{little endian} del
+
+\item[\const{PR\_SET\_ENDIAN}] Imposta la \itindex{endianness}
+  \textit{endianness} del processo chiamante secondo il valore fornito
+  in \param{arg2}. I valori possibili sono sono: \const{PR\_ENDIAN\_BIG}
+  (\textit{big endian}), \const{PR\_ENDIAN\_LITTLE} (\textit{little endian}),
+  e \const{PR\_ENDIAN\_PPC\_LITTLE} (lo pseudo \textit{little endian} del
   PowerPC). Introdotta a partire dal kernel 2.6.18, solo per architettura
   PowerPC.
-\item[\const{PR\_GET\_ENDIAN}] Ottiene il valore della \textit{endianness} del
-  processo chiamante, salvato sulla variabile puntata da \param{arg2} che deve
-  essere passata come di tipo \ctyp{(int *)}. Introdotta a partire dal kernel
-  2.6.18, solo su PowerPC.
+
+\item[\const{PR\_GET\_ENDIAN}] Ottiene il valore della \itindex{endianness}
+  \textit{endianness} del processo chiamante, salvato sulla variabile puntata
+  da \param{arg2} che deve essere passata come di tipo ``\ctyp{int
+    *}''. Introdotta a partire dal kernel 2.6.18, solo su PowerPC.
+
 \item[\const{PR\_SET\_FPEMU}] Imposta i bit di controllo per l'emulazione
   della virgola mobile su architettura ia64, secondo il valore
   di \param{arg2}, si deve passare \const{PR\_FPEMU\_NOPRINT} per emulare in
   maniera trasparente l'accesso alle operazioni in virgola mobile, o
   \const{PR\_FPEMU\_SIGFPE} per non emularle ed inviare il segnale
   \signal{SIGFPE} (vedi sez.~\ref{sec:sig_prog_error}). Introdotta a partire
-  dal kernel 2.4.18, solo su ia64.
+  dal kernel 2.4.18, solo su architettura ia64.
+
 \item[\const{PR\_GET\_FPEMU}] Ottiene il valore dei flag di controllo
   dell'emulazione della virgola mobile, salvato all'indirizzo puntato
-  da \param{arg2}, che deve essere di tipo \code{(int *)}. Introdotta a
-  partire dal kernel 2.4.18, solo su ia64.
+  da \param{arg2}, che deve essere di tipo ``\ctyp{int *}''. Introdotta a
+  partire dal kernel 2.4.18, solo su architettura ia64.
+
 \item[\const{PR\_SET\_FPEXC}] Imposta la modalità delle eccezioni in virgola
   mobile (\textit{floating-point exception mode}) al valore di \param{arg2}.
-  I valori possibili sono: \const{PR\_FP\_EXC\_SW\_ENABLE} per usare FPEXC per
-  le eccezioni, \const{PR\_FP\_EXC\_DIV} per la divisione per zero in virgola
-  mobile, \const{PR\_FP\_EXC\_OVF} per gli overflow, \const{PR\_FP\_EXC\_UND}
-  per gli underflow, \const{PR\_FP\_EXC\_RES} per risultati non esatti,
-  \const{PR\_FP\_EXC\_INV} per operazioni invalide,
-  \const{PR\_FP\_EXC\_DISABLED} per disabilitare le eccezioni,
-  \const{PR\_FP\_EXC\_NONRECOV} per utilizzare la modalità di eccezione
-  asincrona non recuperabile, \const{PR\_FP\_EXC\_ASYNC} per utilizzare la
-  modalità di eccezione asincrona recuperabile, \const{PR\_FP\_EXC\_PRECISE}
-  per la modalità precisa di eccezione.\footnote{trattasi di gestione
-    specialistica della gestione delle eccezioni dei calcoli in virgola mobile
-    che, i cui dettagli al momento vanno al di là dello scopo di questo
-    testo.} Introdotta a partire dal kernel 2.4.21, solo su PowerPC.
+  I valori possibili sono: 
+  \begin{itemize*}
+  \item \const{PR\_FP\_EXC\_SW\_ENABLE} per usare FPEXC per le eccezioni,
+  \item \const{PR\_FP\_EXC\_DIV} per la divisione per zero in virgola mobile,
+  \item \const{PR\_FP\_EXC\_OVF} per gli overflow,
+  \item \const{PR\_FP\_EXC\_UND} per gli underflow,
+  \item \const{PR\_FP\_EXC\_RES} per risultati non esatti,
+  \item \const{PR\_FP\_EXC\_INV} per operazioni invalide,
+  \item \const{PR\_FP\_EXC\_DISABLED} per disabilitare le eccezioni,
+  \item \const{PR\_FP\_EXC\_NONRECOV} per usare la modalità di eccezione
+    asincrona non recuperabile,
+  \item \const{PR\_FP\_EXC\_ASYNC} per usare la modalità di eccezione
+    asincrona recuperabile,
+  \item \const{PR\_FP\_EXC\_PRECISE} per la modalità precisa di
+    eccezione.\footnote{trattasi di gestione specialistica della gestione
+      delle eccezioni dei calcoli in virgola mobile che, i cui dettagli al
+      momento vanno al di là dello scopo di questo testo.}
+  \end{itemize*}
+Introdotta a partire dal kernel 2.4.21, solo su PowerPC.
+
 \item[\const{PR\_GET\_FPEXC}] Ottiene il valore della modalità delle eccezioni
   delle operazioni in virgola mobile, salvata all'indirizzo
-  puntato \param{arg2}, che deve essere di tipo \code{(int *)}.  Introdotta a
-  partire dal kernel 2.4.21, solo su PowerPC.
+  puntato \param{arg2}, che deve essere di tipo ``\ctyp{int *}''.  Introdotta
+  a partire dal kernel 2.4.21, solo su PowerPC.
+
 \item[\const{PR\_SET\_KEEPCAPS}] Consente di controllare quali
-  \textit{capabilities} vengono cancellate quando si esegue un cambiamento di
-  \textit{user-ID} del processo (per i dettagli si veda
+  \itindex{capabilities} \textit{capabilities} vengono cancellate quando si
+  esegue un cambiamento di \acr{uid} del processo (per i dettagli si veda
   sez.~\ref{sec:proc_capabilities}, in particolare quanto illustrato a
   pag.~\pageref{sec:capability-uid-transition}). Un valore nullo (il default)
   per \param{arg2} comporta che vengano cancellate, il valore 1 che vengano
@@ -3588,17 +3715,22 @@ predefinite del seguente elenco, che illustra quelle disponibili al momento:
   flag \const{SECURE\_KEEP\_CAPS} dei \itindex{securebits} \textit{securebits}
   (vedi l'uso di \const{PR\_SET\_SECUREBITS} più avanti). Introdotta a partire
   dal kernel 2.2.18.
+
 \item[\const{PR\_GET\_KEEPCAPS}] Ottiene come valore di ritorno della funzione
-  il valore del flag di controllo impostato con
-  \const{PR\_SET\_KEEPCAPS}. Introdotta a partire dal kernel 2.2.18.
+  il valore del flag di controllo delle \itindex{capabilities}
+  \textit{capabilities} impostato con \const{PR\_SET\_KEEPCAPS}. Introdotta a
+  partire dal kernel 2.2.18.
+
 \item[\const{PR\_SET\_NAME}] Imposta il nome del processo chiamante alla
-  stringa puntata da \param{arg2}, che deve essere di tipo \code{(char *)}. Il
+  stringa puntata da \param{arg2}, che deve essere di tipo ``\ctyp{char *}''. Il
   nome può essere lungo al massimo 16 caratteri, e la stringa deve essere
   terminata da NUL se più corta.  Introdotta a partire dal kernel 2.6.9.
+
 \item[\const{PR\_GET\_NAME}] Ottiene il nome del processo chiamante nella
-  stringa puntata da \param{arg2}, che deve essere di tipo \code{(char *)}; si
-  devono allocare per questo almeno 16 byte, e il nome sarà terminato da NUL
-  se più corto. Introdotta a partire dal kernel 2.6.9.
+  stringa puntata da \param{arg2}, che deve essere di tipo ``\ctyp{char *}'';
+  si devono allocare per questo almeno 16 byte, e il nome sarà terminato da
+  NUL se più corto. Introdotta a partire dal kernel 2.6.9.
+
 \item[\const{PR\_SET\_PDEATHSIG}] Consente di richiedere l'emissione di un
   segnale, che sarà ricevuto dal processo chiamante, in occorrenza della
   terminazione del proprio processo padre; in sostanza consente di invertire
@@ -3606,55 +3738,65 @@ predefinite del seguente elenco, che illustra quelle disponibili al momento:
   numero del segnale, o 0 per disabilitare l'emissione. Il valore viene
   automaticamente cancellato per un processo figlio creato con \func{fork}.
   Introdotta a partire dal kernel 2.1.57.
+
 \item[\const{PR\_GET\_PDEATHSIG}] Ottiene il valore dell'eventuale segnale
   emesso alla terminazione del padre, salvato all'indirizzo
-  puntato \param{arg2}, che deve essere di tipo \code{(int *)}. Introdotta a
+  puntato \param{arg2}, che deve essere di tipo ``\ctyp{int *}''. Introdotta a
   partire dal kernel 2.3.15.
+
 \item[\const{PR\_SET\_SECCOMP}] Imposta il cosiddetto
   \itindex{secure~computing~mode} \textit{secure computing mode} per il
   processo corrente. Prevede come unica possibilità che \param{arg2} sia
-  impostato ad 1. Una volta abilitato il \textit{secure computing mode} il
-  processo potrà utilizzare soltanto un insieme estremamente limitato di
-  \textit{system call}: \func{read}, \func{write}, \func{\_exit} e
-  \func{sigreturn}, ogni altra \textit{system call} porterà all'emissione di
-  un \func{SIGKILL} (vedi sez.~\ref{sec:sig_termination}).  Il \textit{secure
-    computing mode} è stato ideato per fornire un supporto per l'esecuzione di
-  codice esterno non fidato e non verificabile a scopo di calcolo;\footnote{lo
-    scopo è quello di poter vendere la capacità di calcolo della proprio
-    macchina ad un qualche servizio di calcolo distribuito senza
-    comprometterne la sicurezza eseguendo codice non sotto il proprio
-    controllo.} in genere i dati vengono letti o scritti grazie ad un socket o
-  una pipe, e per evitare problemi di sicurezza non sono possibili altre
-  operazioni se non quelle citate.  Introdotta a partire dal kernel 2.6.23,
-  disponibile solo se si è abilitato il supporto nel kernel con
-  \texttt{CONFIG\_SECCOMP}.
+  impostato ad 1. Una volta abilitato il \itindex{secure~computing~mode}
+  \textit{secure computing mode} il processo potrà utilizzare soltanto un
+  insieme estremamente limitato di \textit{system call}: \func{read},
+  \func{write}, \func{\_exit} e \func{sigreturn}. Ogni altra \textit{system
+    call} porterà all'emissione di un \func{SIGKILL} (vedi
+  sez.~\ref{sec:sig_termination}).  Il \textit{secure computing mode} è stato
+  ideato per fornire un supporto per l'esecuzione di codice esterno non fidato
+  e non verificabile a scopo di calcolo;\footnote{lo scopo è quello di poter
+    vendere la capacità di calcolo della proprio macchina ad un qualche
+    servizio di calcolo distribuito senza comprometterne la sicurezza
+    eseguendo codice non sotto il proprio controllo.} in genere i dati vengono
+  letti o scritti grazie ad un socket o una pipe, e per evitare problemi di
+  sicurezza non sono possibili altre operazioni se non quelle citate.
+  Introdotta a partire dal kernel 2.6.23, disponibile solo se si è abilitato
+  il supporto nel kernel con \texttt{CONFIG\_SECCOMP}.
+
 \item[\const{PR\_GET\_SECCOMP}] Ottiene come valore di ritorno della funzione
   lo stato corrente del \textit{secure computing mode}, al momento attuale la
   funzione è totalmente inutile in quanto l'unico valore ottenibile è 0, dato
-  che la chiamata di questa funzione in \textit{secure computing mode}
-  comporterebbe l'emissione di \texttt{SIGKILL}, è stata comunque definita per
-  eventuali estensioni future.  Introdotta a partire dal kernel 2.6.23.
+  che la chiamata di questa funzione in \itindex{secure~computing~mode}
+  \textit{secure computing mode} comporterebbe l'emissione di
+  \texttt{SIGKILL}, è stata comunque definita per eventuali estensioni future.
+  Introdotta a partire dal kernel 2.6.23.
+
 \item[\const{PR\_SET\_SECUREBITS}] Imposta i \itindex{securebits}
   \textit{securebits} per il processo chiamante al valore indicato
   da \param{arg2}; per i dettagli sul significato dei \textit{securebits} si
   veda sez.~\ref{sec:proc_capabilities}, ed in particolare i valori di
   tab.~\ref{tab:securebits_values} e la relativa trattazione. L'operazione
-  richiede i privilegi di amministratore (la capacità \const{CAP\_SETPCAP}),
-  altrimenti la chiamata fallirà con un errore di \errval{EPERM}. Introdotta a
-  partire dal kernel 2.6.26.
+  richiede i privilegi di amministratore (la \itindex{capabilities} capacità
+  \const{CAP\_SETPCAP}), altrimenti la chiamata fallirà con un errore di
+  \errval{EPERM}. Introdotta a partire dal kernel 2.6.26.
+
 \item[\const{PR\_GET\_SECUREBITS}] Ottiene come valore di ritorno della
   funzione l'impostazione corrente per i \itindex{securebits}
   \textit{securebits}. Introdotta a partire dal kernel 2.6.26.
+
 \item[\const{PR\_SET\_TIMING}] Imposta il metodo di temporizzazione del
-  processo da indicare con il valore di \param{arg2}, con
-  \const{PR\_TIMING\_STATISTICAL} si usa il metodo statistico tradizionale,
-  con \const{PR\_TIMING\_TIMESTAMP} il più accurato basato su dei
-  \textit{timestamp}, quest'ultimo però non è ancora implementato ed il suo
-  uso comporta la restituzione di un errore di \errval{EINVAL}. Introdotta a
-  partire dal kernel 2.6.0-test4.
+  processo da indicare con il valore di \param{arg2}, attualmente i valori
+  possibili sono due, con \const{PR\_TIMING\_STATISTICAL} si usa il metodo
+  statistico tradizionale, con \const{PR\_TIMING\_TIMESTAMP} il più accurato
+  basato su dei \textit{timestamp}, quest'ultimo però non è ancora
+  implementato ed il suo uso comporta la restituzione di un errore di
+  \errval{EINVAL}. Introdotta a partire dal kernel 2.6.0-test4.
+
 \item[\const{PR\_GET\_TIMING}] Ottiene come valore di ritorno della funzione
-  il metodo di temporizzazione del processo attualmente in uso. Introdotta a
-  partire dal kernel 2.6.0-test4.
+  il metodo di temporizzazione del processo attualmente in uso (uno dei due
+  valori citati per \const{PR\_SET\_TIMING}). Introdotta a partire dal kernel
+  2.6.0-test4.
+
 \item[\const{PR\_SET\_TSC}] Imposta il flag che indica se il processo
   chiamante può leggere il registro di processore contenente il contatore dei
   \textit{timestamp} (TSC, o \textit{Time Stamp Counter}) da indicare con il
@@ -3662,15 +3804,17 @@ predefinite del seguente elenco, che illustra quelle disponibili al momento:
   abilitare la lettura o \const{PR\_TSC\_SIGSEGV} per disabilitarla con la
   generazione di un segnale di \signal{SIGSEGV} (vedi
   sez.~\ref{sec:sig_prog_error}). La lettura viene automaticamente
-  disabilitata se si attiva il \textit{secure computing mode}.  Introdotta a
-  partire dal kernel 2.6.26, solo su x86.
+  disabilitata se si attiva il \itindex{secure~computing~mode} \textit{secure
+    computing mode}.  Introdotta a partire dal kernel 2.6.26, solo su x86.
+
 \item[\const{PR\_GET\_TSC}] Ottiene il valore del flag che controlla la
   lettura del contattore dei \textit{timestamp}, salvato all'indirizzo
-  puntato \param{arg2}, che deve essere di tipo \code{(int *)}. Introdotta a
+  puntato \param{arg2}, che deve essere di tipo ``\ctyp{int *}''. Introdotta a
   partire dal kernel 2.6.26, solo su x86.
 % articoli sul TSC e relativi problemi: http://lwn.net/Articles/209101/,
 % http://blog.cr0.org/2009/05/time-stamp-counter-disabling-oddities.html,
 % http://en.wikipedia.org/wiki/Time_Stamp_Counter 
+
 \item[\const{PR\_SET\_UNALIGN}] Imposta la modalità di controllo per l'accesso
   a indirizzi di memoria non allineati, che in varie architetture risultano
   illegali, da indicare con il valore di \param{arg2}. Si deve specificare il
@@ -3678,6 +3822,7 @@ predefinite del seguente elenco, che illustra quelle disponibili al momento:
   ed il valore \const{PR\_UNALIGN\_SIGBUS} per generare un segnale di
   \signal{SIGBUS} (vedi sez.~\ref{sec:sig_prog_error}) in caso di accesso non
   allineato.  Introdotta con diverse versioni su diverse architetture.
+
 \item[\const{PR\_GET\_UNALIGN}] Ottiene il valore della modalità di controllo
   per l'accesso a indirizzi di memoria non allineati, salvato all'indirizzo
   puntato \param{arg2}, che deve essere di tipo \code{(int *)}. Introdotta con
@@ -3735,6 +3880,7 @@ predefinite del seguente elenco, che illustra quelle disponibili al momento:
 \end{basedescript}
 
 
+
 \subsection{La \textit{system call} \func{clone}}
 \label{sec:process_clone}
 
@@ -3751,18 +3897,19 @@ delegata ad una nuova \textit{system call}, \func{sys\_clone}, che consente di
 reimplementare anche la tradizionale \func{fork}. In realtà in questo caso più
 che di nuovi processi si può parlare della creazioni di nuovi
 ``\textit{task}'' del kernel che possono assumere la veste sia di un processo
-classico come quelli trattati finora, che di un \textit{thread}, come quelli
-che vedremo in sez.~\ref{sec:linux_thread}, in cui la memoria viene condivisa
-fra il processo chiamante ed il nuovo processo creato. Per evitare confusione
-fra \textit{thread} e processi ordinari, abbiamo deciso di usare la
-nomenclatura \textit{task} per indicare la unità di esecuzione generica messa
-a disposizione del kernel che \texttt{sys\_clone} permette di creare.
+classico isolato dagli altri come quelli trattati finora, che di un
+\textit{thread} in cui la memoria viene condivisa fra il processo chiamante ed
+il nuovo processo creato, come quelli che vedremo in
+sez.~\ref{sec:linux_thread}. Per evitare confusione fra \textit{thread} e
+processi ordinari, abbiamo deciso di usare la nomenclatura \textit{task} per
+indicare la unità di esecuzione generica messa a disposizione del kernel che
+\texttt{sys\_clone} permette di creare.
 
 Oltre a questo la funzione consente, ad uso delle nuove funzionalità di
 virtualizzazione dei processi, di creare nuovi \textit{namespace} per una
 serie di proprietà generali dei processi (come l'elenco dei PID, l'albero dei
-file, dei \textit{mount point}, della rete, ecc.), che consentono di creare
-gruppi di processi che vivono in una sorta di spazio separato dagli altri, che
+file, i \textit{mount point}, la rete, ecc.), che consentono di creare gruppi
+di processi che vivono in una sorta di spazio separato dagli altri, che
 costituisce poi quello che viene chiamato un \textit{container}.
 
 La \textit{system call} richiede soltanto due argomenti: il
@@ -3822,7 +3969,9 @@ visto in sez.~\ref{sec:proc_syscall}.\footnote{ed inoltre per questa
 
 \begin{funcproto}{ 
 \fhead{sched.h}
-\fdecl{int clone(int (*fn)(void *), void *child\_stack, int flags, void *arg, ...    /* pid\_t *ptid, struct user\_desc *tls, pid\_t *ctid */)}
+\fdecl{int clone(int (*fn)(void *), void *child\_stack, int flags, void *arg,
+  ...  \\
+\phantom{int clone(}/* pid\_t *ptid, struct user\_desc *tls, pid\_t *ctid */ )}
 \fdesc{Crea un nuovo processo o \textit{thread}.} 
 }
 {La funzione ritorna il \textit{Thread ID} assegnato al nuovo processo in caso
@@ -3845,9 +3994,9 @@ che verrà messa in esecuzione nel nuovo processo, che può avere un unico
 argomento di tipo puntatore a \ctyp{void}, il cui valore viene passato dal
 terzo argomento \param{arg}. Per quanto il precedente prototipo possa
 intimidire nella sua espressione, in realtà l'uso è molto semplice basterà
-definire una qualunque funzione \param{fn} che restitisce un intero ed ha come
-argomento un puntatore a \ctyp{vois}, e \code{fn(arg)} sarà eseguita in un
-nuovo processo.
+definire una qualunque funzione \param{fn} che restituisce un intero ed ha
+come argomento un puntatore a \ctyp{void}, e \code{fn(arg)} sarà eseguita in
+un nuovo processo.
 
 Il nuovo processo resterà in esecuzione fintanto che la funzione \param{fn}
 non ritorna, o esegue \func{exit} o viene terminata da un segnale. Il valore
@@ -3858,7 +4007,10 @@ presenti solo a partire dal kernel 2.6 ed usati principalmente per le funzioni
 di gestione dei \textit{thread} presenti nella \acr{glibc}.
 
 Il comportamento di \func{clone}, che si riflette sulle caratteristiche del
-nuovo processo da essa creato, è controllato dall'argomento \param{flags}, 
+nuovo processo da essa creato, è controllato dall'argomento \param{flags}, che
+deve essere specificato come maschera binaria, ottenuta con un OR aritmetico
+di una delle costanti del seguente elenco, che illustra quelle attualmente
+disponibili:\footnote{alla stesura di questa sezione, cioè con il kernel 3.2.}
 
 \begin{basedescript}{\desclabelstyle{\pushlabel}}
 
@@ -3911,11 +4063,25 @@ Da fare.
 %
 % TODO l'I/O sulle porte di I/O 
 % consultare le manpage di ioperm, iopl e outb
+% non c'entra nulla qui, va trovato un altro posto (altri meccanismi di I/O in
+% fileintro ?)
 
 Da fare
 
-% TODO: funzioni varie sparse citate da qualche parte e da trattare forse in
-% una sezione a parte: sigreturn,
+
+%\subsection{La gestione di architetture a nodi multipli}
+%\label{sec:process_NUMA}
+
+% TODO trattare i cpuset, che attiene anche a NUMA, e che possono essere usati
+% per associare l'uso di gruppi di processori a gruppi di processi (vedi
+% manpage omonima)
+% TODO trattare getcpu, che attiene anche a NUMA, mettere qui anche
+% sched_getcpu, che potrebbe essere indipendente ma richiama getcpu
+
+%TODO trattare le funzionalità per il NUMA
+% vedi man numa e, mbind, get_mempolicy, set_mempolicy, 
+% le pagine di manuale relative
+% vedere anche dove metterle...
 
 
 \section{Problematiche di programmazione multitasking}
@@ -3925,12 +4091,13 @@ Benché i processi siano strutturati in modo da apparire il più possibile come
 indipendenti l'uno dall'altro, nella programmazione in un sistema multitasking
 occorre tenere conto di una serie di problematiche che normalmente non
 esistono quando si ha a che fare con un sistema in cui viene eseguito un solo
-programma alla volta.
+programma alla volta. 
 
-Pur essendo questo argomento di carattere generale, ci è parso opportuno
-introdurre sinteticamente queste problematiche, che ritroveremo a più riprese
-in capitoli successivi, in questa sezione conclusiva del capitolo in cui
-abbiamo affrontato la gestione dei processi.
+Per questo motivo, essendo questo argomento di carattere generale, ci è parso
+opportuno introdurre sinteticamente queste problematiche, che ritroveremo a
+più riprese in capitoli successivi, in questa sezione conclusiva del capitolo
+in cui abbiamo affrontato la gestione dei processi, sottolineando come esse
+diventino cogenti quando invece si usano i \textit{thread}.
 
 
 \subsection{Le operazioni atomiche}
@@ -3944,7 +4111,7 @@ 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
+altro processo o dalla ricezione di un segnale. Occorre pertanto essere
 accorti nei confronti delle possibili \itindex{race~condition} \textit{race
   condition} (vedi sez.~\ref{sec:proc_race_cond}) derivanti da operazioni
 interrotte in una fase in cui non erano ancora state completate.
@@ -3967,13 +4134,20 @@ il solo accesso o l'assegnazione di una variabile possono non essere più
 operazioni atomiche (torneremo su questi aspetti in
 sez.~\ref{sec:sig_adv_control}).
 
+Qualora invece si usino i \textit{thread}, in cui lo spazio degli indirizzi è
+condiviso, il problema è sempre presente, perché qualunque \textit{thread} può
+interromperne un altro in qualunque momento e l'atomicità di qualunque
+operazione è messa in discussione, per cui l'assenza di eventuali
+\itindex{race~condition} \textit{race condition} deve essere sempre verificata
+nei minimi dettagli.
+
 In questo caso il sistema provvede un tipo di dato, il \type{sig\_atomic\_t},
 il cui accesso è assicurato essere atomico.  In pratica comunque si può
 assumere che, in ogni piattaforma su cui è implementato Linux, il tipo
 \ctyp{int}, gli altri interi di dimensione inferiore ed i puntatori sono
 atomici. Non è affatto detto che lo stesso valga per interi di dimensioni
 maggiori (in cui l'accesso può comportare più istruzioni in assembler) o per
-le strutture. In tutti questi casi è anche opportuno marcare come
+le strutture di dati. In tutti questi casi è anche opportuno marcare come
 \direct{volatile} le variabili che possono essere interessate ad accesso
 condiviso, onde evitare problemi con le ottimizzazioni del codice.
 
@@ -4005,16 +4179,26 @@ che l'unico modo per evitarle è quello di riconoscerle come tali e prendere
 gli adeguati provvedimenti per far sì che non si verifichino. Casi tipici di
 \textit{race condition} si hanno quando diversi processi accedono allo stesso
 file, o nell'accesso a meccanismi di intercomunicazione come la memoria
-condivisa. In questi casi, se non si dispone della possibilità di eseguire
-atomicamente le operazioni necessarie, occorre che quelle parti di codice in
-cui si compiono le operazioni sulle risorse condivise (le cosiddette
+condivisa. 
+
+In questi casi, se non si dispone della possibilità di eseguire atomicamente
+le operazioni necessarie, occorre che quelle parti di codice in cui si
+compiono le operazioni sulle risorse condivise (le cosiddette
 \index{sezione~critica} \textsl{sezioni critiche}) del programma, siano
 opportunamente protette da meccanismi di sincronizzazione (torneremo su queste
 problematiche di questo tipo in cap.~\ref{cha:IPC}).
 
+Nel caso dei \textit{thread} invece la situazione è molto più delicata e
+sostanzialmente qualunque accesso in memoria (a buffer, variabili o altro) può
+essere soggetto a \textit{race condition} dato potrebbe essere interrotto in
+qualunque momento da un altro \textit{thread}. In tal caso occorre pianificare
+con estrema attenzione l'uso delle variabili ed utilizzare i vari meccanismi
+di sincronizzazione che anche in questo caso sono disponibili (torneremo su
+queste problematiche di questo tipo in cap.~\ref{sez:thread_xxx})
+
 \itindbeg{deadlock} Un caso particolare di \textit{race condition} sono poi i
-cosiddetti \textit{deadlock} (traducibile in \textsl{condizioni di stallo}),
-particolarmente gravi in quanto comportano spesso il blocco completo di un
+cosiddetti \textit{deadlock} (traducibile in \textsl{condizione di stallo}),
+che particolarmente gravi in quanto comportano spesso il blocco completo di un
 servizio, e non il fallimento di una singola operazione. Per definizione un
 \textit{deadlock} è una situazione in cui due o più processi non sono più in
 grado di proseguire perché ciascuno aspetta il risultato di una operazione che
@@ -4033,6 +4217,7 @@ In tutti questi casi è di fondamentale importanza il concetto di atomicità
 visto in sez.~\ref{sec:proc_atom_oper}; questi problemi infatti possono essere
 risolti soltanto assicurandosi, quando essa sia richiesta, che sia possibile
 eseguire in maniera atomica le operazioni necessarie.
+
 \itindend{race~condition}
 \itindend{deadlock}
 
@@ -4070,8 +4255,7 @@ parte del programmatore.
 
 In genere le funzioni di libreria non sono rientranti, molte di esse ad
 esempio utilizzano \index{variabili!statiche} variabili statiche, le
-\acr{glibc} però mettono a disposizione due macro di compilatore,\footnote{si
-  ricordi quanto illustrato in sez.~\ref{sec:intro_gcc_glibc_std}.}
+\acr{glibc} però mettono a disposizione due macro di compilatore,
 \macro{\_REENTRANT} e \macro{\_THREAD\_SAFE}, la cui definizione attiva le
 versioni rientranti di varie funzioni di libreria, che sono identificate
 aggiungendo il suffisso \code{\_r} al nome della versione normale.
@@ -4108,9 +4292,9 @@ aggiungendo il suffisso \code{\_r} al nome della versione normale.
 % LocalWords:  shmctl ioperm iopl chroot ptrace accounting swap reboot hangup
 % LocalWords:  vhangup mknod lease permitted inherited inheritable bounding AND
 % LocalWords:  capability capget capset header ESRCH undef version obj clear PT
-% LocalWords:  pag ssize length proc capgetp preemptive cache runnable 
-% LocalWords:  SIGSTOP soft slice nice niceness counter which SC
-% LocalWords:  getpriority who setpriority RTLinux RTAI Adeos fault FIFO 
+% LocalWords:  pag ssize length proc capgetp preemptive cache runnable  contest
+% LocalWords:  SIGSTOP soft slice nice niceness counter which SC switch side
+% LocalWords:  getpriority who setpriority RTLinux RTAI Adeos fault FIFO  COUNT
 % LocalWords:  yield Robin setscheduler policy param OTHER priority setparam to
 % LocalWords:  min getparam getscheduler interval robin ENOSYS fifo ping long
 % LocalWords:  affinity setaffinity unsigned mask cpu NUMA CLR ISSET SETSIZE RR
@@ -4125,7 +4309,7 @@ aggiungendo il suffisso \code{\_r} al nome della versione normale.
 % LocalWords:  waitid NOCLDSTOP ENOCHLD WIFCONTINUED ifdef endif idtype siginfo
 % LocalWords:  infop ALL WEXITED WSTOPPED WNOWAIT signo CLD EXITED KILLED page
 % LocalWords:  CONTINUED sources forking Spawned successfully executing exiting
-% LocalWords:  next cat for COMMAND pts bash defunct TRAPPED DUMPED PR
+% LocalWords:  next cat for COMMAND pts bash defunct TRAPPED DUMPED PR effects
 % LocalWords:  SIGKILL static RLIMIT preemption PREEMPT VOLUNTARY IDLE RTPRIO
 % LocalWords:  completely fair compat uniform CFQ queuing elevator dev cfq RT
 % LocalWords:  documentation block syscall ioprio IPRIO CLASS class best effort
@@ -4138,9 +4322,10 @@ aggiungendo il suffisso \code{\_r} al nome della versione normale.
 % LocalWords:  timestamp Stamp SIGSEGV UNALIGN SIGBUS MCEERR AO failure early
 % LocalWords:  namespace vsyscall SETTID FILES NEWIPC NEWNET NEWNS NEWPID ptid
 % LocalWords:  NEWUTS SETTLS SIGHAND SYSVSEM UNTRACED tls ctid CLEARTID panic
-% LocalWords:  loader EISDIR SIGTRAP uninterrutible killable
+% LocalWords:  loader EISDIR SIGTRAP uninterrutible killable EQUAL sizeof XOR
  
 %%% Local Variables: 
 %%% mode: latex
 %%% TeX-master: "gapil"
 %%% End: 
+% LocalWords:  destset srcset ALLOC num cpus setsize emacs
index 0d0e5eed9548c32ea11cfbf0aff339eaf19b9b38..d1c76cb4afefd5f5d11b9c27b84d6776dba399d5 100644 (file)
@@ -3392,6 +3392,10 @@ parte l'uso di \type{sigjmp\_buf} per \param{env}, è assolutamente identica a
 \func{longjmp}.
 
 
+% TODO: se e quando si troverà un argomento adeguato inserire altre funzioni
+% sparse attinenti ai segnali, al momento sono note solo:
+% * sigreturn (funzione interna, scarsamente interessante)
+% argomento a priorità IDLE (fare quando non resta niente altro da trattare)
 
 
 % LocalWords:  kernel POSIX timer shell control ctrl kill raise signal handler