Aggiunte un po' di funzioni ausiliarie, quasi a fine dello scheduler.
[gapil.git] / prochand.tex
index c005bbd5918d8a28fc0670c7e7ea1989288862f8..770eebf86c4b5bfc215a98511160c75d249a2ed4 100644 (file)
@@ -606,7 +606,7 @@ comune dopo l'esecuzione di una \func{fork} 
 \item la directory di lavoro e la directory radice (vedi
   \secref{sec:file_work_dir} e \secref{sec:file_chroot}).
 \item la maschera dei permessi di creazione (vedi \secref{sec:file_umask}).
-\item la maschera dei segnali bloccati (vedi \secref{sec:sig_sigpending}) e le
+\item la maschera dei segnali bloccati (vedi \secref{sec:sig_sigmask}) e le
   azioni installate (vedi \secref{sec:sig_gen_beha}).
 \item i segmenti di memoria condivisa agganciati al processo (vedi
 \secref{sec:ipc_xxx}). 
@@ -1216,7 +1216,7 @@ la lista completa 
   \secref{sec:file_umask}) ed i \textit{lock} sui file (vedi
   \secref{sec:file_locking}).
 \item i segnali sospesi (\textit{pending}) e la maschera dei segnali (si veda
-  \secref{sec:sig_sigpending}).
+  \secref{sec:sig_sigmask}).
 \item i limiti sulle risorse (vedi \secref{sec:sys_limits}).
 \item i valori delle variabili \var{tms\_utime}, \var{tms\_stime},
   \var{tms\_cutime}, \var{tms\_ustime} (vedi \secref{sec:xxx_xxx}).
@@ -2019,7 +2019,7 @@ funzione \func{getpriority}, derivata da BSD, il cui prototipo 
 \begin{prototype}{sys/resource.h}
 {int getpriority(int which, int who)}
   
-  Restituisce la priorità per l'insieme dei processi specificati.
+Restituisce il valore di \var{nice} per l'insieme dei processi specificati.
 
   \bodydesc{La funzione ritorna la priorità in caso di successo e -1 in caso di
     errore, nel qual caso \var{errno} può assumere i valori:
@@ -2084,7 +2084,7 @@ settare la priorit
 \end{prototype}
 
 La funzione setta la priorità al valore specificato da \param{prio} per tutti
-i processi indicati dagli argomenti \parm{which} e \param{who}.  La gestione
+i processi indicati dagli argomenti \param{which} e \param{who}.  La gestione
 dei permessi dipende dalle varie implementazioni; in Linux, secondo le
 specifiche dello standard SUSv3, e come avviene per tutti i sistemi che
 derivano da SYSV, è richiesto che il real o l'effective user id del processo
@@ -2097,20 +2097,195 @@ Ultrix, *BSD) la corrispondenza pu
 \subsection{Il meccanismo di \textit{scheduling real-time}}
 \label{sec:proc_real_time}
 
-
 Come spiegato in \secref{sec:proc_sched} lo standard POSIX.1b ha introdotto le
