From c3e498249706436db56faaa3be03458b7ac1113d Mon Sep 17 00:00:00 2001 From: Simone Piccardi Date: Wed, 8 May 2002 23:31:26 +0000 Subject: [PATCH] Risistemata tutta la parte sui clock tick (e corrette le fregnacce dette in precedenza). Scritta la parte sui process time. --- prochand.tex | 14 +++-- signal.tex | 6 -- system.tex | 172 +++++++++++++++++++++++++++++++++++++++++---------- 3 files changed, 148 insertions(+), 44 deletions(-) diff --git a/prochand.tex b/prochand.tex index 98a0788..a8be792 100644 --- a/prochand.tex +++ b/prochand.tex @@ -137,10 +137,12 @@ system call ed ad ogni interrupt,\footnote{pi occasioni. NDT completare questa parte.} (ma può essere anche attivato esplicitamente). Il timer di sistema provvede comunque a che esso sia invocato periodicamente, generando un interrupt periodico secondo la frequenza -specificata dalla costante \macro{HZ}, definita in \file{asm/param.h}. Il -valore usuale è 100\footnote{è così per tutte le architetture eccetto l'alpha, - per la quale è 1000} ed è espresso in Hertz. Si ha cioè un interrupt dal -timer ogni centesimo di secondo. +specificata dalla costante \macro{HZ}, definita in \file{asm/param.h}, ed il +cui valore è espresso in Hertz.\footnote{Il valore usuale di questa costante è + 100, per tutte le architetture eccetto l'alpha, per la quale è 1000. Occorre + fare attenzione a non confondere questo valore con quello dei clock tick + (vedi \secref{sec:sys_unix_time}).} +%Si ha cioè un interrupt dal timer ogni centesimo di secondo. Ogni volta che viene eseguito, lo \textit{scheduler} effettua il calcolo delle priorità dei vari processi attivi (torneremo su questo in @@ -619,8 +621,8 @@ le differenze fra padre e figlio dopo la \func{fork} invece sono: \item il \textit{process id}. \item il \textit{parent process id} (quello del figlio viene settato al \acr{pid} del padre). -\item i valori dei tempi di esecuzione (vedi \secref{sec:sys_xxx}) che - nel figlio sono posti a zero. +\item i valori dei tempi di esecuzione della struttura \var{tms} (vedi + \secref{sec:sys_cpu_times}) che nel figlio sono posti a zero. \item i \textit{file lock} (vedi \secref{sec:file_locking}), che non vengono ereditati dal figlio. \item gli allarmi ed i segnali pendenti (vedi \secref{sec:sig_gen_beha}), che diff --git a/signal.tex b/signal.tex index f0565a2..7904fa9 100644 --- a/signal.tex +++ b/signal.tex @@ -1141,12 +1141,6 @@ struct itimerval struct timeval it_interval; /* next value */ struct timeval it_value; /* current value */ }; - -struct timeval -{ - long tv_sec; /* seconds */ - long tv_usec; /* microseconds */ -}; \end{lstlisting} \end{minipage} \normalsize diff --git a/system.tex b/system.tex index 5b645af..fd0284d 100644 --- a/system.tex +++ b/system.tex @@ -324,8 +324,8 @@ relative spiegazioni, si pu \texttt{\_SC\_SSIZE\_MAX}&\macro{SSIZE\_MAX}& valore massimo del tipo di dato \type{ssize\_t}.\\ \texttt{\_SC\_CLK\_TCK}& \macro{CLK\_TCK} & - Il numero di \textit{clock tick} al secondo, cioè la frequenza delle - interruzioni del timer di sistema (vedi \secref{sec:proc_priority}).\\ + Il numero di \textit{clock tick} al secondo, cioè l'unità di misura del + \textit{process time} (vedi \secref{sec:sys_unix_time}).\\ \texttt{\_SC\_JOB\_CONTROL}&\macro{\_POSIX\_JOB\_CONTROL}& Indica se è supportato il \textit{job control} (vedi \secref{sec:sess_xxx}) in stile POSIX.\\ @@ -1655,11 +1655,12 @@ anche il massimo valore che pu \section{La gestione dei tempi del sistema} \label{sec:sys_time} -In questa sezione tratteremo le varie funzioni attinenti alla gestione del -tempo in un sistema unix-like, a partire da quelle della gestione di data e -ora, a quelle per convertire i vari tempi nelle differenti rappresentazioni -che vengono utilizzate, a quelle per misurare i veri tempi di sistema -associati ai processi. +In questa sezione, una volta introdotti i concetti base della gestione dei +tempi da parte del sistema, tratteremo le varie funzioni attinenti alla +gestione del tempo in un sistema unix-like, a partire da quelle per misurare i +veri tempi di sistema associati ai processi, a quelle per convertire i vari +tempi nelle differenti rappresentazioni che vengono utilizzate, a quelle della +gestione di data e ora. \subsection{La misura del tempo in Unix} @@ -1670,24 +1671,28 @@ dati per la misure dei tempi all'interno del sistema: essi sono rispettivamente chiamati \textit{calendar time} e \textit{process time}, secondo le definizioni: \begin{description} -\item[\textit{calendar time}]: è il numero di secondi dalla mezzanotte del - primo gennaio 1970, in tempo universale coordinato (o UTC), data che viene - usualmente indicata con 00:00:00 Jan, 1 1970 (UTC) e chiamata \textit{the - Epoch}. Questo tempo viene anche chiamato anche GMT (Greenwich Mean Time) - dato che l'UTC corrisponde all'ora locale di Greenwich. È il tempo su cui - viene mantenuto l'orologio del calcolatore, e viene usato ad esempio per - indicare le date di modifica dei file o quelle di avvio dei processi. Per - memorizzare questo tempo è stato riservato il tipo primitivo \type{time\_t}. -\item[\textit{process time}]: detto anche tempo di processore. Viene misurato - in \textit{clock tick}, corrispondenti al numero di interruzioni effettuate - dal timer di sistema, e che per Linux avvengono ogni centesimo di - secondo.\footnote{eccetto per la piattaforma alpha dove avvengono ogni - millesimo di secondo.} Il dato primitivo usato per questo tempo è - \type{clock\_t}, inoltre la costante \macro{HZ} restituisce la frequenza di - operazione del timer, e corrisponde dunque al numero di tick al secondo. Lo - standard POSIX definisce allo stesso modo la costante \macro{CLK\_TCK}); - questo valore può comunque essere ottenuto con \func{sysconf} (vedi - \secref{sec:sys_limits}). +\item[\textit{calendar time}]: detto anche \textsl{tempo di calendario}. È il + numero di secondi dalla mezzanotte del primo gennaio 1970, in tempo + universale coordinato (o UTC), data che viene usualmente indicata con + 00:00:00 Jan, 1 1970 (UTC) e chiamata \textit{the Epoch}. Questo tempo viene + anche chiamato anche GMT (Greenwich Mean Time) dato che l'UTC corrisponde + all'ora locale di Greenwich. È il tempo su cui viene mantenuto l'orologio + del kernel, e viene usato ad esempio per indicare le date di modifica dei + file o quelle di avvio dei processi. Per memorizzare questo tempo è stato + riservato il tipo primitivo \type{time\_t}. +\item[\textit{process time}]: detto talvolta \textsl{tempo di processore}. + Viene misurato in \textit{clock tick}. Un tempo questo corrispondeva al + numero di interruzioni effettuate dal timer di sistema, adesso lo standard + POSIX richiede che esso sia pari al valore della costante + \macro{CLOCKS\_PER\_SEC}, che deve essere definita come 1000000, qualunque + sia la risoluzione reale dell'orologio di sistema e la frequenza delle + interruzioni del timer.\footnote{quest'ultima, come accennato in + \secref{sec:proc_hierarchy}, è invece data dalla costante \macro{HZ}.} Il + dato primitivo usato per questo tempo è \type{clock\_t}, che ha quindi una + risoluzione del microsecondo. Il numero di tick al secondo può essere + ricavato anche attraverso \func{sysconf} (vedi \secref{sec:sys_sysconf}). Il + vecchio simbolo \macro{CLK\_TCK} definito in \file{time.h} è ormai + considerato obsoleto. \end{description} In genere si usa il \textit{calendar time} per esprimere le date dei file e le @@ -1701,10 +1706,11 @@ tempo locale, utilizzando le opportune informazioni di localizzazione mantenuto dal sistema e non è detto che corrisponda al tempo tenuto dall'orologio hardware del calcolatore. -Anche il \textit{process time} di solito si esprime in secondi, ma provvede una -precisione ovviamente superiore al \textit{calendar time} (la cui granularità -minima è il secondo) e viene usato per tenere conto dei tempi di esecuzione -dei processi. Per ciascun processo il kernel calcola tre tempi diversi: +Anche il \textit{process time} di solito si esprime in secondi, ma provvede +una precisione ovviamente superiore al \textit{calendar time} (che è mantenuto +dal sistema con una granularità di un secondo) e viene usato per tenere conto +dei tempi di esecuzione dei processi. Per ciascun processo il kernel calcola +tre tempi diversi: \begin{description*} \item[\textit{clock time}]: il tempo \textsl{reale} (viene chiamato anche \textit{wall clock time}) passato dall'avvio del processo. Chiaramente tale @@ -1718,15 +1724,117 @@ dei processi. Per ciascun processo il kernel calcola tre tempi diversi: In genere la somma di \textit{user time} e \textit{system time} indica il tempo di processore totale in cui il sistema è stato effettivamente impegnato -nell'eseguire un certo processo e viene chiamato \textit{CPU time}. +nell'eseguire un certo processo e viene chiamato \textit{CPU time} o +\textsl{tempo di CPU}. -\subsection{I tempi di processore} +\subsection{La gestione del \textit{process time}} \label{sec:sys_cpu_times} +Di norma tutte le operazioni del sistema fanno sempre riferimento al +\textit{calendar time}, l'uso del \textit{process time} è riservato a quei +casi in cui serve conoscere i tempi di esecuzione di un processo (ad esempio +per valutarne l'efficienza). In tal caso infatti fare ricorso al +\textit{calendar time} è inutile in quanto il tempo può essere trascorso mentre +un altro processo era in esecuzione o in attesa del risultato di una +operazione di I/O. + +La funzione più semplice per leggere il \textit{process time} di un processo è +\func{clock}, che da una valutazione approssimativa del tempo di CPU +utilizzato dallo stesso; il suo prototipo è: +\begin{prototype}{time.h}{clock\_t clock(void)} + Legge il valore corrente del tempo di CPU. + + \bodydesc{La funzione ritorna il tempo di CPU usato dal programma e -1 in + caso di errore.} +\end{prototype} + +La funzione restituisce il tempo in tick, quindi se si vuole il tempo in +secondi occorre moltiplicare il risultato per la costante +\macro{CLOCKS\_PER\_SEC}.\footnote{le \acr{glibc} seguono lo standard ANSI C, + POSIX richiede che \macro{CLOCKS\_PER\_SEC} sia definito pari a 1000000 + indipendetemente dalla risoluzione del timer di sistema.} In genere +\type{clock\_t} viene rappresentato come intero a 32 bit, il che comporta un +valore massimo corrispondente a circa 72 minuti, dopo i quali il contatore +riprenderà lo stesso valore iniziale. + +Come accennato in \secref{sec:sys_unix_time} il tempo di CPU è la somma di +altri due tempi, l'\textit{user time} ed il \textit{system time} che sono +quelli effettivamente mantenuti dal kernel per ciascun processo. Questi +possono essere letti attraverso la funzione \func{times}, il cui prototipo è: +\begin{prototype}{sys/times.h}{clock\_t times(struct tms *buf)} + Legge in \param{buf} il valore corrente dei tempi di processore. + + \bodydesc{La funzione ritorna il numero di clock tick dall'avvio del sistema + in caso di successo e -1 in caso di errore.} +\end{prototype} + +La funzione restituisce i valori di process time del processo corrente in una +struttura di tipo \var{tms}, la cui definizione è riportata in +\secref{fig:sys_tms_struct}. La struttura prevede quattro campi; i primi due, +\var{tms\_utime} e \var{tms\_stime}, sono l'\textit{user time} ed il +\textit{system time} del processo, così come definiti in +\secref{sec:sys_unix_time}. + +\begin{figure}[!htb] + \footnotesize + \centering + \begin{minipage}[c]{15cm} + \begin{lstlisting}[labelstep=0]{}%,frame=,indent=1cm]{} + struct tms { + clock_t tms_utime; /* user time */ + clock_t tms_stime; /* system time */ + clock_t tms_cutime; /* user time of children */ + clock_t tms_cstime; /* system time of children */ + }; + \end{lstlisting} + \end{minipage} + \normalsize + \caption{La struttura \var{tms} dei tempi di processore associati a un + processo.} + \label{fig:sys_tms_struct} +\end{figure} + +Gli altri due campi mantengono rispettivamente la somma dell'\textit{user + time} ed del \textit{system time} di tutti i processi figli che sono +terminati; il kernel cioè somma in \var{tms\_cutime} il valore di +\var{tms\_utime} e \var{tms\_cutime} per ciascun figlio del quale è stato +ricevuto lo stato di terminazione, e lo stesso vale per \var{tms\_cstime}. -\var{tms\_utime}, \var{tms\_stime}, \var{tms\_cutime}, \var{tms\_uetime} +Si tenga conto che l'aggiornamento di \var{tms\_cutime} e \var{tms\_cstime} +viene eseguito solo quando una chiamata a \func{wait} o \func{waitpid} è +ritornata. Per questo motivo se un figlio termina prima di altri suoi figli, +questi ``nipoti'' non potranno essere considerati nel calcolo di questi tempi. + + + +\subsection{Le funzioni per il \textit{calendar time}} +\label{sec:sys_time_base} + +Normalmente il \textit{calendar time} è mantenuto in una variabile di tipo +\type{time\_t}, che usualmente corrisponde ad un tipo nativo (in Linux è un +intero a 32 bit). Le \acr{glibc} provvedono delle rappresentazioni +alternative che consentono un suo utilizzo per diversi scopi; in particolare +quando necessita manipolare + + +\begin{figure}[!htb] + \footnotesize + \centering + \begin{minipage}[c]{15cm} + \begin{lstlisting}[labelstep=0]{}%,frame=,indent=1cm]{} +struct timeval +{ + long tv_sec; /* seconds */ + long tv_usec; /* microseconds */ +}; + \end{lstlisting} + \end{minipage} + \normalsize + \caption{La struttura \var{timeval} per il calendar time.} + \label{fig:sys_timeval_struct} +\end{figure} -- 2.30.2