X-Git-Url: https://gapil.gnulinux.it/gitweb/?p=gapil.git;a=blobdiff_plain;f=process.tex;h=0ca84e1ae3d4d6fea72496775311966a3bffbdf5;hp=45363c591eb6a225a0df92e6c41d4d717f15ad26;hb=4504f0bd1ad5cb4b933e6ee80a767103e517376f;hpb=b68aa96c16958fda51be7ce0fc43ff51b1171342 diff --git a/process.tex b/process.tex index 45363c5..0ca84e1 100644 --- a/process.tex +++ b/process.tex @@ -521,7 +521,6 @@ confronti di piccoli errori come quello di chiamate doppie a \texttt{free}; in pparticolare se la variabile è posta a zero gli errori vengono ignorati, se è posta ad 1 viene stampato un avviso sullo standard error e se - Il problema più comune e più difficile da tracciare che si incontra con l'allocazione della memoria è però quando la memoria non più utilizzata non viene opportunamente liberata (quello che in inglese viene chiamato @@ -559,25 +558,105 @@ segmento di stack della funzione corrente. La sintassi ma in questo caso non è più necessario liberare la memoria in quanto questa viene rilasciata automaticamente al ritorno della funzione. -Come è evidente questa funzione ha molti vantaggi, in particolare in Linux -la funzione è molto veloce ed occupa poco spazio, essendo codificata -direttamente dentro il compilatore, inoltre +Come è evidente questa funzione ha molti vantaggi, e permette di evitare i +problemi di memory leak non essendo più necessaria la deallocazione esplicita; +una delle ragioni principali per usarla è però che funziona anche quando si +usa \texttt{longjump} per uscire con un salto non locale da una funzione (vedi +\secref{sec:proc_longjmp}), + +Un altro vantaggio e che in Linux la funzione è molto veloce e non viene +sprecato spazio, infatti non è necessario gestire un pool di memoria da +riservare e si evitano anche problemi di frammentazione. + +Gli svantaggi sono che la funzione non è disponibile su tutti gli unix quando +non è possibile aumentare le dimensioni dello stack una volta chiamata una +funzione e quindi l'uso limita la portabilità dei programmi, inoltre se si +cerca di allocare troppa memoria non si ottiene un messaggio di errore, ma un +segnale di \textit{segmentation violation} analogo a quello che si avrebbe da +una ricorsione infinita. \subsection{Le funzioni \texttt{brk} e \texttt{sbrk}} \label{sec:proc_mem_sbrk} +L'uso di queste funzioni è necessario solo quando si voglia accedere alle +analoghe system call a cui fanno da interfaccia (ad esempio per implementare +una propria versione di \texttt{malloc}. Le funzione sono: +\begin{prototype}{unistd.h}{int *brk(void end\_data\_segment)} + Sposta la fine del segmento dei dati all'indirizzo specificato da + \texttt{end\_data\_segment}. + + La funzione restituisce 0 in caso di successo e -1 in caso di fallimento, + nel qual caso \texttt{errno} viene settata a \texttt{ENOMEM}. +\end{prototype} +\begin{prototype}{unistd.h}{int *sbrk(ptrdiff\_t increment)} + Incrementa lo spazio dati di un programma di \texttt{increment}. Un valore + zero restituisce l'attuale posizione della fine del segmento dati. + + La funzione restituisce il puntatore all'inzio della nuova zona di memoria + allocata in caso di successo e \texttt{NULL} in caso di fallimento, nel qual + caso \texttt{errno} viene settata a \texttt{ENOMEM}. +\end{prototype} + +Queste funzioni sono state deliberatamente escluse dallo standard POSIX.1 e +per i programmi normali è opportuno usare le funzioni di allocazione standard +descritte in precedenza, che sono costruite su di esse. In genere si usa +\texttt{sbrk} con un valore zero per ottenere l'attuale posizione della fine +del segmento dati. + -\subsection{La personalizzazione delle funzioni di allocazione} -\label{sec:proc_mem_malloc_custom} +% \subsection{La personalizzazione delle funzioni di allocazione} +% \label{sec:proc_mem_malloc_custom} \subsection{Il controllo della memoria virtuale} \label{sec:proc_mem_mlock} +Come spiegato in \secref{sec:proc_mem_gen} il kernel gestisce la memoria in +maniera trasparente ai processi, decidendo quando rimuovere pagine dalla +memoria per metterle nello swap sulla base dell'utilizzo corrente da parte dei +vari processi. + +Nell'uso comune un processo non deve preoccuparsi di tutto ciò in quanto il +meccanismo della paginazione riporta in RAM, ed in maniera trasparente, tutte +le pagine che gli occorrono; esistono però esigenze particolari in cui non si +vuole che il meccanismo dello \textit{swapping}, in generale i motivi per cui +si possono avere queste necessità sono sostanzialmente due: +\begin{itemize} +\item La velocità. Il processo della paginazione è trasparente solo se il + programma in esecuzione se non è sensibile al tempo che occorre a riportare + la pagina in memoria; per questo motivi processi critici che hanno esigenze + di tempo reale o tolleranze critiche nella risposte (ad esempio processi che + trattano campionamenti sonori) possono non essere in grado di sopportare + le variazioni della velocità di accesso dovuta alla paginazione. + + In certi casi poi un programmatore può conoscere meglio dell'algoritmo di + allocazione delle pagine le esigenze specifiche del suo programma e decidere + quali pagine di memoria è opportuno che restino in memoria per un aumento + delle prestazioni. In genere queste sono esigenze particolari e richiedono + anche un aumento delle priorità in esecuzione (vedi \secref{sec:xxx_xxx}). + +\item La sicurezza. Se si tengono password o chiavi in memoria queste possono + essere portate su disco dal meccanismo della paginazione, questo rende più + lungo il periodo di tempo in cui i segreti sono presenti in chiaro, e + complessa la loro cancellazione (in genere è possibile cancellare della ram + ma altrettanto non vale per il disco su cui la pagina contenente i segreti + può essere stata salvata). Per questo motivo programmi di crittografia + richiedono il blocco di alcune pagine di memoria. +\end{itemize} \section{Il controllo di flusso non locale} -\label{sec:proc_flux} +\label{sec:proc_longjmp} + +Il controllo del flusso di un programma in genere viene effettuato con le +varie istruzioni del linguaggio C, la più bistrattata delle quali è il +\texttt{goto} ampiamente deprecato in favore di costrutti più puliti; esiste +però un caso in l'uso di questa istruzione porta all'implementazione più +efficiente, quello dell'uscita in caso di errore. + +Il C però non consente di effettuare un salto ad una label definita in +un'altra funzione, per cui se l'errore avviene in funzioni profondamente +annidate \section{La gestione di parametri e opzioni}