-priorità assolute per permettere la gestione di processi real-time; benché
-Linux non sia un sistema operativo real-time,\footnote{a meno che non si siano
-  installate le patch di RTLinux o RTAI, con i quali è possibile ottenere un
-  sistema effettivamente hard real-time.} è stata comunque implementata anche
-una politica di scheduling corrispondente a questo meccanismo.
+priorità assolute per permettere la gestione di processi real-time. In realtà
+nel caso di Linux non si tratta di un vero hard real-time, in quanto in
+presenza di eventuali interrupt il kernel interrompe l'esecuzione di un
+processo qualsiasi sia la sua priorità,\footnote{questo a meno che non si
+  siano installate le patch di RTLinux o RTAI, con i quali è possibile
+  ottenere un sistema effettivamente hard real-time. In tal caso infatti gli
+  interrupt vengono intercettati dall'interfaccia real-time, e gestiti
+  direttamente qualora ci sia la necessità di avere un processo con priorità
+  più elevata di un \textit{interrupt handler}.} mentre con l'incorrere in un
+page fault si possono avere ritardi non previsti. Se l'ultimo problema può
+essere aggirato attraverso l'uso delle funzioni di controllo della memoria
+virtuale (vedi \secref{sec:proc_mem_lock}), il primo non è superabile e può
+comportare ritardi non prevedibili riguardo ai tempi di esecuzione di
+qualunque processo.
+
+In ogni caso occorre usare le priorità assolute con molta attenzione: se si dà
+ad un processo una priorità assoluta e questo finisce in un loop infinito,
+nessun altro processo potrà essere eseguito, ed esso sarà mantenuto in
+esecuzione permanentemente assorbendo tutta la CPU e senza nessuna possibilità
+di riottenere l'accesso al sistema. Per questo motivo è sempre opportuno,
+quando si lavora con processi che usano priorità assolute, tenere attiva una
+shell cui si sia assegnata la massima priorità assoluta, in modo da poter
+essere comunque in grado di rientrare nel sistema.
+
+Quando c'è un processo con priorità assoluta lo scheduler lo metterà in
+esecuzione prima di ogni processo normale. In caso di più processi sarà
+eseguito per primo quello con priorità assoluta più alta. Quando ci sono più
+processi con la stessa priorità assoluta questi vegono tenuti in una coda
+tocca al kernel decidere quale deve essere eseguito. 
+
+
+
+Il meccanismo con cui vengono gestiti questi processi dipende dalla politica
+di scheduling che si è scelto; lo standard ne prevede due:
+\begin{basedescript}{\desclabelwidth{3cm}\desclabelstyle{\nextlinelabel}}
+\item[\textit{FIFO}] il processo viene eseguito fintanto che non cede
+  volontariamente la CPU, si blocca, finisce o viene interrotto da un processo
+  a priorità più alta.
+\item[\textit{Round Robin}] ciascun processo viene eseguito a turno per un
+  certo periodo di tempo (una \textit{time slice}). Solo i processi con la
+  stessa priorità ed in stato \textit{runnable} entrano nel circolo.
+\end{basedescript}
+
+La funzione per settare le politiche di scheduling (sia real-time che
+ordinarie) ed i relativi parametri è \func{sched\_setscheduler}; il suo
+prototipo è:
+\begin{prototype}{sched.h}
+{int sched\_setscheduler(pid\_t pid, int policy, const struct sched\_param *p)}
+  Setta priorità e politica di scheduling per il processo \param{pid}.
+
+  \bodydesc{La funzione ritorna la priorità in caso di successo e -1 in caso di
+    errore, nel qual caso \var{errno} può assumere i valori:
+    \begin{errlist}
+    \item[\macro{ESRCH}] il processo \param{pid} non esiste.
+    \item[\macro{EINVAL}] il valore di \param{policy} non esiste o il relativo
+      valore di \param{p} non è valido.
+    \item[\macro{EPERM}] il processo non ha i privilegi per attivare la
+      politica richiesta (vale solo per \macro{SCHED\_FIFO} e
+      \macro{SCHED\_RR}).
+  \end{errlist}}
+\end{prototype}
+
+La funzione esegue il settaggio per il processo specificato; un valore nullo
+di \param{pid} esegue il settaggio per il processo corrente, solo un processo
+con i privilegi di amministratore può settare delle priorità assolute diverse
+da zero. La politica di scheduling è specificata dall'argomento \param{policy}
+i cui possibili valori sono riportati in \tabref{tab:proc_sched_policy}; un
+valore negativo per \param{policy} mantiene la politica di scheduling
+corrente.
 
-In realtà non si tratta di un vero hard real-time, in quanto la presenza di
-eventuali interrupt o di page fault può sempre interrompere l'esecuzione di un
-processo, in questo modo comunque si potrà dare .
+\begin{table}[htb]
+  \centering
+  \footnotesize
+  \begin{tabular}[c]{|c|l|}
+    \hline
+    \textbf{Policy}  & \textbf{Significato} \\
+    \hline
+    \hline
+    \macro{SCHED\_FIFO} & Scheduling real-time con politica \textit{FIFO} \\
+    \macro{SCHED\_RR}   & Scheduling real-time con politica \textit{Round
+    Robin} \\
+    \macro{SCHED\_OTHER}& Scheduling ordinario\\
+    \hline
+  \end{tabular}
+  \caption{Valori dell'argomento \param{policy}  per la funzione
+    \func{sched\_setscheduler}. }
+  \label{tab:proc_sched_policy}
+\end{table}
 
