+\begin{table}[htb]
+ \centering
+ \footnotesize
+ \begin{tabular}[c]{|l|p{6cm}|}
+ \hline
+ \textbf{Politica} & \textbf{Significato} \\
+ \hline
+ \hline
+ \const{SCHED\_FIFO} & \textit{Scheduling real-time} con politica
+ \textit{FIFO}. \\
+ \const{SCHED\_RR} & \textit{Scheduling real-time} con politica
+ \textit{Round Robin}. \\
+ \hline
+ \const{SCHED\_OTHER}& \textit{Scheduling} ordinario.\\
+ \const{SCHED\_BATCH}& \textit{Scheduling} ordinario con l'assunzione
+ ulteriore di lavoro \textit{CPU
+ intensive} (dal kernel 2.6.16)\\
+ \const{SCHED\_IDLE} & \textit{Scheduling} di priorità estremamente
+ bassa (dal kernel 2.6.23)\\
+ \hline
+ \end{tabular}
+ \caption{Valori dell'argomento \param{policy} per la funzione
+ \func{sched\_setscheduler}.}
+ \label{tab:proc_sched_policy}
+\end{table}
+
+Con le versioni più recenti del kernel sono state introdotte anche delle
+varianti sulla politica di \textit{scheduling} tradizionale per alcuni carichi
+di lavoro specifici, queste due nuove politiche sono specifiche di Linux e non
+devono essere usate se si vogliono scrivere programmi portabili.
+
+La politica \const{SCHED\_BATCH} è una variante della politica ordinaria con
+la sola differenza che i processi ad essa soggetti non ottengono, nel calcolo
+delle priorità dinamiche fatto dallo scheduler, il cosiddetto bonus di
+interattività che mira a favorire i processi che si svegliano dallo stato di
+\textit{sleep}.\footnote{cosa che accade con grande frequenza per i processi
+ interattivi, dato che essi sono per la maggior parte del tempo in attesa di
+ dati in ingresso da parte dell'utente.} La si usa pertanto, come indica il
+nome, per processi che usano molta CPU (come programmi di calcolo) che in
+questo modo sono leggermente sfavoriti rispetto ai processi interattivi che
+devono rispondere a dei dati in ingresso, pur non perdendo il loro valore di
+\textit{nice}.
+
+La politica \const{SCHED\_IDLE} invece è una politica dedicata ai processi che
+si desidera siano eseguiti con la più bassa priorità possibile, ancora più
+bassa di un processo con il minimo valore di \textit{nice}. In sostanza la si
+può utilizzare per processi che devono essere eseguiti se non c'è niente altro
+da fare. Va comunque sottolineato che anche un processo \const{SCHED\_IDLE}
+avrà comunque una sua possibilità di utilizzo della CPU, sia pure in
+percentuale molto bassa.
+
+Qualora si sia richiesta una politica \textit{real-time} il valore della
+priorità statica viene impostato attraverso la struttura
+\struct{sched\_param}, riportata in fig.~\ref{fig:sig_sched_param}, il cui
+solo campo attualmente definito è \var{sched\_priority}. Il campo deve
+contenere il valore della priorità statica da assegnare al processo; lo
+standard prevede che questo debba essere assegnato all'interno di un
+intervallo fra un massimo ed un minimo che nel caso di Linux sono
+rispettivamente 1 e 99.
+
+\begin{figure}[!htbp]
+ \footnotesize \centering
+ \begin{minipage}[c]{0.5\textwidth}
+ \includestruct{listati/sched_param.c}
+ \end{minipage}
+ \normalsize
+ \caption{La struttura \structd{sched\_param}.}
+ \label{fig:sig_sched_param}
+\end{figure}
+
+I processi con politica di \textit{scheduling} ordinaria devono sempre
+specificare un valore nullo di \var{sched\_priority} altrimenti si avrà un
+errore \errcode{EINVAL}, questo valore infatti non ha niente a che vedere con
+la priorità dinamica determinata dal valore di \textit{nice}, che deve essere
+impostato con le funzioni viste in precedenza.
+
+Lo standard POSIX.1b prevede comunque che l'intervallo dei valori delle
+priorità statiche possa essere ottenuto con le funzioni di sistema
+\funcd{sched\_get\_priority\_max} e \funcd{sched\_get\_priority\_min}, i cui
+prototipi sono:
+
+\begin{funcproto}{
+\fhead{sched.h}
+\fdecl{int sched\_get\_priority\_max(int policy)}
+\fdesc{Legge il valore massimo di una priorità statica.}
+\fdecl{int sched\_get\_priority\_min(int policy)}
+\fdesc{Legge il valore minimo di una priorità statica.}
+}
+{Le funzioni ritornano il valore della priorità in caso di successo e $-1$ per
+ un errore, nel qual caso \var{errno} assumerà il valore:
+\begin{errlist}
+\item[\errcode{EINVAL}] il valore di \param{policy} non è valido.
+\end{errlist}}
+\end{funcproto}
+
+Le funzioni ritornano rispettivamente i due valori della massima e minima
+priorità statica possano essere ottenuti per una delle politiche di
+\textit{scheduling} \textit{real-time} indicata dall'argomento \param{policy}.
+
+Si tenga presente che quando si imposta una politica di \textit{scheduling}
+real-time per un processo o se ne cambia la priorità statica questo viene
+messo in cima alla lista dei processi con la stessa priorità; questo comporta
+che verrà eseguito subito, interrompendo eventuali altri processi con la
+stessa priorità in quel momento in esecuzione.
+
+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 è \const{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.
+
+Solo un processo con i privilegi di amministratore\footnote{più precisamente
+ con la \itindex{capabilities} capacità \const{CAP\_SYS\_NICE}, vedi
+ sez.~\ref{sec:proc_capabilities}.} può impostare senza restrizioni priorità
+assolute diverse da zero o politiche \const{SCHED\_FIFO} e
+\const{SCHED\_RR}. Un utente normale può modificare solo le priorità di
+processi che gli appartengono; è cioè richiesto che l'\ids{UID} effettivo del
+processo chiamante corrisponda all'\ids{UID} reale o effettivo del processo
+indicato con \param{pid}.
+
+Fino al kernel 2.6.12 gli utenti normali non potevano impostare politiche
+\textit{real-time} o modificare la eventuale priorità statica di un loro
+processo. A partire da questa versione è divenuto possibile anche per gli
+utenti normali usare politiche \textit{real-time} fintanto che la priorità
+assoluta che si vuole impostare è inferiore al limite \const{RLIMIT\_RTPRIO}
+(vedi sez.~\ref{sec:sys_resource_limit}) ad essi assegnato.
+
+Unica eccezione a questa possibilità sono i processi \const{SCHED\_IDLE}, che
+non possono cambiare politica di \textit{scheduling} indipendentemente dal
+valore di \const{RLIMIT\_RTPRIO}. Inoltre, in caso di processo già sottoposto
+ad una politica \textit{real-time}, un utente può sempre, indipendentemente
+dal valore di \const{RLIMIT\_RTPRIO}, diminuirne la priorità o portarlo ad una
+politica ordinaria.
+
+Se si intende operare solo sulla priorità statica di un processo si possono
+usare le due funzioni di sistema \funcd{sched\_setparam} e
+\funcd{sched\_getparam} che consentono rispettivamente di impostarne e
+leggerne il valore, i loro prototipi sono:
+
+\begin{funcproto}{
+\fhead{sched.h}
+\fdecl{int sched\_setparam(pid\_t pid, const struct sched\_param *param)}
+\fdesc{Imposta la priorità statica di un processo.}
+\fdecl{int sched\_getparam(pid\_t pid, struct sched\_param *param)}
+\fdesc{Legge la priorità statica di un processo.}
+}
+{Le funzioni ritornano $0$ in caso di successo e $-1$ per un errore, nel qual
+caso \var{errno} assumerà uno dei valori:
+\begin{errlist}
+\item[\errcode{EINVAL}] il valore di \param{param} non ha senso per la
+ politica usata dal processo.
+\item[\errcode{EPERM}] non si hanno privilegi sufficienti per eseguire
+ l'operazione.
+\item[\errcode{ESRCH}] il processo \param{pid} non esiste.
+\end{errlist}}
+\end{funcproto}
+
+Le funzioni richiedono di indicare nell'argomento \param{pid} il processo su
+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}.
+
+L'uso di \func{sched\_setparam}, compresi i controlli di accesso che vi si
+applicano, è del tutto equivalente a quello di \func{sched\_setscheduler} con
+argomento \param{policy} uguale a $-1$. Come per \func{sched\_setscheduler}
+specificando $0$ come valore dell'argomento \param{pid} si opera sul processo
+corrente. Benché la funzione sia utilizzabile anche con processi sottoposti a
+politica ordinaria essa ha senso soltanto per quelli \textit{real-time}, dato
+che per i primi la priorità statica può essere soltanto nulla. La
+disponibilità di entrambe le funzioni può essere verificata controllando la
+macro \macro{\_POSIX\_PRIORITY\_SCHEDULING} che è definita nell'\textit{header
+ file} \headfile{sched.h}.
+
+Se invece si vuole sapere quale è politica di \textit{scheduling} di un
+processo si può usare la funzione di sistema \funcd{sched\_getscheduler}, il
+cui prototipo è:
+
+\begin{funcproto}{
+\fhead{sched.h}
+\fdecl{int sched\_getscheduler(pid\_t pid)}
+\fdesc{Legge la politica di \textit{scheduling}.}
+}
+{La funzione ritorna la politica di \textit{scheduling} in caso di successo e
+ $-1$ per un errore, nel qual caso \var{errno} assumerà uno dei valori:
+\begin{errlist}
+ \item[\errcode{EPERM}] non si hanno privilegi sufficienti per eseguire
+ l'operazione.
+ \item[\errcode{ESRCH}] il processo \param{pid} non esiste.
+\end{errlist}}
+\end{funcproto}
+
+La funzione restituisce il valore, secondo quanto elencato in
+tab.~\ref{tab:proc_sched_policy}, della politica di \textit{scheduling} per il
+processo specificato dall'argomento \param{pid}, se questo è nullo viene
+restituito il valore relativo al processo chiamante.
+
+L'ultima funzione di sistema che permette di leggere le informazioni relative
+ai processi real-time è \funcd{sched\_rr\_get\_interval}, che permette di
+ottenere la lunghezza della \textit{time-slice} usata dalla politica
+\textit{round robin}; il suo prototipo è:
+
+\begin{funcproto}{
+\fhead{sched.h}
+\fdecl{int sched\_rr\_get\_interval(pid\_t pid, struct timespec *tp)}
+\fdesc{Legge la durata della \textit{time-slice} per lo \textit{scheduling}
+ \textit{round robin}.}
+}
+{La funzione ritorna $0$ in caso di successo e $-1$ per un errore, nel qual
+caso \var{errno} assumerà uno dei valori:
+\begin{errlist}
+\item[\errcode{EINVAL}] l'argomento \param{pid} non è valido.
+\item[\errcode{ENOSYS}] la \textit{system call} non è presente (solo per
+ kernel arcaici).
+\item[\errcode{ESRCH}] il processo \param{pid} non esiste.
+\end{errlist}
+ed inoltre anche \errval{EFAULT} nel suo significato generico.}
+\end{funcproto}
+
+La funzione restituisce nell'argomento \param{tp} come una struttura
+\struct{timespec}, (la cui definizione si può trovare in
+fig.~\ref{fig:sys_timeval_struct}) il valore dell'intervallo di tempo usato
+per la politica \textit{round robin} dal processo indicato da \ids{PID}. Il
+valore dipende dalla versione del kernel, a lungo infatti questo intervallo di
+tempo era prefissato e non modificabile ad un valore di 150 millisecondi,
+restituito indipendentemente dal \ids{PID} indicato.
+
+Con kernel recenti però è possibile ottenere una variazione della
+\textit{time-slice}, modificando il valore di \textit{nice} del processo
+(anche se questo non incide assolutamente sulla priorità statica) che come
+accennato in precedenza modifica il valore assegnato alla \textit{time-slice}
+di un processo ordinario, che però viene usato anche dai processi
+\textit{real-time}.
+
+Come accennato ogni processo può rilasciare volontariamente la CPU in modo da
+consentire agli altri processi di essere eseguiti; la funzione di sistema che
+consente di fare tutto questo è \funcd{sched\_yield}, il cui prototipo è:
+
+\begin{funcproto}{
+\fhead{sched.h}
+\fdecl{int sched\_yield(void)}
+\fdesc{Rilascia volontariamente l'esecuzione.}
+}
+{La funzione ritorna $0$ in caso di successo e teoricamente $-1$ per un
+ errore, ma su Linux ha sempre successo.}
+\end{funcproto}
+
+
+Questa funzione ha un utilizzo effettivo soltanto quando si usa lo
+\textit{scheduling} \textit{real-time}, e serve a far sì che il processo
+corrente rilasci la CPU, in modo da essere rimesso in coda alla lista dei
+processi con la stessa priorità per permettere ad un altro di essere eseguito;
+se però il processo è l'unico ad essere presente sulla coda l'esecuzione non
+sarà interrotta. In genere usano questa funzione i processi con politica
+\const{SCHED\_FIFO}, per permettere l'esecuzione degli altri processi con pari
+priorità quando la sezione più urgente è finita.
+
+La funzione può essere utilizzata anche con processi che usano lo
+\textit{scheduling} ordinario, ma in questo caso il comportamento non è ben
+definito, e dipende dall'implementazione. Fino al kernel 2.6.23 questo
+comportava che i processi venissero messi in fondo alla coda di quelli attivi,
+con la possibilità di essere rimessi in esecuzione entro breve tempo, con
+l'introduzione del \textit{Completely Fair Scheduler} questo comportamento è
+cambiato ed un processo che chiama la funzione viene inserito nella lista dei
+processi inattivo, con un tempo molto maggiore.\footnote{è comunque possibile
+ ripristinare un comportamento analogo al precedente scrivendo il valore 1
+ nel file \sysctlfile{kernel/sched\_compat\_yield}.}
+
+L'uso delle funzione nella programmazione ordinaria può essere utile e
+migliorare le prestazioni generali del sistema quando si è appena rilasciata
+una risorsa contesa con altri processi, e si vuole dare agli altri una
+possibilità di approfittarne mettendoli in esecuzione, ma chiamarla senza
+necessità, specie se questo avviene ripetutamente all'interno di un qualche
+ciclo, può avere invece un forte impatto negativo per la generazione di
+\itindex{contest~switch} \textit{contest switch} inutili.
+
+
+\subsection{Il controllo dello \textit{scheduler} per i sistemi
+ multiprocessore}
+\label{sec:proc_sched_multiprocess}
+
+Con il supporto dei sistemi multiprocessore sono state introdotte delle
+funzioni che permettono di controllare in maniera più dettagliata la scelta di
+quale processore utilizzare per eseguire un certo programma. Uno dei problemi
+che si pongono nei sistemi multiprocessore è infatti quello del cosiddetto
+\index{effetto~ping-pong} \textsl{effetto ping-pong}. Può accadere cioè che lo
+\textit{scheduler}, quando riavvia un processo precedentemente interrotto
+scegliendo il primo processore disponibile, lo faccia eseguire da un
+processore diverso rispetto a quello su cui era stato eseguito in
+precedenza. Se il processo passa da un processore all'altro in questo modo,
+cosa che avveniva abbastanza di frequente con i kernel della seria 2.4.x, si
+ha l'\textsl{effetto ping-pong}.
+
+Questo tipo di comportamento può generare dei seri problemi di prestazioni;
+infatti tutti i processori moderni utilizzano una memoria interna (la
+\textit{cache}) contenente i dati più usati, che permette di evitare di
+eseguire un accesso (molto più lento) alla memoria principale sulla scheda
+madre. Chiaramente un processo sarà favorito se i suoi dati sono nella cache
+del processore, ma è ovvio che questo può essere vero solo per un processore
+alla volta, perché in presenza di più copie degli stessi dati su più
+processori, non si potrebbe determinare quale di questi ha la versione dei
+dati aggiornata rispetto alla memoria principale.
+
+Questo comporta che quando un processore inserisce un dato nella sua cache,
+tutti gli altri processori che hanno lo stesso dato devono invalidarlo, e
+questa operazione è molto costosa in termini di prestazioni. Il problema
+diventa serio quando si verifica l'\textsl{effetto ping-pong}, in tal caso
+infatti un processo \textsl{rimbalza} continuamente da un processore all'altro
+e si ha una continua invalidazione della cache, che non diventa mai
+disponibile.
+
+\itindbeg{CPU~affinity}
+
+Per ovviare a questo tipo di problemi è nato il concetto di \textsl{affinità
+ di processore} (o \textit{CPU affinity}); la possibilità cioè di far sì che
+un processo possa essere assegnato per l'esecuzione sempre allo stesso
+processore. Lo \textit{scheduler} dei kernel della serie 2.4.x aveva una
+scarsa \textit{CPU affinity}, e \index{effetto~ping-pong} l'effetto ping-pong
+era comune; con il nuovo \textit{scheduler} dei kernel della 2.6.x questo
+problema è stato risolto ed esso cerca di mantenere il più possibile ciascun
+processo sullo stesso processore.
+
+In certi casi però resta l'esigenza di poter essere sicuri che un processo sia
+sempre eseguito dallo stesso processore,\footnote{quella che viene detta
+ \textit{hard CPU affinity}, in contrasto con quella fornita dallo
+ \textit{scheduler}, detta \textit{soft CPU affinity}, che di norma indica
+ solo una preferenza, non un requisito assoluto.} e per poter risolvere
+questo tipo di problematiche nei nuovi kernel\footnote{le due \textit{system
+ call} per la gestione della \textit{CPU affinity} sono state introdotte
+ nel kernel 2.5.8, e le corrispondenti funzioni di sistema nella
+ \textsl{glibc} 2.3.} è stata introdotta l'opportuna infrastruttura ed una
+nuova \textit{system call} che permette di impostare su quali processori far
+eseguire un determinato processo attraverso una \textsl{maschera di
+ affinità}. La corrispondente funzione di sistema è
+\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 setsize,
+ cpu\_set\_t *mask)}
+\fdesc{Imposta la maschera di affinità di un processo.}
+}
+{La funzione ritorna $0$ in caso di successo e $-1$ per un errore, nel qual
+caso \var{errno} assumerà uno dei valori:
+\begin{errlist}
+\item[\errcode{EINVAL}] il valore di \param{mask} contiene riferimenti a
+ processori non esistenti nel sistema o a cui non è consentito l'accesso.
+\item[\errcode{EPERM}] il processo non ha i privilegi sufficienti per
+ eseguire l'operazione.
+\item[\errcode{ESRCH}] il processo \param{pid} non esiste.
+\end{errlist}
+ed inoltre anche \errval{EFAULT} nel suo significato generico.}
+\end{funcproto}
+
+Questa funzione e la corrispondente \func{sched\_getaffinity} hanno una storia
+abbastanza complessa, la sottostante \textit{system call} infatti prevede
+l'uso di due soli argomenti (per il pid e l'indicazione della maschera dei
+processori), che corrispondono al fatto che l'implementazione effettiva usa
+una semplice maschera binaria. Quando le funzioni vennero incluse nella
+\acr{glibc} assunsero invece un prototipo simile a quello mostrato però con il
+secondo argomento di tipo \ctyp{unsigned int}. A complicare la cosa si
+aggiunge il fatto che nella versione 2.3.3 della \acr{glibc} detto argomento
+venne stato eliminato, per poi essere ripristinato nella versione 2.3.4 nella
+forma attuale.\footnote{pertanto se la vostra pagina di manuale non è
+ aggiornata, o usate quella particolare versione della \acr{glibc}, potrete
+ trovare indicazioni diverse, il prototipo illustrato è quello riportato
+ nella versione corrente (maggio 2008) delle pagine di manuale e
+ corrispondente alla definizione presente in \headfile{sched.h}.}
+
+La funzione imposta, con l'uso del valore contenuto all'indirizzo
+\param{mask}, l'insieme dei processori sui quali deve essere eseguito il
+processo identificato tramite il valore passato in \param{pid}. Come in
+precedenza il valore nullo di \param{pid} indica il processo corrente. Per
+poter utilizzare questa funzione sono richiesti i privilegi di amministratore
+(è necessaria la capacità \const{CAP\_SYS\_NICE}) altrimenti essa fallirà con
+un errore di \errcode{EPERM}. Una volta impostata una maschera di affinità,
+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 successivi alla 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
+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
+velocità, e con questa interfaccia diventa possibile selezionare gruppi di
+processori utilizzabili in maniera esclusiva. Lo stesso dicasi quando
+l'accesso a certe risorse (memoria o periferiche) può avere un costo diverso a
+seconda del processore, come avviene nelle architetture NUMA
+(\textit{Non-Uniform Memory Access}).
+
+Infine se un gruppo di processi accede alle stesse risorse condivise (ad
+esempio una applicazione con più \itindex{thread} \textit{thread}) può avere
+senso usare lo stesso processore in modo da sfruttare meglio l'uso della sua
+cache; questo ovviamente riduce i benefici di un sistema multiprocessore
+nell'esecuzione contemporanea dei \itindex{thread} \textit{thread}, ma in
+certi casi (quando i \itindex{thread} \textit{thread} sono inerentemente
+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.
+
+Dato che il numero di processori può variare a seconda delle architetture, per
+semplificare l'uso dell'argomento \param{mask} la \acr{glibc} ha introdotto un
+apposito dato di tipo, \type{cpu\_set\_t},\footnote{questa è una estensione
+ specifica della \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 è 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 \index{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 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 di processori \param{set}.}
+\fdecl{void \macro{CPU\_CLR}(int cpu, cpu\_set\_t *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 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}}
+
+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:
+
+{\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}}
+
+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 corrente usando la funzione di sistema
+\funcd{sched\_getaffinity}, il cui prototipo è:
+
+\begin{funcproto}{
+\fhead{sched.h}
+\fdecl{int sched\_getaffinity (pid\_t pid, size\_t setsize,
+ cpu\_set\_t *mask)}
+\fdesc{Legge la maschera di affinità di un processo.}
+}
+{La funzione ritorna $0$ in caso di successo e $-1$ per un errore, nel qual
+caso \var{errno} assumerà uno dei valori:
+\begin{errlist}
+\item[\errcode{EINVAL}] \param{setsize} è più piccolo delle dimensioni
+ della maschera di affinità usata dal kernel.
+\item[\errcode{ESRCH}] il processo \param{pid} non esiste.
+\end{errlist}
+ed inoltre anche \errval{EFAULT} nel suo significato generico.}
+\end{funcproto}
+
+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.
+
+È 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.
+
+
+\itindend{scheduler}
+\itindend{CPU~affinity}
+
+
+\subsection{Le priorità per le operazioni di I/O}
+\label{sec:io_priority}
+
+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 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 \textit{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 nella \acr{glibc} per queste due
+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
+\textit{system call} sono \funcd{ioprio\_get} ed \funcd{ioprio\_set}; i
+rispettivi prototipi sono:
+
+\begin{funcproto}{
+\fhead{linux/ioprio.h}
+\fdecl{int ioprio\_get(int which, int who)}
+\fdesc{Legge la priorità di I/O di un processo.}
+\fdecl{int ioprio\_set(int which, int who, int ioprio)}
+\fdesc{Imposta la priorità di I/O di un processo.}
+}
+{Le funzioni ritornano rispettivamente un intero positivo o 0 in caso di
+ successo e $-1$ per un errore, nel qual caso \var{errno} assumerà uno dei
+ valori:
+\begin{errlist}
+\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}).
+\item[\errcode{ESRCH}] non esiste un processo corrispondente alle indicazioni.
+\end{errlist}}
+\end{funcproto}
+
+Le funzioni leggono o impostano la priorità di I/O sulla base dell'indicazione
+dei due argomenti \param{which} e \param{who} che hanno lo stesso significato
+già visto per gli omonimi argomenti di \func{getpriority} e
+\func{setpriority}. Anche in questo caso si deve specificare il valore
+di \param{which} tramite le opportune costanti riportate in
+tab.~\ref{tab:ioprio_args} che consentono di indicare un singolo processo, i
+processi di un \textit{process group} (tratteremo questo argomento in
+sez.~\ref{sec:sess_proc_group}) o tutti i processi di un utente.
+
+\begin{table}[htb]
+ \centering
+ \footnotesize
+ \begin{tabular}[c]{|c|c|l|}
+ \hline
+ \param{which} & \param{who} & \textbf{Significato} \\
+ \hline
+ \hline
+ \const{IPRIO\_WHO\_PROCESS} & \type{pid\_t} & processo\\
+ \const{IPRIO\_WHO\_PRGR} & \type{pid\_t} & \itindex{process~group}
+ \textit{process group}\\
+ \const{IPRIO\_WHO\_USER} & \type{uid\_t} & utente\\
+ \hline
+ \end{tabular}
+ \caption{Legenda del valore dell'argomento \param{which} e del tipo
+ dell'argomento \param{who} delle funzioni \func{ioprio\_get} e
+ \func{ioprio\_set} per le tre possibili scelte.}
+ \label{tab:ioprio_args}
+\end{table}
+
+In caso di successo \func{ioprio\_get} restituisce un intero positivo che
+esprime il valore della priorità di I/O, questo valore è una maschera binaria
+composta da due parti, una che esprime la \textsl{classe} di
+\textit{scheduling} di I/O del processo, l'altra che esprime, quando la classe
+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}.
+\begin{table}[htb]
+ \centering
+ \footnotesize
+ \begin{tabular}[c]{|l|p{8cm}|}
+ \hline
+ \textbf{Macro} & \textbf{Significato}\\
+ \hline
+ \hline
+ \macro{IOPRIO\_PRIO\_CLASS}\texttt{(\textit{value})}
+ & Dato il valore di una priorità come
+ restituito da \func{ioprio\_get} estrae il
+ valore della classe.\\
+ \macro{IOPRIO\_PRIO\_DATA}\texttt{(\textit{value})}
+ & Dato il valore di una priorità come
+ restituito da \func{ioprio\_get} estrae il
+ valore della priorità.\\
+ \macro{IOPRIO\_PRIO\_VALUE}\texttt{(\textit{class},\textit{prio})}
+ & Dato un valore di priorità ed una classe
+ ottiene il valore numerico da passare a
+ \func{ioprio\_set}.\\
+ \hline
+ \end{tabular}
+ \caption{Le macro per la gestione dei valori numerici .}
+ \label{tab:IOsched_class_macro}
+\end{table}
+
+
+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
+ \begin{tabular}[c]{|l|l|}
+ \hline
+ \textbf{Classe} & \textbf{Significato} \\
+ \hline
+ \hline
+ \const{IOPRIO\_CLASS\_RT} & \textit{Scheduling} di I/O \textit{real-time}.\\
+ \const{IOPRIO\_CLASS\_BE} & \textit{Scheduling} di I/O ordinario.\\
+ \const{IOPRIO\_CLASS\_IDLE}& \textit{Scheduling} di I/O di priorità minima.\\
+ \hline
+ \end{tabular}
+ \caption{Costanti che identificano le classi di \textit{scheduling} di I/O.}
+ \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,
+perché un processo in questa classe può venire completamente bloccato quando
+ci sono altri processi in una qualunque delle altre due classi che stanno
+accedendo al disco. Quando si usa questa classe non ha senso indicare un
+valore di priorità, dato che in questo caso non esiste nessuna gerarchia e la
+priorità è identica, la minima possibile, per tutti i processi.
+
+La seconda classe di priorità di I/O è \const{IOPRIO\_CLASS\_BE} (il nome sta
+per \textit{best-effort}) che è quella usata ordinariamente da tutti
+processi. In questo caso esistono priorità diverse che consentono di
+assegnazione di una maggiore banda passante nell'accesso a disco ad un
+processo rispetto agli altri, con meccanismo simile a quello dei valori di
+\textit{nice} in cui si evita che un processo a priorità più alta possa
+bloccare indefinitamente quelli a priorità più bassa. In questo caso però le
+diverse priorità sono soltanto otto, indicate da un valore numerico fra 0 e 7
+e come per \textit{nice} anche in questo caso un valore più basso indica una
+priorità maggiore.
+
+
+Infine la classe di priorità di I/O \textit{real-time}
+\const{IOPRIO\_CLASS\_RT} ricalca le omonime priorità di processore: un
+processo in questa classe ha sempre la precedenza nell'accesso a disco
+rispetto a tutti i processi delle altre classi e di un processo nella stessa
+classe ma con priorità inferiore, ed è pertanto in grado di bloccare
+completamente tutti gli altri. Anche in questo caso ci sono 8 priorità diverse
+con un valore numerico fra 0 e 7, con una priorità più elevata per valori più
+bassi.
+
+In generale nel funzionamento ordinario la priorità di I/O di un processo
+viene impostata in maniera automatica nella classe \const{IOPRIO\_CLASS\_BE}
+con un valore ottenuto a partire dal corrispondente valore di \textit{nice}
+tramite la formula: $\mathtt{\mathit{prio}}=(\mathtt{\mathit{nice}}+20)/5$. Un
+utente ordinario può modificare con \func{ioprio\_set} soltanto le priorità
+dei processi che gli appartengono,\footnote{per la modifica delle priorità di
+ altri processi occorrono privilegi amministrativi, ed in particolare la
+ capacità \const{CAP\_SYS\_NICE} (vedi sez.~\ref{sec:proc_capabilities}).}
+cioè quelli il cui \ids{UID} reale corrisponde all'\ids{UID} reale o effettivo
+del chiamante. Data la possibilità di ottenere un blocco totale del sistema,
+solo l'amministratore\footnote{o un processo con la capacità
+ \const{CAP\_SYS\_ADMIN} (vedi sez.~\ref{sec:proc_capabilities}).} può
+impostare un processo ad una priorità di I/O nella classe
+\const{IOPRIO\_CLASS\_RT}, lo stesso privilegio era richiesto anche per la
+classe \const{IOPRIO\_CLASS\_IDLE} fino al kernel 2.6.24, ma dato che in
+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/
+\section{Funzioni di gestione avanzata}
+\label{sec:proc_advanced_control}
+
+Nelle precedenti sezioni si sono trattate la gran parte delle funzioni che
+attengono alla gestione ordinaria dei processi e delle loro proprietà più
+comuni. Tratteremo qui alcune \textit{system call} dedicate alla gestione di
+funzionalità dei processi molto specifiche ed avanzate, il cui uso è in genere
+piuttosto ridotto. Trattandosi di problematiche abbastanza complesse, che
+spesso presuppongono la conoscenza di altri argomenti trattati nel seguito
+della guida, si può saltare questa sezione in una prima lettura, tornando su
+di essa in un secondo tempo.
+
+
+\subsection{La funzione \func{prctl}}
+\label{sec:process_prctl}
+
+Benché la gestione ordinaria possa essere effettuata attraverso le funzioni
+che abbiamo già esaminato nelle sezioni precedenti, esistono una serie di
+proprietà e caratteristiche particolari dei processi non coperte da esse, per
+la cui gestione è stata predisposta una apposita \textit{system call} che
+fornisce una interfaccia generica per tutte le operazioni specialistiche. La
+funzione di sistema è \funcd{prctl} ed il suo prototipo è:\footnote{la
+ funzione non è standardizzata ed è specifica di Linux, anche se ne esiste
+ una analoga in IRIX; è stata introdotta con il kernel 2.1.57.}
+
+\begin{funcproto}{
+\fhead{sys/prctl.h}
+\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
+ caso di successo e $-1$ per un errore, nel qual caso \var{errno} assumerà
+ valori diversi a seconda del tipo di operazione richiesta (in genere
+ \errval{EINVAL} o \errval{EPERM}).}
+\end{funcproto}
+
+La funzione ritorna un valore nullo o positivo in caso di successo e $-1$ in
+caso di errore; il significato degli argomenti della funzione successivi al
+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:\footnote{alla stesura di questa sezione, cioè con il kernel 3.2.}
+
+\begin{basedescript}{\desclabelwidth{2.cm}\desclabelstyle{\nextlinelabel}}
+\item[\const{PR\_CAPBSET\_READ}] Controlla la disponibilità di una delle
+ \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
+ \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}
+ \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
+ sez.~\ref{sec:sig_standard}) lo genera effettivamente. In genere questo flag
+ viene attivato automaticamente, ma per evitare problemi di sicurezza (la
+ generazione di un file da parte di processi privilegiati può essere usata
+ 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 \ids{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 \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 \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 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 ``\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:
+ \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 ``\ctyp{int *}''. Introdotta
+ a partire dal kernel 2.4.21, solo su PowerPC.
+
+\item[\const{PR\_SET\_KEEPCAPS}] Consente di controllare quali
+ \itindex{capabilities} \textit{capabilities} vengono cancellate quando si
+ esegue un cambiamento di \ids{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
+ mantenute, questo valore viene sempre cancellato attraverso una \func{exec}.
+ L'uso di questo flag è stato sostituito, a partire dal kernel 2.6.26, dal
+ 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 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 ``\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 ``\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
+ il ruolo di \signal{SIGCHLD}. Il valore di \param{arg2} deve indicare il
+ 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 ``\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 \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 \funcm{sigreturn}. Ogni altra \textit{system
+ call} porterà all'emissione di un \signal{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 \itindex{secure~computing~mode}
+ \textit{secure computing mode} comporterebbe l'emissione di
+ \signal{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 \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}, 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 (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
+ valore di \param{arg2}. Si deve specificare \const{PR\_TSC\_ENABLE} per
+ 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 \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 ``\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
+ valore \const{PR\_UNALIGN\_NOPRINT} per ignorare gli accessi non allineati,
+ 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
+ diverse versioni su diverse architetture.
+\item[\const{PR\_MCE\_KILL}] Imposta la politica di gestione degli errori
+ dovuti a corruzione della memoria per problemi hardware. Questo tipo di
+ errori vengono riportati dall'hardware di controllo della RAM e vengono
+ gestiti dal kernel,\footnote{la funzionalità è disponibile solo sulle
+ piattaforme più avanzate che hanno il supporto hardware per questo tipo di
+ controlli.} ma devono essere opportunamente riportati ai processi che
+ usano quella parte di RAM che presenta errori; nel caso specifico questo
+ avviene attraverso l'emissione di un segnale di \signal{SIGBUS} (vedi
+ sez.~\ref{sec:sig_prog_error}).\footnote{in particolare viene anche
+ impostato il valore di \var{si\_code} in \struct{siginfo\_t} a
+ \const{BUS\_MCEERR\_AO}; per il significato di tutto questo si faccia
+ riferimento alla trattazione di sez.~\ref{sec:sig_sigaction}.}
+
+ Il comportamento di default prevede che per tutti i processi si applichi la
+ politica generale di sistema definita nel file
+ \sysctlfile{vm/memory\_failure\_early\_kill}, ma specificando
+ per \param{arg2} il valore \const{PR\_MCE\_KILL\_SET} è possibile impostare
+ con il contenuto di \param{arg3} una politica specifica del processo
+ chiamante. Si può tornare alla politica di default del sistema utilizzando
+ invece per \param{arg2} il valore \const{PR\_MCE\_KILL\_CLEAR}. In tutti i
+ casi, per compatibilità con eventuali estensioni future, tutti i valori
+ degli argomenti non utilizzati devono essere esplicitamente posti a zero,
+ pena il fallimento della chiamata con un errore di \errval{EINVAL}.
+
+ In caso di impostazione di una politica specifica del processo con
+ \const{PR\_MCE\_KILL\_SET} i valori di \param{arg3} possono essere soltanto
+ due, che corrispondono anche al valore che si trova nell'impostazione
+ generale di sistema di \texttt{memory\_failure\_early\_kill}, con
+ \const{PR\_MCE\_KILL\_EARLY} si richiede l'emissione immediata di
+ \signal{SIGBUS} non appena viene rilevato un errore, mentre con
+ \const{PR\_MCE\_KILL\_LATE} il segnale verrà inviato solo quando il processo
+ tenterà un accesso alla memoria corrotta. Questi due valori corrispondono
+ rispettivamente ai valori 1 e 0 di
+ \texttt{memory\_failure\_early\_kill}.\footnote{in sostanza nel primo caso
+ viene immediatamente inviato il segnale a tutti i processi che hanno la
+ memoria corrotta mappata all'interno del loro spazio degli indirizzi, nel
+ secondo caso prima la pagina di memoria viene tolta dallo spazio degli
+ indirizzi di ciascun processo, mentre il segnale viene inviato solo quei
+ processi che tentano di accedervi.} Si può usare per \param{arg3} anche un
+ terzo valore, \const{PR\_MCE\_KILL\_DEFAULT}, che corrisponde a impostare
+ per il processo la politica di default.\footnote{si presume la politica di
+ default corrente, in modo da non essere influenzati da un eventuale
+ successivo cambiamento della stessa.} Introdotta a partire dal kernel
+ 2.6.32.
+\item[\const{PR\_MCE\_KILL\_GET}] Ottiene come valore di ritorno della
+ funzione la politica di gestione degli errori dovuti a corruzione della
+ memoria. Tutti gli argomenti non utilizzati (al momento tutti) devono essere
+ nulli pena la ricezione di un errore di \errval{EINVAL}. Introdotta a
+ partire dal kernel 2.6.32.
+\label{sec:prctl_operation}
+\end{basedescript}
+
+
+
+\subsection{La \textit{system call} \func{clone}}
+\label{sec:process_clone}
+
+La funzione tradizionale con cui creare un nuovo processo in un sistema
+Unix-like, come illustrato in sez.~\ref{sec:proc_fork}, è \func{fork}, ma con
+l'introduzione del supporto del kernel per i \textit{thread} (vedi
+cap.~\ref{cha:threads}), si è avuta la necessità di una interfaccia che
+consentisse un maggiore controllo sulla modalità con cui vengono creati nuovi
+processi, che poi è stata utilizzata anche per fornire supporto per le
+tecnologie di virtualizzazione dei processi (i cosiddetti \textit{container}).
+
+Per questo l'interfaccia per la creazione di un nuovo processo è stata
+delegata ad una nuova \textit{system call}, \funcm{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 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 \ids{PID},
+l'albero dei file, i \itindex{mount~point} \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
+primo, \param{flags}, consente di controllare le modalità di creazione del
+nuovo \textit{task}, il secondo, \param{child\_stack}, imposta l'indirizzo
+dello \itindex{stack} \textit{stack} per il nuovo \textit{task}, e deve essere
+indicato quando si intende creare un \textit{thread}. L'esecuzione del
+programma creato da \func{sys\_clone} riprende, come per \func{fork}, da
+dopo l'esecuzione della stessa.
+
+La necessità di avere uno \itindex{stack} \textit{stack} alternativo c'è solo
+quando si intende creare un \textit{thread}, in tal caso infatti il nuovo
+\textit{task} vede esattamente la stessa memoria del \textit{task}
+``\textsl{padre}'',\footnote{in questo caso per padre si intende semplicemente
+ il \textit{task} che ha eseguito \func{sys\_clone} rispetto al \textit{task}
+ da essa creato, senza nessuna delle implicazioni che il concetto ha per i
+ processi.} e nella sua esecuzione alla prima chiamata di una funzione
+andrebbe a scrivere sullo \textit{stack} usato anche dal padre (si ricordi
+quanto visto in sez.~\ref{sec:proc_mem_layout} riguardo all'uso dello
+\textit{stack}).
+
+Per evitare di doversi garantire contro la evidente possibilità di
+\itindex{race~condition} \textit{race condition} che questa situazione
+comporta (vedi sez.~\ref{sec:proc_race_cond} per una spiegazione della
+problematica) è necessario che il chiamante allochi preventivamente un'area di
+memoria. In genere lo si fa con una \func{malloc} che allochi un buffer che
+la funzione imposterà come \textit{stack} del nuovo processo, avendo
+ovviamente cura di non utilizzarlo direttamente nel processo chiamante.
+
+In questo modo i due \textit{task} avranno degli \textit{stack} indipendenti e
+non si dovranno affrontare problematiche di \itindex{race~condition}
+\textit{race condition}. Si tenga presente inoltre che in molte architetture
+di processore lo \textit{stack} cresce verso il basso, pertanto in tal caso
+non si dovrà specificare per \param{child\_stack} il puntatore restituito da
+\func{malloc}, ma un puntatore alla fine del buffer da essa allocato.
+
+Dato che tutto ciò è necessario solo per i \textit{thread} che condividono la
+memoria, la \textit{system call}, a differenza della funzione di libreria che
+vedremo a breve, consente anche di passare per \param{child\_stack} il valore
+\val{NULL}, che non imposta un nuovo \textit{stack}. Se infatti si crea un
+processo, questo ottiene un suo nuovo spazio degli indirizzi,\footnote{è
+ sottinteso cioè che non si stia usando il flag \const{CLONE\_VM} che vedremo
+ a breve.} ed in questo caso si applica la semantica del
+\itindex{copy~on~write} \textit{copy on write} illustrata in
+sez.~\ref{sec:proc_fork}, per cui le pagine dello \textit{stack} verranno
+automaticamente copiate come le altre e il nuovo processo avrà un suo
+\textit{stack} totalmente indipendente da quello del padre.
+
+Dato che l'uso principale della nuova \textit{system call} è quello relativo
+alla creazione dei \textit{thread}, la \acr{glibc} definisce una funzione di
+libreria con una sintassi diversa, orientata a questo scopo, e la
+\textit{system call} resta accessibile solo se invocata esplicitamente come
+visto in sez.~\ref{sec:proc_syscall}.\footnote{ed inoltre per questa
+ \textit{system call} non è disponibile la chiamata veloce con
+ \texttt{vsyscall}.} La funzione di libreria si chiama semplicemente
+\funcd{clone} ed il suo prototipo è:
+
+\begin{funcproto}{
+\fhead{sched.h}
+\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
+ di successo e $-1$ per un errore, nel qual caso \var{errno} assumerà uno dei
+ valori:
+\begin{errlist}
+ \item[\errcode{EAGAIN}] sono già in esecuzione troppi processi.
+ \item[\errcode{EINVAL}] si è usata una combinazione non valida di flag o
+ un valore nullo per \param{child\_stack}.
+ \item[\errcode{ENOMEM}] non c'è memoria sufficiente per creare una nuova
+ \struct{task\_struct} o per copiare le parti del contesto del chiamante
+ necessarie al nuovo \textit{task}.
+ \item[\errcode{EPERM}] non si hanno i privilegi di amministratore
+ richiesti dai flag indicati.
+\end{errlist}}
+\end{funcproto}
+
+% NOTE: una pagina con la descrizione degli argomenti:
+% * http://www.lindevdoc.org/wiki/Clone
+
+La funzione prende come primo argomento \param{fn} il puntatore alla funzione
+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 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
+di ritorno della funzione (o quello specificato con \func{exit}) verrà
+utilizzato come stato di uscita della funzione. I tre
+argomenti \param{ptid}, \param{tls} e \param{ctid} sono opzionali e sono
+presenti solo a partire dal kernel 2.6 e sono stati aggiunti come supporto per
+le funzioni di gestione dei \textit{thread} (la \textit{Native Thread Posix
+ Library}, vedi sez.~\ref{sec:linux_ntpl}) nella \acr{glibc}, essi vengono
+utilizzati soltanto se si sono specificati rispettivamente i flag
+\const{CLONE\_PARENT\_SETTID}, \const{CLONE\_SETTLS} e
+\const{CLONE\_CHILD\_SETTID}.
+
+La funzione ritorna un l'identificatore del nuovo \textit{task}, denominato
+\texttt{Thread ID} (da qui in avanti \ids{TID}) il cui significato è analogo
+al \ids{PID} dei normali processi e che a questo corrisponde qualora si crei
+un processo.
+
+Il comportamento di \func{clone}, che si riflette sulle caratteristiche del
+nuovo processo da essa creato, è controllato principalmente
+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{si fa
+ riferimento al momento della stesura di questa sezione, cioè con il kernel
+ 3.2.}
+
+\begin{basedescript}{\desclabelwidth{2.cm}\desclabelstyle{\nextlinelabel}}
+
+\item[\const{CLONE\_CHILD\_CLEARTID}] cancella il valore del \ids{TID}
+\item[\const{CLONE\_CHILD\_SETTID}]
+\item[\const{CLONE\_FILES}]
+\item[\const{CLONE\_FS}]
+\item[\const{CLONE\_IO}]
+\item[\const{CLONE\_NEWIPC}]
+\item[\const{CLONE\_NEWNET}]
+\item[\const{CLONE\_NEWNS}]
+\item[\const{CLONE\_NEWPID}]
+\item[\const{CLONE\_NEWUTS}]
+\item[\const{CLONE\_PARENT}]
+\item[\const{CLONE\_PARENT\_SETTID}]
+\item[\const{CLONE\_PID}]
+\item[\const{CLONE\_PTRACE}]
+\item[\const{CLONE\_SETTLS}]
+\item[\const{CLONE\_SIGHAND}]
+\item[\const{CLONE\_STOPPED}]
+\item[\const{CLONE\_SYSVSEM}]
+\item[\const{CLONE\_THREAD}]
+\item[\const{CLONE\_UNTRACED}]
+\item[\const{CLONE\_VFORK}]
+\item[\const{CLONE\_VM}]
+\end{basedescript}
+
+
+%TODO trattare unshare
+
+
+\subsection{La funzione \func{ptrace}}
+\label{sec:process_ptrace}
+
+Da fare
+
+% TODO: trattare PTRACE_SEIZE, aggiunta con il kernel 3.1
+
+
+\subsection{La gestione delle operazioni in virgola mobile}
+\label{sec:process_fenv}
+
+Da fare.
+
+% TODO eccezioni ed arrotondamenti per la matematica in virgola mobile
+% consultare la manpage di fenv, math_error, fpclassify, matherr, isgreater,
+% isnan, nan, INFINITY
+
+
+\subsection{L'accesso alle porte di I/O}
+\label{sec:process_io_port}
+
+%
+% 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
+
+
+%\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...