From 596d8a42fe9018aa5e41c0083186f04f719ce7dc Mon Sep 17 00:00:00 2001 From: Simone Piccardi Date: Sun, 15 Apr 2012 21:15:09 +0000 Subject: [PATCH] Correzioni varie ed accorpamento dei dati relativi ai tempi di sistema --- prochand.tex | 39 +++--- signal.tex | 4 +- system.tex | 368 ++++++++++++++++++++++++++++++++++----------------- 3 files changed, 264 insertions(+), 147 deletions(-) diff --git a/prochand.tex b/prochand.tex index 9677726..7bd2ed9 100644 --- a/prochand.tex +++ b/prochand.tex @@ -157,19 +157,15 @@ in fig.~\ref{fig:proc_task_struct}. Come accennato in sez.~\ref{sec:intro_unix_struct} è lo \itindex{scheduler} \textit{scheduler} che decide quale processo mettere in esecuzione; esso viene -eseguito ad ogni \textit{system call} ed ad ogni interrupt e in una serie di -altre occasioni, 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 -\const{HZ},\footnote{fino al kernel 2.4 il valore di \const{HZ} era 100 su - tutte le architetture tranne l'alpha, per cui era 1000, nel 2.6 è stato - portato a 1000 su tutte; dal 2.6.13 lo si può impostare in fase di - compilazione del kernel, con un default di 250 e valori possibili di 100, - 250, 1000 e dal 2.6.20 anche 300 (che è divisibile per le frequenze di - refresh della televisione); occorre fare attenzione a non confondere questo - valore con quello dei \itindex{clock~tick} \textit{clock tick} (vedi - sez.~\ref{sec:sys_unix_time}).} definita in \file{asm/param.h}, ed il cui -valore è espresso in Hertz. +eseguito in occasione di dell'invocazione di ogni \textit{system call} ed per +ogni interrupt dall'hardware oltre che in una serie di altre occasioni, e può +essere anche attivato esplicitamente. Il timer di sistema provvede comunque a +che esso sia invocato periodicamente, generando un interrupt periodico secondo +una frequenza predeterminata, specificata dalla costante \const{HZ} del kernel +(torneremo su questo argomento in sez.~\ref{sec:sys_unix_time}), che assicura +che lo \textit{scheduler} scheduler venga comunque eseguito ad intervalli +regolari e possa prendere le sue decisioni. + A partire dal kernel 2.6.21 è stato introdotto anche un meccanismo completamente diverso, detto \textit{tickless}, in cui non c'è più una @@ -3889,14 +3885,15 @@ Introdotta a partire dal kernel 2.4.21, solo su PowerPC. nulli pena la ricezione di un errore di \errval{EINVAL}. Introdotta a partire dal kernel 2.6.32. % TODO: verificare questa parte -\item[PR\_SET\_CHILD\_SUBREAPER] Imposta il processo indicato con il \ids{PID} - specificato da \param{arg2} come nuovo ``\textsl{genitore adottivo}'' per - tutti i processi discendenti del chiamante che diventeranno orfani, - sostituendo in questo ruolo \cmd{init} (si ricordi quanto illustrato in - sez.~\ref{sec:proc_termination}). Introdotta a partire dal kernel 3.4. -\item[PR\_GET\_CHILD\_SUBREAPER] Ottiene il \ids{PID} del processo a cui - vengono assegnati come figli gli orfani del processo corrente. Introdotta a - partire dal kernel 3.4. +\item[\const{PR\_SET\_CHILD\_SUBREAPER}] Imposta il processo indicato con il + \ids{PID} specificato da \param{arg2} come nuovo ``\textsl{genitore + adottivo}'' per tutti i processi discendenti del chiamante che + diventeranno orfani, sostituendo in questo ruolo \cmd{init} (si ricordi + quanto illustrato in sez.~\ref{sec:proc_termination}). Introdotta a partire + dal kernel 3.4. +\item[\const{PR\_GET\_CHILD\_SUBREAPER}] Ottiene il \ids{PID} del processo a + cui vengono assegnati come figli gli orfani del processo + corrente. Introdotta a partire dal kernel 3.4. \label{sec:prctl_operation} \end{basedescript} diff --git a/signal.tex b/signal.tex index 1a63283..164c96f 100644 --- a/signal.tex +++ b/signal.tex @@ -1221,7 +1221,7 @@ queste funzioni era limitata dalla frequenza del timer di sistema,\footnote{il valore della costante \texttt{HZ}, di cui abbiamo già parlato in sez.~\ref{sec:proc_hierarchy}.} in quanto le temporizzazioni erano calcolate in numero di interruzioni del timer (i cosiddetti \itindex{jiffies} -''\textit{jiffies}''), ed era assicurato soltanto che il segnale non sarebbe +``\textit{jiffies}''), ed era assicurato soltanto che il segnale non sarebbe stato mai generato prima della scadenza programmata (l'arrotondamento cioè era effettuato per eccesso).\footnote{questo in realtà non è del tutto vero a causa di un bug, presente fino al kernel 2.6.12, che in certe circostanze @@ -2607,7 +2607,7 @@ massima dei tempi dell'orologio interno del kernel, che era quella ottenibile dal timer di sistema che governa lo \textit{scheduler},\footnote{e quindi limitate dalla frequenza dello stesso che si ricordi, come già illustrato in sez.~\ref{sec:proc_hierarchy}, è data dal valore della costante - \texttt{HZ}.} i contatori usati per il calcolo dei tempo infatti erano + \texttt{HZ}.} i contatori usati per il calcolo dei tempi infatti erano basati sul numero di \itindex{jiffies} \textit{jiffies} che vengono incrementati ad ogni \textit{clock tick} del timer di sistema.\footnote{il che comportava anche, come accennato in sez.~\ref{sec:sig_alarm_abort} per diff --git a/system.tex b/system.tex index 40d4874..69c89fd 100644 --- a/system.tex +++ b/system.tex @@ -1522,14 +1522,15 @@ recepita nello standard POSIX.1-2001, che però indica come campi di I campi più utilizzati sono comunque \var{ru\_utime} e \var{ru\_stime} che indicano rispettivamente il tempo impiegato dal processo nell'eseguire le -istruzioni in user space, e quello impiegato dal kernel nelle \textit{system - call} eseguite per conto del processo. I campi \var{ru\_minflt} e -\var{ru\_majflt} servono a quantificare l'uso della memoria -virtuale\index{memoria~virtuale} e corrispondono rispettivamente al numero di -\itindex{page~fault} \textit{page fault} (vedi sez.~\ref{sec:proc_mem_gen}) -avvenuti senza richiedere I/O su disco (i cosiddetti \textit{minor page - fault}), a quelli che invece han richiesto I/O su disco (detti invece -\textit{major page fault}).% mentre \var{ru\_nswap} ed al numero di volte che +istruzioni in \textit{user space}, e quello impiegato dal kernel nelle +\textit{system call} eseguite per conto del processo (vedi +sez.~\ref{sec:sys_unix_time}). I campi \var{ru\_minflt} e \var{ru\_majflt} +servono a quantificare l'uso della memoria virtuale\index{memoria~virtuale} e +corrispondono rispettivamente al numero di \itindex{page~fault} \textit{page + fault} (vedi sez.~\ref{sec:proc_mem_gen}) avvenuti senza richiedere I/O su +disco (i cosiddetti \textit{minor page fault}), a quelli che invece han +richiesto I/O su disco (detti invece \textit{major page + fault}).% mentre \var{ru\_nswap} ed al numero di volte che % il processo è stato completamente tolto dalla memoria per essere inserito % nello swap. % TODO verificare \var{ru\_nswap} non citato nelle pagine di manuali recenti e @@ -1865,7 +1866,6 @@ limiti. Il significato dell'argomento \param{resource} resta identico rispetto a \func{getrlimit} e \func{setrlimit}, così come i restanti requisiti. - \subsection{Le informazioni sulle risorse di memoria e processore} \label{sec:sys_memory_res} @@ -1889,7 +1889,7 @@ ricompilare i programmi per ogni possibile caso e relativa scelta di dimensioni, è necessario poter utilizzare una funzione che restituisca questi valori quando il programma viene eseguito. -Dato che si tratta di una caratteristica general del sistemae come abbiamo +Dato che si tratta di una caratteristica generale del sistema come abbiamo visto in sez.~\ref{sec:sys_characteristics} questa dimensione può essere ottenuta come tutte le altre attraverso una chiamata a \func{sysconf}, nel caso specifico si dovrebbe utilizzare il parametro \const{\_SC\_PAGESIZE}. Ma @@ -2053,75 +2053,132 @@ gestione di data e ora. \subsection{La misura del tempo in Unix} \label{sec:sys_unix_time} -Storicamente i sistemi unix-like hanno sempre mantenuto due distinti tipi di -dati per la misure dei tempi all'interno del sistema: essi sono -rispettivamente chiamati \itindex{calendar~time} \textit{calendar time} e -\itindex{process~time} \textit{process time}, secondo le definizioni: +Tradizionalmente nei sistemi unix-like sono sempre stati previsti due tipi +distinti di tempi, caratterizzati da altrettante modalità di misura ed +espressi con diversi tipi di dati, chiamati rispettivamente \textit{calendar + time} e \textit{process time}, secondo le seguenti definizioni: \begin{basedescript}{\desclabelwidth{1.5cm}\desclabelstyle{\nextlinelabel}} + \item[\textit{calendar time}] \itindex{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}] \itindex{process~time} detto talvolta - \textsl{tempo di processore}. Viene misurato in \itindex{clock~tick} - \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 \const{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 sez.~\ref{sec:proc_hierarchy}, è invece data dalla - costante \const{HZ}.} Il dato primitivo usato per questo tempo è - \type{clock\_t}, che ha quindi una risoluzione del microsecondo. Il numero - di \itindex{clock~tick} \textit{tick} al secondo può essere ricavato anche - attraverso \func{sysconf} (vedi sez.~\ref{sec:sys_limits}). Il vecchio - simbolo \const{CLK\_TCK} definito in \headfile{time.h} è ormai considerato - obsoleto. + \textsl{tempo di calendario}, \textsl{tempo d'orologio} o \textit{tempo + reale}. Si tratta di un tempo assoluto o di un intervallo di tempo come lo + intende normalmente per le misure fatte con un orologio. Per esprimere + questo tempo è stato riservato il tipo \type{time\_t}, e viene + tradizionalmente misurato in secondi a partire dalla mezzanotte del primo + gennaio 1970, data che viene chiamata \textit{the Epoch}. + +\item[\textit{process time}] \itindex{process~time} detto anche \textsl{tempo + di processore} o \textsl{tempo di CPU}. Si tratta del tempo impiegato da + un processore nell'esecuzione del codice di un programma all'interno di un + processo. Per esprimere questo tempo è stato riservato il tipo + \type{clock\_t}, e viene misurato nei cosiddetti \itindex{clock~tick} + \textit{clock tick}, tradizionalmente corrispondenti al numero di + interruzioni del processore da parte del timer di sistema. A differenza del + precedente indica soltanto un intervallo di durata. \end{basedescript} -In genere si usa il \itindex{calendar~time} \textit{calendar time} per -esprimere le date dei file e le informazioni analoghe che riguardano i -cosiddetti \textsl{tempi di orologio}, che vengono usati ad esempio per i -demoni che compiono lavori amministrativi ad ore definite, come \cmd{cron}. - -Di solito questo tempo viene convertito automaticamente dal valore in UTC al -tempo locale, utilizzando le opportune informazioni di localizzazione -(specificate in \conffile{/etc/timezone}). E da tenere presente che questo -tempo è mantenuto dal sistema e non è detto che corrisponda al tempo tenuto -dall'orologio hardware del calcolatore. - -Anche il \itindex{process~time} \textit{process time} di solito si esprime in -secondi, ma fornisce 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{basedescript}{\desclabelwidth{1.5cm}\desclabelstyle{\nextlinelabel}} -\item[\textit{clock time}] il tempo \textsl{reale} (viene chiamato anche - \textit{wall clock time} o \textit{elapsed time}) passato dall'avvio del - processo. Chiaramente tale tempo dipende anche dal carico del sistema e da - quanti altri processi stavano girando nello stesso periodo. +Il \itindex{calendar~time} \textit{calendar time} viene sempre mantenuto +facendo riferimento al cosiddetto \textit{tempo universale coordinato} UTC, +anche se talvolta viene usato il cosiddetto GMT (\textit{Greenwich Mean Time}) +dato che l'UTC corrisponde all'ora locale di Greenwich. Si tratta del tempo su +cui viene mantenuto il cosiddetto \textsl{orologio di sistema}, e viene usato +per indicare i tempi dei file (quelli di sez.~\ref{sec:file_file_times}) o le +date di avvio dei processi, ed è il tempo che viene usato dai demoni che +compiono lavori amministrativi ad orari definito, come \cmd{cron}. + +Si tenga presente che questo tempo è mantenuto dal kernel e non è detto che +corrisponda al tempo misurato dall'orologio hardware presente su praticamente +tutte le piastre madri dei computer moderni (il cosiddetto \textit{hardware + clock}), il cui valore viene gestito direttamente dall'hardware in maniera +indipendente e viene usato dal kernel soltanto all'avvio per impostare un +valore iniziale dell'orologio di sistema. La risoluzione tradizionale data dal +tipo di dato \type{time\_t} è di un secondo, ma nei sistemi più recenti sono +disponibili altri tipi di dati con precisioni maggiori. + +Si tenga presente inoltre che a differenza di quanto avviene con altri sistemi +operativi,\footnote{è possibile, ancorché assolutamente sconsigliabile, + forzare l'orologio di sistema all'ora locale per compatibilità con quei + sistemi operativi che han fatto questa deprecabile scelta.} l'orologio di +sistema viene mantenuto sempre in UTC e che la conversione all'ora locale del +proprio fuso orario viene effettuata dalle funzioni di libreria utilizzando le +opportune informazioni di localizzazione (specificate in +\conffile{/etc/timezone}). In questo modo si ha l'assicurazione che l'orologio +di sistema misuri sempre un tempo monotono crescente come nella realtà, anche +in presenza di cambi di fusi orari. + +Il \itindex{process~time} \textit{process time} invece indica sempre una +misura di un lasso di tempo e viene usato per tenere conto dei tempi di +esecuzione dei processi. Esso viene sempre diviso in \textit{user time} e +\textit{system time}, per misurare la durata di ciascun processo il kernel +infatti calcola tre tempi: +\begin{basedescript}{\desclabelwidth{2.2cm}\desclabelstyle{\nextlinelabel}} +\item[\textit{clock time}] il tempo \textsl{reale}, viene chiamato anche + \textit{wall clock time} o \textit{elapsed time}, passato dall'avvio del + processo. Questo tempo fa riferimento al \itindex{calendar~time} + \textit{calendar time} e dice la durata effettiva dell'esecuzione del + processo, ma chiaramente dipende dal carico del sistema e da quanti altri + processi stanno girando nello stesso momento. \item[\textit{user time}] il tempo effettivo che il processore ha impiegato - nell'esecuzione delle istruzioni del processo in user space. È quello - riportato nella risorsa \var{ru\_utime} di \struct{rusage} vista in - sez.~\ref{sec:sys_resource_use}. + nell'esecuzione delle istruzioni del programma in \textit{user space}. È + anche quello riportato nella risorsa \var{ru\_utime} di \struct{rusage} + vista in sez.~\ref{sec:sys_resource_use}. \item[\textit{system time}] il tempo effettivo che il processore ha impiegato per eseguire codice delle \textit{system call} nel kernel per conto del - processo. È quello riportato nella risorsa \var{ru\_stime} di + processo. È anche quello riportato nella risorsa \var{ru\_stime} di \struct{rusage} vista in sez.~\ref{sec:sys_resource_use}. \end{basedescript} -In genere la somma di \textit{user time} e \textit{system time} indica il -tempo di processore totale che il sistema ha effettivamente utilizzato per -eseguire un certo processo, questo viene chiamato anche \textit{CPU time} o -\textsl{tempo di CPU}. Si può ottenere un riassunto dei valori di questi tempi -quando si esegue un qualsiasi programma lanciando quest'ultimo come argomento -del comando \cmd{time}. +La somma di \textit{user time} e \textit{system time} indica il +\itindex{process~time} \textit{process time}, vale a dire il tempo di +processore totale che il sistema ha effettivamente utilizzato per eseguire il +programma di un certo processo. Si può ottenere un riassunto dei valori di +questi tempi quando si esegue un qualsiasi programma lanciando quest'ultimo +come argomento del comando \cmd{time}. + +Come accennato il \itindex{process~time} \textit{process time} viene misurato +nei cosiddetti \itindex{clock~tick} \textit{clock tick}. Un tempo questo +corrispondeva al numero di interruzioni effettuate dal timer di sistema, oggi +lo standard POSIX richiede che esso sia espresso come multiplo della costante +\const{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 che, come accennato in sez.~\ref{sec:proc_hierarchy} e +come vedremo a breve, è invece data dalla costante \const{HZ}. + +Il tipo di dato usato per questo tempo, \type{clock\_t}, con questa +convenzione ha una risoluzione del microsecondo. Ma non tutte le funzioni di +sistema come vedremo seguono questa convenzione, in tal caso il numero di +\itindex{clock~tick} \textit{clock tick} al secondo può essere ricavato anche +attraverso \func{sysconf} richiedendo il valore della costante +\const{\_SC\_CLK\_TCK} (vedi sez.~\ref{sec:sys_limits}). Il vecchio simbolo +\const{CLK\_TCK} definito in \headfile{time.h} è ormai considerato obsoleto e +non deve essere usato. + +In realtà tutti calcoli dei tempi vengono effettuati dal kernel per il +cosiddetto \textit{software clock}, utilizzando il \textit{timer di sistema} e +facendo i conti in base al numero delle interruzioni generate dello stesso, i +cosiddetti \itindex{jiffies} ``\textit{jiffies}''. La durata di un +``\textit{jiffy}'' è determinata dalla frequenza di interruzione del timer, +indicata in Hertz, come accennato in sez.~\ref{sec:proc_hierarchy}, dal valore +della costante \const{HZ} del kernel, definita in \file{asm/param.h}. + +Fino al kernel 2.4 il valore di \const{HZ} era 100 su tutte le architetture +tranne l'alpha, per cui era 1000. Con il 2.6.0 è stato portato a 1000 su tutte +le architetture, ma dal 2.6.13 il valore è diventato una opzione di +compilazione del kernel, con un default di 250 e valori possibili di 100, 250, +1000. Dal 2.6.20 è stato aggiunto anche il valore 300 che è divisibile per le +frequenze di refresh della televisione (50 o 60 Hz). Si può pensare che questi +valori determinino anche la corrispondente durata dei \itindex{clock~tick} +\textit{clock tick}, ma in realtà questa granularità viene calcolata in +maniera indipendente usando la costante del kernel \const{USER\_HZ}. + +Fino al kernel 2.6.21 la durata di un \textit{jiffy} costituiva la risoluzione +massima ottenibile nella misura dei tempi impiegabile in una \textit{system + call} (ad esempio per i timeout). Con il 2.6.21 e l'introduzione degli +\textit{high-resolution timers} (HRT) è divenuto possibile ottenere, per le +funzioni di attesa ed i timer, la massima risoluzione possibile fornita +dall'hardware. Torneremo su questo in sez.~\ref{sec:sig_timer_adv}. @@ -2153,34 +2210,40 @@ utilizzato dallo stesso; il suo prototipo è: \var{errno} non viene usata.} \end{funcproto} -La funzione restituisce il tempo in \itindex{clock~tick} \texttt{clock tick}, -quindi se si vuole il tempo in secondi occorre dividere il risultato per la -costante \const{CLOCKS\_PER\_SEC}.\footnote{le \acr{glibc} seguono lo standard - ANSI C, POSIX richiede che \const{CLOCKS\_PER\_SEC} sia definito pari a - 1000000 indipendentemente 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. - -% TODO questi valori sono obsoleti, verificare il tutto. - -Come accennato in sez.~\ref{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 \funcd{times}, il cui prototipo è: +La funzione restituisce il tempo in \itindex{clock~tick} \textit{clock tick} +ma la \acr{glibc} segue lo standard POSIX e quindi se si vuole il tempo in +secondi occorre dividere il risultato per la costante +\const{CLOCKS\_PER\_SEC}. 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. + +La funzione è presente anche nello standard ANSI C, ma in tal caso non è +previsto che il valore ritornato indichi un intervallo di tempo ma solo un +valore assoluto, per questo se si vuole la massima portabilità anche al di +fuori di kernel unix-like, può essere opportuno chiamare la funzione +all'inizio del programma ed ottenere il valore del tempo con una differenza. + +Si tenga presente inoltre che con altri kernel unix-like il valore riportato +dalla funzione può includere anche il tempo di processore usato dai processi +figli di cui si è ricevuto lo stato di terminazione con \func{wait} e +affini. Questo non vale per Linux, in cui questa informazione deve essere +ottenuta separatamente. + +Come accennato in sez.~\ref{sec:sys_unix_time} il tempo di processore è 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 separatamente attraverso la funzione \funcd{times}, il +cui prototipo è: \begin{funcproto}{ -\fhead{sys/times.h +\fhead{sys/times.h} \fdecl{clock\_t times(struct tms *buf)} \fdesc{Legge il valore corrente dei tempi di processore.} } -{La funzione ritorna il numero di \textit{clock ticks} in caso di successo e - $-1$ per un errore, nel qual caso \var{errno} assumerà uno dei valori: - \begin{errlist} - \end{errlist} - ed inoltre -nel loro significato generico.} +{La funzione ritorna un numero di \textit{clock tick} in caso di successo e + $-1$ per un errore, nel qual caso \var{errno} potrà assumere solo il valore + \errval{EFAULT} nel suo significato generico.} \end{funcproto} La funzione restituisce i valori di \textit{process time} del processo @@ -2188,12 +2251,15 @@ corrente in una struttura di tipo \struct{tms}, la cui definizione è riportata in fig.~\ref{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 -sez.~\ref{sec:sys_unix_time}. +sez.~\ref{sec:sys_unix_time}. Gli altri due campi, \var{tms\_cutime} e +\var{tms\_cstime}, riportano la somma dell'\textit{user time} e del +\textit{system time} di tutti processi figli di cui si è ricevuto lo stato di +terminazione. \begin{figure}[!htb] \footnotesize \centering - \begin{minipage}[c]{\textwidth} + \begin{minipage}[c]{0.8\textwidth} \includestruct{listati/tms.h} \end{minipage} \normalsize @@ -2202,17 +2268,56 @@ sez.~\ref{sec:sys_unix_time}. \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}. + +Si tenga presente che i tempi di processore dei processi figli di un processo +vengono sempre sommati al valore corrente ogni volta che se ne riceve lo stato +di terminazione, e detto valore è quello che viene a sua volta ottenuto dal +processo padre. Pertanto nei campi \var{tms\_cutime} e \var{tms\_cstime} si +sommano anche i tempi di ulteriori discendenti di cui i rispettivi genitori +abbiano ricevuto lo stato di terminazione. 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 processo figlio termina prima di ricevere lo stato di terminazione di tutti i suoi figli, questi processi -``\textsl{nipoti}'' non verranno considerati nel calcolo di questi tempi. +``\textsl{nipoti}'' non verranno considerati nel calcolo di questi tempi e +così via per i relativi ``\textsl{discendenti}''. + +Come accennato in sez.~\ref{sec:sys_resource_use} per i kernel precedenti la +versione 2.6.9 il tempo di processore dei processi figli veniva sommato +comunque chiedendo di ignorare \const{SIGCHLD} anche se lo standard POSIX +richiede esplicitamente che questo avvenga solo quando si riceve lo stato di +uscita con una funzione della famiglia delle \func{wait}, anche in questo caso +il comportamento è stato adeguato allo standard a partire dalla versione +2.6.9. + +A differenza di quanto avviene per \func{clock} i valori restituiti nei campi +di una struttura \struct{tms} sono misurati in numero di \itindex{clock~tick} +\textit{clock tick} effettivi e non in multipli di \const{CLOCKS\_PER\_SEC}, +pertanto per ottenere il valore effettivo in secondi occorrerà dividere per il +risultato di \code{sysconf(\_SC\_CLK\_TCK)}. + +Lo stesso vale per il valore di ritorno della funzione, il cui significato fa +riferimento ad un tempo relativo ad un certo punto nel passato la cui +definizione dipende dalle diverse implementazioni, e varia anche fra diverse +versioni del kernel. Fino al kernel 2.4 si faceva infatti riferimento al +momento dell'avvio del kernel. Con il kernel 2.6 si fa riferimento a +$2^{32}/\mathtt{HZ}-300$ secondi prima dell'avvio. + +Considerato che il numero dei \itindex{clock~tick} \textit{clock tick} per un +kernel che è attivo da molto tempo può eccedere le dimensioni per il tipo +\type{clock\_t} il comportamento più opportuno per i programmi è di ignorare +comunque il valore di ritorno della funzione e ricorrere alle funzioni per il +tempo di calendario del prossimo paragrafo qualora si voglia calcolare il +tempo effettivamente trascorso dall'inizio del programma. + +Infine si tenga presente che per dei limiti nelle convenzioni per il ritorno +dei valori delle \textit{system call} su alcune architetture hardware (ed in +particolare la \texttt{i386} dei PC a 32 bit) nel kernel della serie 2.6 il +valore di ritorno della funzione può risultare erroneamente uguale a $-1$, +indicando un errore, nei primi secondi dopo il boot (per la precisione nei +primi 41 secondi) e se il valore del contatore eccede le dimensione del tipo +\type{clock\_t}. \itindend{process~time} @@ -2223,37 +2328,51 @@ lo stato di terminazione di tutti i suoi figli, questi processi \itindbeg{calendar~time} Come anticipato in sez.~\ref{sec:sys_unix_time} il \textit{calendar time} è -mantenuto dal kernel in una variabile di tipo \type{time\_t},\footnote{in - realtà il kernel usa una rappresentazione interna di che fornisce una - precisione molto maggiore, e consente per questo anche di usare - rappresentazioni diverse del \textit{calendar time}.} che usualmente -corrisponde ad un tipo elementare (in Linux è definito come \ctyp{long int}, -che di norma corrisponde a 32 bit). Il valore corrente del \textit{calendar +mantenuto dal kernel in una variabile di tipo \type{time\_t}, che usualmente +corrisponde ad un tipo elementare; in Linux è definito come \ctyp{long int}, +che di norma corrisponde a 32 bit. Il valore corrente del \textit{calendar time}, che indicheremo come \textsl{tempo di sistema}, può essere ottenuto -con la funzione \funcd{time} che lo restituisce nel suddetto formato; il suo +con la funzione \funcd{time} che lo restituisce nel suddetto formato, il suo prototipo è: -\begin{prototype}{time.h}{time\_t time(time\_t *t)} - Legge il valore corrente del \textit{calendar time}. - - \bodydesc{La funzione ritorna il valore del \textit{calendar time} in caso - di successo e -1 in caso di errore, che può essere solo \errval{EFAULT}.} -\end{prototype} -\noindent dove \param{t}, se non nullo, deve essere l'indirizzo di una + +\begin{funcproto}{ +\fhead{time.h} +\fdecl{time\_t time(time\_t *t)} +\fdesc{Legge il valore corrente del \textit{calendar time}.} +} + +{La funzione ritorna il valore del \textit{calendar time} in caso di successo + e $-1$ per un errore, nel qual caso \var{errno} potrà assumere solo il + valore \errval{EFAULT} nel suo significato generico.} +\end{funcproto} + +\noindent dove \param{t}, se non nullo, deve essere l'indirizzo di una variabile su cui duplicare il valore di ritorno. Analoga a \func{time} è la funzione \funcd{stime} che serve per effettuare l'operazione inversa, e cioè per impostare il tempo di sistema qualora questo sia necessario; il suo prototipo è: -\begin{prototype}{time.h}{int stime(time\_t *t)} - Imposta a \param{t} il valore corrente del \textit{calendar time}. - - \bodydesc{La funzione ritorna 0 in caso di successo e -1 in caso di errore, - che può essere \errval{EFAULT} o \errval{EPERM}.} -\end{prototype} -\noindent dato che modificare l'ora ha un impatto su tutto il sistema -il cambiamento dell'orologio è una operazione privilegiata e questa funzione -può essere usata solo da un processo con i privilegi di amministratore, -altrimenti la chiamata fallirà con un errore di \errcode{EPERM}. + +\begin{funcproto}{ +\fhead{time.h} +\fdecl{int stime(time\_t *t)} +\fdesc{Imposta il valore corrente del \textit{calendar time}.} +} + +{La funzione ritorna $0$ in caso di successo e $-1$ per un errore, nel qual + caso \var{errno} assumerà uno dei valori: + \begin{errlist} + \item[\errcode{EPERM}] non si hanno i permessi di amministrazione. + \end{errlist} + ed inoltre \errval{EFAULT} nel suo significato generico.} +\end{funcproto} + + +Dato che modificare l'ora ha un impatto su tutto il sistema il cambiamento +dell'orologio è una operazione privilegiata e questa funzione può essere usata +solo da un processo con i privilegi di amministratore (per la precisione la la +\itindex{capabilities} capability \const{CAP\_SYS\_TIME}), altrimenti la +chiamata fallirà con un errore di \errcode{EPERM}. Data la scarsa precisione nell'uso di \type{time\_t} (che ha una risoluzione massima di un secondo) quando si devono effettuare operazioni sui tempi di @@ -2962,20 +3081,21 @@ linea non vengano ripetuti. % LocalWords: second delete progress has occurred BAD broken tm gmtoff asctime % LocalWords: ctime timep gmtime localtime mktime tzname tzset daylight format % LocalWords: strftime thread EOF modifiable lvalue app errcode strerror LC at -% LocalWords: perror string errnum MESSAGES error message strtol log +% LocalWords: perror string errnum MESSAGES error message strtol log jiffy asm % LocalWords: program invocation argv printf print progname exit count fname % LocalWords: lineno one standardese Di page Wed Wednesday Apr April PM AM CAD % LocalWords: CEST utmpxname Solaris updwtmpx reboot RESTART Ctrl OFF SIGINT % LocalWords: HALT halted sync KEXEC kexec load bootloader POWER Power with nr % LocalWords: Restarting command arg entry segments segment ARCH CRASH CONTEXT % LocalWords: PRESERVE PPC IA ARM SH MIPS nvcsw nivcsw inblock oublock maxrss -% LocalWords: context switch slice Resident SIG SIGCHLD cur Gb lease mlock +% LocalWords: context switch slice Resident SIG SIGCHLD cur Gb lease mlock Hz % LocalWords: memory mlockall MAP LOCKED shmctl MSGQUEUE attr NICE nice MADV % LocalWords: madvise WILLNEED RTPRIO sched setscheduler setparam scheduling -% LocalWords: RTTIME execve kb prlimit pid new old ESRCH EUSERS +% LocalWords: RTTIME execve kb prlimit pid new old ESRCH EUSERS refresh high %%% Local Variables: %%% mode: latex %%% TeX-master: "gapil" %%% End: +% LocalWords: resolution HRT jiffies -- 2.30.2