+tutti i suoi \textit{memory lock}. Inoltre i \textit{memory lock} non sono
+ereditati dai processi figli, ma siccome Linux usa il \textit{copy on write}
+(vedi sez.~\ref{sec:proc_fork}) gli indirizzi virtuali del figlio sono
+mantenuti sullo stesso segmento di RAM del padre, e quindi fintanto che un
+figlio non scrive su un segmento bloccato, può usufruire del \textit{memory
+ lock} del padre. Infine i \textit{memory lock} vengono automaticamente
+rimossi se si pone in esecuzione un altro programma con \func{exec} (vedi
+sez.~\ref{sec:proc_exec}).
+
+Il sistema pone dei limiti all'ammontare di memoria di un processo che può
+essere bloccata e al totale di memoria fisica che si può dedicare a questo, lo
+standard POSIX.1 richiede che sia definita in \headfile{unistd.h} la macro
+\macrod{\_POSIX\_MEMLOCK\_RANGE} per indicare la capacità di eseguire il
+\textit{memory locking}.
+
+Siccome la richiesta di un \textit{memory lock} da parte di un processo riduce
+la memoria fisica disponibile nel sistema per gli altri processi, questo ha un
+evidente impatto su tutti gli altri processi, per cui fino al kernel 2.6.9
+solo un processo dotato di privilegi amministrativi (la \textit{capability}
+\const{CAP\_IPC\_LOCK}, vedi sez.~\ref{sec:proc_capabilities}) aveva la
+capacità di bloccare una pagina di memoria.
+
+A partire dal kernel 2.6.9 anche un processo normale può bloccare la propria
+memoria\footnote{la funzionalità è stata introdotta per non essere costretti a
+ dare privilegi eccessivi a programmi di crittografia, che necessitano di
+ questa funzionalità, ma che devono essere usati da utenti normali.} ma
+mentre un processo privilegiato non ha limiti sulla quantità di memoria che
+può bloccare, un processo normale è soggetto al limite della risorsa
+\const{RLIMIT\_MEMLOCK} (vedi sez.~\ref{sec:sys_resource_limit}). In generale
+poi ogni processo può sbloccare le pagine relative alla propria memoria, se
+però diversi processi bloccano la stessa pagina questa resterà bloccata
+fintanto che ci sarà almeno un processo che la blocca.
+
+Le funzioni di sistema per bloccare e sbloccare la paginazione di singole
+sezioni di memoria sono rispettivamente \funcd{mlock} e \funcd{munlock}; i
+loro prototipi sono:
+
+\begin{funcproto}{
+ \fhead{sys/mman.h}
+ \fdecl{int mlock(const void *addr, size\_t len)}
+ \fdesc{Blocca la paginazione su un intervallo di memoria.}
+
+ \fdecl{int munlock(const void *addr, size\_t len)}
+ \fdesc{Rimuove il blocco della paginazione su un intervallo di memoria.}
+ }
+{Entrambe le funzioni ritornano $0$ in caso di successo e $-1$ in caso di
+ errore, nel qual caso \var{errno} assumerà uno dei valori:
+ \begin{errlist}
+ \item[\errcode{EAGAIN}] una parte o tutto l'intervallo richiesto non può
+ essere bloccato per una mancanza temporanea di risorse.
+ \item[\errcode{EINVAL}] \param{len} non è un valore positivo o la somma con
+ \param{addr} causa un overflow.
+ \item[\errcode{ENOMEM}] alcuni indirizzi dell’intervallo specificato non
+ corrispondono allo spazio di indirizzi del processo o con \func{mlock} si
+ è superato il limite di \const{RLIMIT\_MEMLOCK} per un processo non
+ privilegiato (solo per kernel a partire dal 2.6.9) o si è superato il
+ limite di regioni di memoria con attributi diversi.
+ \item[\errcode{EPERM}] il processo non è privilegiato (per kernel precedenti
+ il 2.6.9) o si ha un limite nullo per \const{RLIMIT\_MEMLOCK} e
+ il processo non è privilegiato (per kernel a partire dal 2.6.9).
+ \end{errlist}}
+\end{funcproto}
+
+Le due funzioni permettono rispettivamente di bloccare e sbloccare la
+paginazione per l'intervallo di memoria iniziante all'indirizzo \param{addr} e
+lungo \param{len} byte. Al ritorno di \func{mlock} tutte le pagine che
+contengono una parte dell'intervallo bloccato sono garantite essere in RAM e
+vi verranno mantenute per tutta la durata del blocco. Con kernel diversi da
+Linux si può ottenere un errore di \errcode{EINVAL} se \param{addr} non è un
+multiplo della dimensione delle pagine di memoria, pertanto se si ha a cuore
+la portabilità si deve avere cura di allinearne correttamente il valore. Il
+blocco viene rimosso chiamando \func{munlock}.
+
+Altre due funzioni di sistema, \funcd{mlockall} e \funcd{munlockall},
+consentono di bloccare genericamente la paginazione per l'intero spazio di
+indirizzi di un processo. I prototipi di queste funzioni sono:
+
+\begin{funcproto}{
+\fhead{sys/mman.h}
+\fdecl{int mlockall(int flags)}
+\fdesc{Blocca la paginazione per lo spazio di indirizzi del processo corrente.}
+\fdecl{int munlockall(void)}
+\fdesc{Sblocca la paginazione per lo spazio di indirizzi del processo corrente.}
+}
+{Codici di ritorno ed errori sono gli stessi di \func{mlock} e \func{munlock},
+ tranne per \errcode{EINVAL} che viene restituito solo se si è specificato
+ con \func{mlockall} un valore sconosciuto per \param{flags}.}
+\end{funcproto}
+
+L'argomento \param{flags} di \func{mlockall} permette di controllarne il
+comportamento; esso deve essere specificato come maschera binaria dei valori
+espressi dalle costanti riportate in tab.~\ref{tab:mlockall_flags}.
+
+\begin{table}[htb]
+ \footnotesize
+ \centering
+ \begin{tabular}[c]{|l|p{8cm}|}
+ \hline
+ \textbf{Valore} & \textbf{Significato} \\
+ \hline
+ \hline
+ \constd{MCL\_CURRENT}& blocca tutte le pagine correntemente mappate nello
+ spazio di indirizzi del processo.\\
+ \constd{MCL\_FUTURE} & blocca tutte le pagine che verranno mappate nello
+ spazio di indirizzi del processo.\\
+ \constd{MCL\_ONFAULT}& esegue il blocco delle pagine selezionate solo
+ quando vengono utilizzate (dal kernel 4.4).\\
+ \hline
+ \end{tabular}
+ \caption{Valori e significato dell'argomento \param{flags} della funzione
+ \func{mlockall}.}
+ \label{tab:mlockall_flags}
+\end{table}
+
+Con \func{mlockall} si possono bloccare tutte le pagine mappate nello spazio
+di indirizzi del processo, sia che comprendano il segmento di testo, di dati,
+lo \textit{stack}, lo \textit{heap} e pure le funzioni di libreria chiamate, i
+file mappati in memoria, i dati del kernel mappati in user space, la memoria
+condivisa. L'uso dell'argomento \param{flags} permette di selezionare con
+maggior finezza le pagine da bloccare, ad esempio usando \const{MCL\_FUTURE}
+ci si può limitare a tutte le pagine allocate a partire dalla chiamata della
+funzione, mentre \const{MCL\_CURRENT} blocca tutte quelle correntemente
+mappate. L'uso di \func{munlockall} invece sblocca sempre tutte le pagine di
+memoria correntemente mappate nello spazio di indirizzi del programma.
+
+A partire dal kernel 4.4 alla funzione \func{mlockall} è stato aggiunto un
+altro flag, \const{MCL\_ONFAULT}, che può essere abbinato a entrambi gli altri
+due flag, e consente di modificare il comportamento della funzione per
+ottenere migliori prestazioni.
+
+Il problema che si presenta infatti è che eseguire un \textit{memory lock} per
+un intervallo ampio di memoria richiede che questa venga comunque allocata in
+RAM, con altrettanti \textit{page fault} che ne assicurino la presenza; questo
+vale per tutto l'intervallo e può avere un notevole costo in termini di
+prestazioni, anche quando poi, nell'esecuzione del programma, venisse usata
+solo una piccola parte dello stesso. L'uso di \const{MCL\_ONFAULT} previene il
+\textit{page faulting} immediato di tutto l'intervallo, le pagine
+dell'intervallo verranno bloccate, ma solo quando un \textit{page fault}
+dovuto all'accesso ne richiede l'allocazione effettiva in RAM.
+
+Questo stesso comportamento non è ottenibile con \func{mlock}, che non dispone
+di un argomento \param{flag} che consenta di richiederlo, per questo sempre
+con il kernel 4.4 è stata aggiunta una ulteriore funzione di sistema,
+\funcd{mlock2}, il cui prototipo è:
+
+\begin{funcproto}{
+ \fhead{sys/mman.h}
+ \fdecl{int mlock2(const void *addr, size\_t len, int flags)}
+ \fdesc{Blocca la paginazione su un intervallo di memoria.}
+}
+{Le funzione ritornano $0$ in caso di successo e $-1$ in caso di errore, nel
+ qual caso \var{errno} assume gli stessi valori di \func{mlock} con
+ l'aggiunta id un possibile \errcode{EINVAL} anche se si è indicato un valore
+ errato di \param{flags}.}
+\end{funcproto}
+
+% NOTA: per mlock2, introdotta con il kernel 4.4 (vedi
+% http://lwn.net/Articles/650538/)
+
+Indicando un valore nullo per \param{flags} il comportamento della funzione è
+identico a quello di \func{mlock}, l'unico altro valore possibile è
+\constd{MLOCK\_ONFAULT} che ha lo stesso effetto sull'allocazione delle pagine
+in RAM già descritto per \const{MCL\_ONFAULT}.
+
+Si tenga presente che un processo \textit{real-time} che intende usare il
+\textit{memory locking} con \func{mlockall} per prevenire l'avvenire di un
+eventuale \textit{page fault} ed il conseguente rallentamento (probabilmente
+inaccettabile) dei tempi di esecuzione, deve comunque avere delle accortezze.
+In particolare si deve assicurare di aver preventivamente bloccato una
+quantità di spazio nello \textit{stack} sufficiente a garantire l'esecuzione
+di tutte le funzioni che hanno i requisiti di criticità sui tempi. Infatti,
+anche usando \const{MCL\_FUTURE}, in caso di allocazione di una nuova pagina
+nello \textit{stack} durante l'esecuzione di una funzione (precedentemente non
+usata e quindi non bloccata) si potrebbe avere un \textit{page fault}.
+
+In genere si ovvia a questa problematica chiamando inizialmente una funzione
+che definisca una quantità sufficientemente ampia di variabili automatiche
+(che si ricordi vengono allocate nello \textit{stack}) e ci scriva, in modo da
+esser sicuri che le corrispondenti pagine vengano mappate nello spazio di
+indirizzi del processo, per poi bloccarle. La scrittura è necessaria perché il
+kernel usa il meccanismo di \textit{copy on write} (vedi
+sez.~\ref{sec:proc_fork}) e le pagine potrebbero non essere allocate
+immediatamente.
+
+\itindend{memory~locking}
+\index{memoria~virtuale|)}
+
+
+\subsection{Gestione avanzata dell'allocazione della memoria}
+\label{sec:proc_memory_adv_management}
+
+La trattazione delle funzioni di allocazione di sez.~\ref{sec:proc_mem_alloc}
+si è limitata a coprire le esigenze generiche di un programma, in cui non si
+hanno dei requisiti specifici e si lascia il controllo delle modalità di
+allocazione alle funzioni di libreria. Tuttavia esistono una serie di casi in
+cui può essere necessario avere un controllo più dettagliato delle modalità
+con cui la memoria viene allocata; nel qual caso potranno venire in aiuto le
+funzioni trattate in questa sezione.
+
+Le prime funzioni che tratteremo sono quelle che consentono di richiedere di
+allocare un blocco di memoria ``\textsl{allineato}'' ad un multiplo una certa
+dimensione. Questo tipo di esigenza emerge usualmente quando si devono
+allocare dei buffer da utilizzare per eseguire dell'I/O diretto su dispositivi
+a blocchi. In questo caso infatti il trasferimento di dati viene eseguito per
+blocchi di dimensione fissa, ed è richiesto che l'indirizzo di partenza del
+buffer sia un multiplo intero di questa dimensione, usualmente 512 byte. In
+tal caso l'uso di \func{malloc} non è sufficiente, ed occorre utilizzare una
+funzione specifica.
+
+Tradizionalmente per rispondere a questa esigenza sono state create due
+funzioni diverse, \funcd{memalign} e \funcd{valloc}, oggi obsolete, cui si
+aggiunge \funcd{pvalloc} come estensione GNU, anch'essa obsoleta; i rispettivi
+prototipi sono:
+
+\begin{funcproto}{
+\fhead{malloc.h}
+\fdecl{void *valloc(size\_t size)}
+\fdesc{Alloca un blocco di memoria allineato alla dimensione di una pagina di
+ memoria.}
+\fdecl{void *memalign(size\_t boundary, size\_t size)}
+\fdesc{Alloca un blocco di memoria allineato ad un multiplo
+ di \param{boundary}.}
+\fdecl{void *pvalloc(size\_t size)}
+\fdesc{Alloca un blocco di memoria allineato alla dimensione di una pagina di
+ memoria.}
+}
+{Entrambe le funzioni ritornano un puntatore al blocco di memoria allocato in
+ caso di successo e \val{NULL} in caso di errore, nel qual caso \var{errno}
+ assumerà uno dei valori:
+ \begin{errlist}
+ \item[\errcode{EINVAL}] \param{boundary} non è una potenza di due.
+ \item[\errcode{ENOMEM}] non c'è memoria sufficiente per l'allocazione.
+ \end{errlist}}
+\end{funcproto}
+
+Le funzioni restituiscono il puntatore al buffer di memoria allocata di
+dimensioni pari a \param{size}, che per \func{memalign} sarà un multiplo di
+\param{boundary} mentre per \func{valloc} un multiplo della dimensione di una
+pagina di memoria; lo stesso vale per \func{pvalloc} che però arrotonda
+automaticamente la dimensione dell'allocazione al primo multiplo di una
+pagina. Nel caso della versione fornita dalla \acr{glibc} la memoria allocata
+con queste funzioni deve essere liberata con \func{free}, cosa che non è detto
+accada con altre implementazioni.
+
+Nessuna delle due funzioni ha una chiara standardizzazione e nessuna delle due
+compare in POSIX.1, inoltre ci sono indicazioni discordi sui file che ne
+contengono la definizione;\footnote{secondo SUSv2 \func{valloc} è definita in
+ \headfile{stdlib.h}, mentre sia la \acr{glibc} che le precedenti \acr{libc4}
+ e \acr{libc5} la dichiarano in \headfile{malloc.h}, lo stesso vale per
+ \func{memalign} che in alcuni sistemi è dichiarata in \headfile{stdlib.h}.}
+per questo motivo il loro uso è sconsigliato, essendo state sostituite dalla
+nuova \funcd{posix\_memalign}, che è stata standardizzata in POSIX.1d e
+disponibile dalla \acr{glibc} 2.1.91; il suo prototipo è:
+
+\begin{funcproto}{
+\fhead{stdlib.h}
+\fdecl{posix\_memalign(void **memptr, size\_t alignment, size\_t size)}
+\fdesc{Alloca un buffer di memoria allineato ad un multiplo
+ di \param{alignment}.}
+}
+{Entrambe le funzioni ritornano un puntatore al blocco di memoria allocato in
+ caso di successo e \val{NULL} in caso di errore, nel qual caso \var{errno}
+ assumerà uno dei valori:
+ \begin{errlist}
+ \item[\errcode{EINVAL}] \param{alignment} non è potenza di due o un multiplo
+ di \code{sizeof(void *)}.
+ \item[\errcode{ENOMEM}] non c'è memoria sufficiente per l'allocazione.
+ \end{errlist}}
+\end{funcproto}
+
+La funzione restituisce il puntatore al buffer allocato di dimensioni pari
+a \param{size} nella variabile (di tipo \texttt{void *}) posta all'indirizzo
+indicato da \param{memptr}. La funzione fallisce nelle stesse condizioni delle
+due funzioni precedenti, ma a loro differenza restituisce direttamente come
+valore di ritorno il codice di errore. Come per le precedenti la memoria
+allocata con \func{posix\_memalign} deve essere disallocata con \func{free},
+che in questo caso però è quanto richiesto dallo standard.
+
+Dalla versione 2.16 della \acr{glibc} è stata aggiunta anche la funzione
+\funcd{aligned\_alloc}, prevista dallo standard C11 (e disponibile definendo
+\const{\_ISOC11\_SOURCE}), il cui prototipo è:
+
+\begin{funcproto}{
+\fhead{malloc.h}
+\fdecl{void *aligned\_alloc(size\_t alignment, size\_t size)}
+\fdesc{Alloca un blocco di memoria allineato ad un multiplo
+ di \param{alignment}.}
+}
+{La funzione ha gli stessi valori di ritorno e codici di errore di
+ \func{memalign}.}
+\end{funcproto}
+
+La funzione è identica a \func{memalign} ma richiede che \param{size} sia un
+multiplo di \param{alignment}. Infine si tenga presente infine che nessuna di
+queste funzioni inizializza il buffer di memoria allocato, il loro
+comportamento cioè è analogo, allineamento a parte, a quello di \func{malloc}.
+
+Un secondo caso in cui risulta estremamente utile poter avere un maggior
+controllo delle modalità di allocazione della memoria è quello in cui cercano
+errori di programmazione. Esempi di questi errori sono i \textit{double free},
+o i cosiddetti \itindex{buffer~overrun} \textit{buffer overrun}, cioè le
+scritture su un buffer oltre le dimensioni della sua
+allocazione,\footnote{entrambe queste operazioni causano in genere la
+ corruzione dei dati di controllo delle funzioni di allocazione, che vengono
+ anch'essi mantenuti nello \textit{heap} per tenere traccia delle zone di
+ memoria allocata.} o i classici \textit{memory leak}.
+
+Abbiamo visto in sez.~\ref{sec:proc_mem_lock} come una prima funzionalità di
+ausilio nella ricerca di questi errori sia l'uso della variabile di ambiente
+\envvar{MALLOC\_CHECK\_}. Una modalità alternativa per effettuare dei
+controlli di consistenza sullo stato delle allocazioni di memoria eseguite con
+\func{malloc}, anche questa fornita come estensione specifica (e non standard)
+della \acr{glibc}, è quella di utilizzare la funzione \funcd{mcheck}, che deve
+essere chiamata prima di eseguire qualunque allocazione con \func{malloc}; il
+suo prototipo è:
+
+\begin{funcproto}{
+\fhead{mcheck.h}
+\fdecl{int mcheck(void (*abortfn) (enum mcheck\_status status))}
+\fdesc{Attiva i controlli di consistenza delle allocazioni di memoria.}
+}
+{La funzione ritorna $0$ in caso di successo e $-1$ per un errore;
+ \var{errno} non viene impostata.}
+\end{funcproto}
+
+La funzione consente di registrare una funzione di emergenza che verrà
+eseguita tutte le volte che, in una successiva esecuzione di \func{malloc},
+venissero trovate delle inconsistenze, come delle operazioni di scrittura
+oltre i limiti dei buffer allocati. Per questo motivo la funzione deve essere
+chiamata prima di qualunque allocazione di memoria, altrimenti fallirà.
+
+Se come primo argomento di \func{mcheck} si passa \val{NULL} verrà utilizzata
+una funzione predefinita che stampa un messaggio di errore ed invoca la
+funzione \func{abort} (vedi sez.~\ref{sec:sig_alarm_abort}), altrimenti si
+dovrà creare una funzione personalizzata in grado di ricevere il tipo di
+errore ed agire di conseguenza.
+
+Nonostante la scarsa leggibilità del prototipo si tratta semplicemente di
+definire una funzione di tipo \code{void abortfn(enum mcheck\_status status)},
+che non deve restituire nulla e che deve avere un unico argomento di tipo
+\code{mcheck\_status}. In caso di errore la funzione verrà eseguita ricevendo
+un opportuno valore di \param{status} che è un tipo enumerato che può assumere
+soltanto i valori di tab.~\ref{tab:mcheck_status_value} che indicano la
+tipologia di errore riscontrata.
+
+\begin{table}[htb]
+ \centering
+ \footnotesize
+ \begin{tabular}[c]{|l|p{7cm}|}
+ \hline
+ \textbf{Valore} & \textbf{Significato} \\
+ \hline
+ \hline
+ \constd{MCHECK\_OK} & Riportato a \func{mprobe} se nessuna
+ inconsistenza è presente.\\
+ \constd{MCHECK\_DISABLED}& Riportato a \func{mprobe} se si è chiamata
+ \func{mcheck} dopo aver già usato
+ \func{malloc}.\\
+ \constd{MCHECK\_HEAD} & I dati immediatamente precedenti il buffer sono
+ stati modificati, avviene in genere quando si
+ decrementa eccessivamente il valore di un
+ puntatore scrivendo poi prima dell'inizio del
+ buffer.\\
+ \constd{MCHECK\_TAIL} & I dati immediatamente seguenti il buffer sono
+ stati modificati, succede quando si va scrivere
+ oltre la dimensione corretta del buffer.\\
+ \constd{MCHECK\_FREE} & Il buffer è già stato disallocato.\\
+ \hline
+ \end{tabular}
+ \caption{Valori dello stato dell'allocazione di memoria ottenibili dalla
+ funzione di terminazione installata con \func{mcheck}.}
+ \label{tab:mcheck_status_value}
+\end{table}
+
+Una volta che si sia chiamata \func{mcheck} con successo si può anche
+controllare esplicitamente lo stato delle allocazioni senza aspettare un
+errore nelle relative funzioni utilizzando la funzione \funcd{mprobe}, il cui
+prototipo è:
+
+\begin{funcproto}{
+\fhead{mcheck.h}
+\fdecl{enum mcheck\_status mprobe(ptr)}
+\fdesc{Esegue un controllo di consistenza delle allocazioni.}
+}
+{La funzione ritorna un codice fra quelli riportati in
+ tab.~\ref{tab:mcheck_status_value} e non ha errori.}
+\end{funcproto}
+
+La funzione richiede che si passi come argomento un puntatore ad un blocco di
+memoria precedentemente allocato con \func{malloc} o \func{realloc}, e
+restituisce lo stesso codice di errore che si avrebbe per la funzione di
+emergenza ad una successiva chiamata di una funzione di allocazione, e poi i
+primi due codici che indicano rispettivamente quando tutto è a posto o il
+controllo non è possibile per non aver chiamato \func{mcheck} in tempo.
+
+% TODO: trattare le altre funzionalità avanzate di \func{malloc}, mallopt,
+% mtrace, muntrace, mallinfo e gli hook con le glibc 2.10 c'è pure malloc_info
+% a sostituire mallinfo, vedi http://udrepper.livejournal.com/20948.html
+
+
+\section{Argomenti, ambiente ed altre proprietà di un processo}
+\label{sec:proc_options}