+Il valore della priorità è passato attraverso la struttura \var{sched\_param}
+(riportata in \figref{fig:sig_sched_param}), il cui solo campo attualmente
+definito è \var{sched\_priority}, che nel caso delle priorità assolute deve
+essere specificato nell'intervallo fra 1 e 99 (il valore zero è legale, ma
+indica i processi normali). Lo standard POSIX.1b prevede comunque che questi
+due valori possano essere ottenuti per ciascuna politica di scheduling dalle
+funzioni \func{sched\_get\_priority\_max} e \func{sched\_get\_priority\_min},
+i cui prototipi sono:
+\begin{functions}
+  \headdecl{sched.h}
+  
+  \funcdecl{int sched\_get\_priority\_max(int policy)} Legge il valore
+  massimo della priorità statica per la politica di scheduling \param{policy}.
 
+  
+  \funcdecl{int sched\_get\_priority\_min(int policy)} Legge il valore minimo
+  della priorità statica per la politica di scheduling \param{policy}.
+  
+  \bodydesc{La funzioni ritornano il valore della priorità in caso di successo
+    e -1 in caso di errore, nel qual caso \var{errno} può assumere i valori:
+    \begin{errlist}
+    \item[\macro{EINVAL}] il valore di \param{policy} è invalido.
+  \end{errlist}}
+\end{functions}
+
+
+I processi con politica di scheduling \macro{SCHED\_OTHER} devono specificare
+un valore nullo (altrimenti si avrà un errore \macro{EINVAL}), questo valore
+infatti non ha niente a che vedere con la priorità dinamica determinata dal
+valore di \var{nice}, che deve essere settato con le funzioni viste in
+precedenza.
+
+\begin{figure}[!htb]
+  \footnotesize \centering
+  \begin{minipage}[c]{15cm}
+    \begin{lstlisting}[labelstep=0]{}%,frame=,indent=1cm]{}
+struct sched_param {
+    int sched_priority;
+};
+    \end{lstlisting}
+  \end{minipage} 
+  \normalsize 
+  \caption{La struttura \var{sched\_param}.} 
+  \label{fig:sig_sched_param}
+\end{figure}
+
+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 è \macro{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.
+
+La priorità assoluta può essere riletta indietro dalla funzione
+\func{sched\_getscheduler}, il cui prototipo è:
+\begin{prototype}{sched.h}
+{int sched\_getscheduler(pid\_t pid)}
+  Legge la politica di scheduling per il processo \param{pid}.
+  
+  \bodydesc{La funzione ritorna la politica di scheduling in caso di successo
+    e -1 in caso di errore, nel qual caso \var{errno} può assumere i valori:
+    \begin{errlist}
+    \item[\macro{ESRCH}] il processo \param{pid} non esiste.
+    \item[\macro{EINVAL}] il valore di \param{pid} è negativo.
+  \end{errlist}}
+\end{prototype}
+
+La funzione restituisce il valore (secondo la quanto elencato in
+\tabref{tab:proc_sched_policy}) della politica di scheduling per il processo
+specificato; se \param{pid} è nullo viene restituito quello del processo
+chiamante.
+
+Se si intende operare solo sulla priorità assoluta di un processo si possono
+usare le funzioni \func{sched\_setparam} e \func{sched\_getparam}, i cui
+prototipi sono:
+  
+\begin{functions}
+  \headdecl{sched.h}
+
+  \funcdecl{int sched\_setparam(pid\_t pid, const struct sched\_param *p)}
+  Setta la priorità assoluta del processo \param{pid}.
+
+
+  \funcdecl{int sched\_getparam(pid\_t pid, struct sched\_param *p)}
+  Legge la priorità assoluta del processo \param{pid}.
+
+  \bodydesc{La funzione ritorna la priorità  in caso di successo
+    e -1 in caso di errore, nel qual caso \var{errno} può assumere i valori:
+    \begin{errlist}
+    \item[\macro{ESRCH}] il processo \param{pid} non esiste.
+    \item[\macro{EINVAL}] il valore di \param{pid} è negativo.
+  \end{errlist}}
+\end{functions}
 
+L'uso di \func{sched\_setparam} che è del tutto equivalente a
+\func{sched\_setscheduler} con \param{priority} uguale a -1.
 
 
 \section{Problematiche di programmazione multitasking}