Rilettura e correzioni prima parte.
[gapil.git] / process.tex
index 8aba3c23ddacf3fd17e31c6ccb6049f873537ae1..f14150aa94728ffda3e09f31c8d270eda6ec0e28 100644 (file)
@@ -36,7 +36,7 @@ tutte le parti uguali siano condivise), avrà un suo spazio di indirizzi,
 variabili proprie e sarà eseguito in maniera completamente indipendente da
 tutti gli altri. Questo non è del tutto vero nel caso di un programma
 \textit{multi-thread}, ma la gestione dei \textit{thread} in Linux sarà
-trattata a parte in cap.~\ref{cha:threads}.
+trattata a parte\unavref{in cap.~\ref{cha:threads}}.
 
 
 \subsection{L'avvio e l'esecuzione di un programma}
@@ -44,9 +44,9 @@ trattata a parte in cap.~\ref{cha:threads}.
 
 \itindbeg{link-loader}
 \itindbeg{shared~objects}
-Quando un programma viene messo in esecuzione cosa che può essere fatta solo
-con una funzione della famiglia \func{exec} (vedi sez.~\ref{sec:proc_exec}) il
-kernel esegue un opportuno codice di avvio, il cosiddetto
+Quando un programma viene messo in esecuzione, cosa che può essere fatta solo
+con una funzione della famiglia \func{exec} (vedi sez.~\ref{sec:proc_exec}),
+il kernel esegue un opportuno codice di avvio, il cosiddetto
 \textit{link-loader}, costituito dal programma \cmd{ld-linux.so}. Questo
 programma è una parte fondamentale del sistema il cui compito è quello della
 gestione delle cosiddette \textsl{librerie condivise}, quelle che nel mondo
@@ -64,15 +64,15 @@ una sola volta per tutti i programmi che lo usano.
 Questo significa però che normalmente il codice di un programma è incompleto,
 contenendo solo i riferimenti alle funzioni di libreria che vuole utilizzare e
 non il relativo codice. Per questo motivo all'avvio del programma è necessario
-l'intervento del \textit{link-loader} il cui compito è
-caricare in memoria le librerie condivise eventualmente assenti, ed effettuare
-poi il collegamento dinamico del codice del programma alle funzioni di
-libreria da esso utilizzate prima di metterlo in esecuzione.
+l'intervento del \textit{link-loader} il cui compito è caricare in memoria le
+librerie condivise eventualmente assenti, ed effettuare poi il collegamento
+dinamico del codice del programma alle funzioni di libreria da esso utilizzate
+prima di metterlo in esecuzione.
 
 Il funzionamento di \cmd{ld-linux.so} è controllato da alcune variabili di
-ambiente e dal contenuto del file \conffile{/etc/ld.so.conf}, che consentono
-di elencare le directory un cui cercare le librerie e determinare quali
-verranno utilizzate.  In particolare con la variabile di ambiente
+ambiente e dal contenuto del file \conffile{/etc/ld.so.conf} che consentono di
+elencare le directory un cui cercare le librerie e determinare quali verranno
+utilizzate.  In particolare con la variabile di ambiente
 \envvar{LD\_LIBRARY\_PATH} si possono indicare ulteriori directory rispetto a
 quelle di sistema in cui inserire versioni personali delle librerie che hanno
 la precedenza su quelle di sistema, mentre con la variabile di ambiente
@@ -292,18 +292,28 @@ una qualunque funzione ordinaria, la situazione è totalmente diversa
 nell'esecuzione del programma. Una funzione ordinaria infatti viene eseguita,
 esattamente come il codice che si è scritto nel corpo del programma, in
 \textit{user space}. Quando invece si esegue una \textit{system call}
-l'esecuzione ordinaria del programma viene interrotta, i dati forniti (come
-argomenti della chiamata) vengono trasferiti al kernel che esegue il codice
-della \textit{system call} (che è codice del kernel) in \textit{kernel space}.
+l'esecuzione ordinaria del programma viene interrotta con quello che viene
+usualmente chiamato un \itindex{context~switch} \textit{context
+  switch};\footnote{in realtà si parla più comunemente di \textit{context
+    switch} quando l'esecuzione di un processo viene interrotta dal kernel
+  (tramite lo \textit{scheduler}) per metterne in esecuzione un altro, ma il
+  concetto generale resta lo stesso: l'esecuzione del proprio codice in
+  \textit{user space} viene interrotta e lo stato del processo deve essere
+  salvato per poterne riprendere l'esecuzione in un secondo tempo.}  il
+contesto di esecuzione del processo viene salvato in modo da poterne
+riprendere in seguito l'esecuzione ed i dati forniti (come argomenti della
+chiamata) vengono trasferiti al kernel che esegue il codice della
+\textit{system call} (che è codice del kernel) in \textit{kernel space}; al
+completamento della \textit{system call} i dati salvati nel \textit{context
+  switch} saranno usati per riprendere l'esecuzione ordinaria del programma.
 
 Dato che il passaggio dei dati ed il salvataggio del contesto di esecuzione
