+
+Infine Linux supporta alcune operazioni specifiche non disponibili su altri
+kernel unix-like. La prima di queste operazioni è la possibilità di modificare
+una mappatura precedente, ad esempio per espanderla o restringerla. Questo è
+realizzato dalla funzione \funcd{mremap}, il cui prototipo è:
+\begin{functions}
+ \headdecl{unistd.h}
+ \headdecl{sys/mman.h}
+
+ \funcdecl{void * mremap(void *old\_address, size\_t old\_size , size\_t
+ new\_size, unsigned long flags);}
+
+ Restringe o allarga una mappatura in memoria di un file.
+
+ \bodydesc{La funzione restituisce l'indirizzo alla nuova area di memoria in
+ caso di successo od il valore \const{MAP\_FAILED} (pari a \texttt{(void *)
+ -1}) in caso di errore, nel qual caso \var{errno} assumerà uno dei
+ valori:
+ \begin{errlist}
+ \item[\errcode{EINVAL}] Uno dei puntatori non è validi, in genere si è
+ usato un valore di \param{old\_address} non allineato ad una pagina di
+ memoria.
+ \item[\errcode{EFAULT}] Ci sono degli indirizzi non validi nell'intervallo
+ di memoria specificato dagli argomenti \param{old\_address} e
+ \param{old\_size}, o ci sono altre mappatura di un tipo non
+ corrispondente a quella richiesta.
+ \item[\errcode{ENOMEM}] Non c'è memoria sufficiente oppure l'area di
+ memoria non può essere espansa all'indirizzo virtuale corrente, e non si
+ è specificato \const{MREMAP\_MAYMOVE} nei flag.
+ \item[\errcode{EAGAIN}] Il segmento di memoria scelto è bloccato e non può
+ essere rimappato.
+ \end{errlist}
+ }
+\end{functions}
+
+La funzione richiede come argomenti \param{old\_address} che specifica il
+precedente indirizzo per la mappatura in memoria e \param{old\_size}, che ne
+indica la dimensione, con \param{new\_size} si specifica invece la nuova
+dimensione che si vuole ottenere. Questa funzione usa il meccanismo della
+\index{memoria~virtuale}memoria virtuale per modificare l'associazione fra gli
+indirizzi virtuali del processo e le pagine di memoria, modificando una
+precedente mappatura.
+
+Infine l'argomento \param{flags} è una maschera binaria per i flag che
+controllano il comportamento della funzione. Il solo valore utilizzato è
+\const{MREMAP\_MAYMOVE}\footnote{per poter utilizzare questa costante occorre
+ aver definito \macro{\_GNU\_SOURCE} prima di includere \file{sys/mman.h}.}
+che consente di eseguire l'espansione anche quando non è possibile utilizzare
+il predente indirizzo. Per questo motivo la funzione restituisce sempre
+l'indirizzo della nuova zona di memoria, che, se si è usato questo flag, non è
+detto coincida con \param{old\_address}.
+
+La mappatura in memoria di un file viene normalmente eseguita in maniera
+lineare, cioè parti successive di un file vengono mappate linearmente su
+indirizzi successivi in memoria (la prima pagina di un file viene mappata
+sulla prima pagina di memoria). Esistono però delle applicazioni\footnote{in
+ particolare la tecnica è usata dai database o dai programmi che realizzano
+ macchine virtuali.} in cui è utile poter mappare parti diverse di un file su
+diverse zone di memoria.
+
+Questo è ovviamente sempre possibile eseguendo più volte \func{mmap} per
+ciascuna delle diverse aree, ma questo approccio ha delle conseguenze molto
+pesanti in termini di prestazioni. Si ricordi infatti che il \textit{memory
+ mapping} in memoria funziona facendo ricorso al meccaniso della
+\index{memoria~virtuale} memoria virtuale per trascrivere su un file le
+operazioni effettuate sugli indirizzi di memoria sui cui esso è mappato.
+
+Per questo motivo con il kernel 2.5.46 è stato introdotto ad opera di Ingo
+Molnar un meccanismo che consente la mappatura non lineare, ed i due nuovi
+flag \const{MAP\_POPULATE} e \const{MAP\_NONBLOCK} per \func{mmap}.
+
+