-del programma che consentirà di riprenderne l'esecuzione ordinaria al
-completamento della \textit{system call} sono operazioni critiche per le
-prestazioni del sistema, per rendere il più veloce possibile questa
-operazione, usualmente chiamata \textit{context switch} sono state sviluppate
-una serie di ottimizzazioni che richiedono alcune preparazioni abbastanza
-complesse dei dati, che in genere dipendono dall'architettura del processore
-sono scritte direttamente in \textit{assembler}.
+sono operazioni critiche per le prestazioni del sistema, per rendere il più
+veloce possibile questa operazione sono state sviluppate una serie di
+ottimizzazioni che richiedono alcune preparazioni abbastanza complesse dei
+dati, che in genere dipendono dall'architettura del processore e sono scritte
+direttamente in \textit{assembler}.
+
 
 %
 % TODO:trattare qui, quando sarà il momento vsyscall e vDSO, vedi:
@@ -325,14 +335,19 @@ associazione, e lavorare a basso livello con una specifica versione, oppure si
 può voler utilizzare una \textit{system call} che non è stata ancora associata
 ad una funzione di libreria.  In tal caso, per evitare di dover effettuare
 esplicitamente le operazioni di preparazione citate, all'interno della
-\textsl{glibc} è fornita una specifica funzione, \funcd{syscall}, che consente
-eseguire direttamente una \textit{system call}; il suo prototipo, accessibile
-se si è definita la macro \macro{\_GNU\_SOURCE}, è:
+\textsl{glibc} è fornita una specifica funzione,
+\funcd{syscall},\footnote{fino a prima del kernel 2.6.18 per l'esecuzione
+  diretta delle \textit{system call} erano disponibili anche una serie di
+  macro \texttt{\_syscall\textsl{N}} (con $N$ pari al numero di argomenti
+  della \textit{system call}); queste sono deprecate e pertanto non ne
+  parleremo ulteriormente.} che consente eseguire direttamente una
+\textit{system call}; il suo prototipo, accessibile se si è definita la macro
+\macro{\_GNU\_SOURCE}, è:
 
 \begin{funcproto}{
   \fhead{unistd.h}
   \fhead{sys/syscall.h}
-  \fdecl{int syscall(int number, ...)}
+  \fdecl{long syscall(int number, ...)}
   \fdesc{Esegue la \textit{system call} indicata da \param{number}.}
 }
 {La funzione ritorna un intero dipendente dalla \textit{system call} invocata,
@@ -366,7 +381,7 @@ linguaggio C all'interno della stessa, o se si richiede esplicitamente la
 chiusura invocando direttamente la funzione \func{exit}. Queste due modalità
 sono assolutamente equivalenti, dato che \func{exit} viene chiamata in maniera
 trasparente anche quando \code{main} ritorna, passandogli come argomento il
-valore di ritorno (che essendo .
+valore di ritorno.
 
 La funzione \funcd{exit}, che è completamente generale, essendo definita dallo
 standard ANSI C, è quella che deve essere invocata per una terminazione
@@ -437,8 +452,12 @@ i valori 0 e 1.
 Una forma alternativa per effettuare una terminazione esplicita di un
 programma è quella di chiamare direttamente la \textit{system call}
 \funcd{\_exit},\footnote{la stessa è definita anche come \funcd{\_Exit} in
-  \headfile{stdlib.h}.} che restituisce il controllo direttamente al kernel,
-concludendo immediatamente il processo, il suo prototipo è:
+  \headfile{stdlib.h}, inoltre a partire dalle \acr{glibc} 2.3 usando questa
+  funzione viene invocata \func{exit\_group} che termina tutti i
+  \textit{thread} del processo e non solo quello corrente (fintanto che non si
+  usano i \textit{thread}\unavref{, vedi sez.~\ref{cha:threads},} questo non
+  fa nessuna differenza).} che restituisce il controllo direttamente al
+kernel, concludendo immediatamente il processo, il suo prototipo è:
 
 \begin{funcproto}{ \fhead{unistd.h} \fdecl{void \_exit(int status)}
     \fdesc{Causa la conclusione immediata del programma.}  } {La funzione non