X-Git-Url: https://gapil.gnulinux.it/gitweb/?a=blobdiff_plain;f=signal.tex;h=d1a744ad981da31aa5d374e82b542fb9d3247817;hb=ea887edc424e278e36332f18ba8afb5f1ed84b11;hp=94fb886a9f7f7b20d3788236b7b8c71b82210215;hpb=99b4cf6829122cd46c4b387b977e95766853ae3b;p=gapil.git diff --git a/signal.tex b/signal.tex index 94fb886..d1a744a 100644 --- a/signal.tex +++ b/signal.tex @@ -1163,10 +1163,10 @@ che consente effettivamente di inviare un segnale generico ad un processo, il caso \var{errno} assumerà uno dei valori: \begin{errlist} \item[\errcode{EINVAL}] il segnale specificato non esiste. - \item[\errcode{ESRCH}] il processo o il gruppo di processi indicato non - esiste. \item[\errcode{EPERM}] non si hanno privilegi sufficienti ad inviare il segnale. + \item[\errcode{ESRCH}] il processo o il gruppo di processi indicato non + esiste. \end{errlist} } \end{funcproto} @@ -1469,7 +1469,7 @@ in cui un timer scade prima che il segnale di una precedente scadenza sia stato consegnato. In questo caso, per il comportamento dei segnali descritto in sez.~\ref{sec:sig_sigchld}, un solo segnale sarà consegnato. Per questo oggi l'uso di questa funzione è deprecato a favore degli -\index{High~Resolution~Timer~(HRT)} \textit{high-resolution timer} e della +\itindex{High~Resolution~Timer~(HRT)} \textit{high-resolution timer} e della cosiddetta \itindex{POSIX~Timer~API} \textit{POSIX Timer API}, che tratteremo in sez.~\ref{sec:sig_timer_adv}. @@ -1611,9 +1611,9 @@ favore della nuova funzione di sistema \funcd{nanosleep}, il cui prototipo è: {La funzione ritorna $0$ se l'attesa viene completata e $-1$ per un errore, nel qual caso \var{errno} assumerà uno dei valori: \begin{errlist} + \item[\errcode{EINTR}] la funzione è stata interrotta da un segnale. \item[\errcode{EINVAL}] si è specificato un numero di secondi negativo o un numero di nanosecondi maggiore di 999.999.999. - \item[\errcode{EINTR}] la funzione è stata interrotta da un segnale. \end{errlist} } \end{funcproto} @@ -1858,16 +1858,16 @@ azioni conseguenti (\texttt{\small 6-11}) relative. Questo è il tipico esempio di caso, già citato in sez.~\ref{sec:proc_race_cond}, in cui si genera una \itindex{race~condition} \textit{race condition}. Infatti, in una situazione in cui un segnale è già -arrivato (e quindi \var{flag} è già stata impostata ad 1 nel gestre) se un +arrivato (e quindi \var{flag} è già stata impostata ad 1 nel gestore) se un altro segnale arriva immediatamente dopo l'esecuzione del controllo (\texttt{\small 6}) ma prima della cancellazione di \var{flag} fatta subito dopo (\texttt{\small 7}), la sua occorrenza sarà perduta. Questi esempi ci mostrano come per poter eseguire una gestione effettiva dei segnali occorrono delle funzioni più sofisticate di quelle finora -illustrate. La fuzione \func{signal} infatti ha la sua origine nella +illustrate. La funzione \func{signal} infatti ha la sua origine nella interfaccia alquanto primitiva che venne adottata nei primi sistemi Unix, ma -con questa funzione è sostanzilmente impossibile gestire in maniera adeguata +con questa funzione è sostanzialmente impossibile gestire in maniera adeguata di tutti i possibili aspetti con cui un processo deve reagire alla ricezione di un segnale. @@ -2014,16 +2014,16 @@ essere gestito da un processo. Il suo prototipo è: \fhead{signal.h} \fdecl{int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact)} -\fdesc{Installa una nuova azione pr un segnale.} +\fdesc{Installa una nuova azione per un segnale.} } {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{EFAULT}] si sono specificati indirizzi non validi. \item[\errcode{EINVAL}] si è specificato un numero di segnale invalido o si è cercato di installare il gestore per \signal{SIGKILL} o \signal{SIGSTOP}. - \item[\errcode{EFAULT}] si sono specificati indirizzi non validi. \end{errlist} } \end{funcproto} @@ -2344,8 +2344,8 @@ che abbia le stesse caratteristiche di \func{signal}, a definire attraverso riportato in fig.~\ref{fig:sig_Signal_code} (il codice completo si trova nel file \file{SigHand.c} nei sorgenti allegati). Anche in questo caso, per semplificare la definizione si è poi definito un apposito tipo -\texttt{SigFunc} per esprimere in forma più comprensibile la forma di un -gestore di segnale. +\texttt{SigFunc} per esprimere in modo più comprensibile la forma di un +gestore di segnale. Si noti come, essendo la funzione estremamente semplice, essa è definita come \direct{inline}. Questa direttiva viene usata per dire al compilatore di @@ -2353,9 +2353,9 @@ trattare la funzione cui essa fa riferimento in maniera speciale inserendo il codice direttamente nel testo del programma. Anche se i compilatori più moderni sono in grado di effettuare da soli queste manipolazioni (impostando le opportune ottimizzazioni) questa è una tecnica usata per migliorare le -prestazioni per le funzioni piccole ed usate di frequente (in particolare nel +prestazioni per le funzioni piccole ed usate di frequente, in particolare nel kernel, dove in certi casi le ottimizzazioni dal compilatore, tarate per l'uso -in user space, non sono sempre adatte). +in \textit{user space}, non sono sempre adatte. In tal caso infatti le istruzioni per creare un nuovo frame nello \itindex{stack} \textit{stack} per chiamare la funzione costituirebbero una @@ -2374,7 +2374,7 @@ evitati. \index{maschera dei segnali|(} Come spiegato in sez.~\ref{sec:sig_semantics} tutti i moderni sistemi unix-like permettono di bloccare temporaneamente (o di eliminare completamente, -impostando \const{SIG\_IGN} come azione) la consegna dei segnali ad un +impostando come azione \const{SIG\_IGN}) la consegna dei segnali ad un processo. Questo è fatto specificando la cosiddetta \textsl{maschera dei segnali} (o \textit{signal mask}) del processo\footnote{nel caso di Linux essa è mantenuta dal campo \var{blocked} della \struct{task\_struct} del @@ -2414,13 +2414,13 @@ funzione di sistema \funcd{sigprocmask}, il cui prototipo è: {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{EINVAL}] si è specificato un numero di segnale invalido. \item[\errcode{EFAULT}] si sono specificati indirizzi non validi. + \item[\errcode{EINVAL}] si è specificato un numero di segnale invalido. \end{errlist} } \end{funcproto} -La funzione usa l'insieme di segnali posto all'indirizzo passanto +La funzione usa l'insieme di segnali posto all'indirizzo passato nell'argomento \param{set} per modificare la maschera dei segnali del processo corrente. La modifica viene effettuata a seconda del valore dell'argomento \param{how}, secondo le modalità specificate in @@ -2480,8 +2480,8 @@ sospensione del processo lo standard POSIX ha previsto la funzione di sistema {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{EINVAL}] si è specificato un numero di segnale invalido. \item[\errcode{EFAULT}] si sono specificati indirizzi non validi. + \item[\errcode{EINVAL}] si è specificato un numero di segnale invalido. \end{errlist} } \end{funcproto} @@ -2558,8 +2558,8 @@ interrotta. Il concetto è comunque più generale e porta ad una distinzione fra quelle che POSIX chiama \textsl{funzioni insicure} (\textit{signal unsafe function}) e -\textsl{funzioni sicure} (o più precisamente \textit{signal safe function}); -quando un segnale interrompe una funzione insicura ed il gestore chiama al suo +\textsl{funzioni sicure} (o più precisamente \textit{signal safe function}). +Quando un segnale interrompe una funzione insicura ed il gestore chiama al suo interno una funzione insicura il sistema può dare luogo ad un comportamento indefinito, la cosa non avviene invece per le funzioni sicure. @@ -2570,13 +2570,13 @@ vogliono evitare questi problemi si può ricorrere soltanto all'uso delle funzioni considerate sicure. L'elenco delle funzioni considerate sicure varia a seconda della -implementazione utilizzata e dello standard a cui si fa -riferimento;\footnote{non è riportata una lista specifica delle funzioni - sicure per Linux, si suppone pertanto che siano quelle richieste dallo - standard.} secondo quanto riportato dallo standard POSIX 1003.1 nella -revisione del 2003, le ``\textit{signal safe function}'' che possono essere -chiamate anche all'interno di un gestore di segnali sono tutte quelle della -lista riportata in fig.~\ref{fig:sig_safe_functions}. +implementazione utilizzata e dello standard a cui si fa riferimento. Non è +riportata una lista specifica delle funzioni sicure per Linux, e si suppone +pertanto che siano quelle richieste dallo standard. Secondo quanto richiesto +dallo standard POSIX 1003.1 nella revisione del 2003, le ``\textit{signal safe + function}'' che possono essere chiamate anche all'interno di un gestore di +segnali sono tutte quelle della lista riportata in +fig.~\ref{fig:sig_safe_functions}. \begin{figure}[!htb] \footnotesize \centering @@ -2665,18 +2665,18 @@ di segnali ed eventi attraverso l'uso di file descriptor. Lo standard POSIX.1b, nel definire una serie di nuove interfacce per i servizi \textit{real-time}, ha introdotto una estensione del modello classico dei segnali che presenta dei significativi miglioramenti,\footnote{questa - estensione è stata introdotta in Linux a partire dal kernel 2.1.43, e dalle - \acr{glibc} 2.1.} in particolare sono stati superati tre limiti fondamentali -dei segnali classici: + estensione è stata introdotta in Linux a partire dal kernel 2.1.43, e dalla + versione 2.1 della \acr{glibc}.} in particolare sono stati superati tre +limiti fondamentali dei segnali classici: \begin{basedescript}{\desclabelwidth{1cm}\desclabelstyle{\nextlinelabel}} \item[I segnali non sono accumulati] se più segnali vengono generati prima dell'esecuzione di un gestore questo sarà eseguito una sola volta, ed il processo non sarà in grado di - accorgersi di quante volte l'evento che ha generato il segnale è accaduto; + accorgersi di quante volte l'evento che ha generato il segnale è accaduto. \item[I segnali non trasportano informazione] i segnali classici non prevedono altra informazione sull'evento che li ha generati se non il fatto che sono stati emessi (tutta - l'informazione che il kernel associa ad un segnale è il suo numero); + l'informazione che il kernel associa ad un segnale è il suo numero). \item[I segnali non hanno un ordine di consegna] l'ordine in cui diversi segnali vengono consegnati è casuale e non prevedibile. Non è possibile stabilire una priorità per cui la reazione a @@ -2692,10 +2692,10 @@ funzionalità aggiunte sono: \item i segnali sono inseriti in una coda che permette di consegnare istanze multiple dello stesso segnale qualora esso venga inviato più volte prima dell'esecuzione del gestore; si assicura così che il processo riceva un - segnale per ogni occorrenza dell'evento che lo genera. + segnale per ogni occorrenza dell'evento che lo genera; \item è stata introdotta una priorità nella consegna dei segnali: i segnali vengono consegnati in ordine a seconda del loro valore, partendo da quelli - con un numero minore, che pertanto hanno una priorità maggiore. + con un numero minore, che pertanto hanno una priorità maggiore; \item è stata introdotta la possibilità di restituire dei dati al gestore, attraverso l'uso di un apposito campo \var{si\_value} nella struttura \struct{siginfo\_t}, accessibile tramite gestori di tipo @@ -2715,10 +2715,10 @@ che di norma (vale a dire sulla piattaforma i386) è 64. Questo dà un totale di presente però che i primi segnali \textit{real-time} disponibili vendono usati dalle \acr{glibc} per l'implementazione dei \textit{thread} POSIX (vedi sez.~\ref{sec:thread_posix_intro}), ed il valore di \const{SIGRTMIN} viene -modificato di conseguenza.\footnote{vengono usati i primi tre per la vecchia - implementazione dei \textit{LinuxThread} ed i primi due per la nuova NTPL - (\textit{New Thread Posix Library}), il che comporta che \const{SIGRTMIN} a - seconda dei casi può essere 34 o 35.} +modificato di conseguenza.\footnote{per la precisione vengono usati i primi + tre per la vecchia implementazione dei \textit{LinuxThread} ed i primi due + per la nuova NTPL (\textit{New Thread Posix Library}), il che comporta che + \const{SIGRTMIN} a seconda dei casi può assumere i valori 34 o 35.} Per questo motivo nei programmi che usano i segnali \textit{real-time} non si deve mai usare un valore assoluto dato che si correrebbe il rischio di @@ -2732,33 +2732,33 @@ consegnati per primi, inoltre i segnali \textit{real-time} non possono interrompere l'esecuzione di un gestore di un segnale a priorità più alta; la loro azione predefinita è quella di terminare il programma. I segnali ordinari hanno tutti la stessa priorità, che è più alta di quella di qualunque -segnale \textit{real-time}.\footnote{lo standard non definisce niente al - riguardo ma Linux, come molte altre implementazioni, adotta questa - politica.} +segnale \textit{real-time}. Lo standard non definisce niente al riguardo ma +Linux, come molte altre implementazioni, adotta questa politica. Si tenga presente che questi nuovi segnali non sono associati a nessun evento specifico, a meno di non richiedere specificamente il loro utilizzo in meccanismi di notifica come quelli per l'I/O asincrono (vedi sez.~\ref{sec:file_asyncronous_io}) o per le code di messaggi POSIX (vedi -sez.~\ref{sec:ipc_posix_mq}); pertanto devono essere inviati esplicitamente. +sez.~\ref{sec:ipc_posix_mq}), pertanto devono essere inviati esplicitamente. Inoltre, per poter usufruire della capacità di restituire dei dati, i relativi gestori devono essere installati con \func{sigaction}, specificando per \var{sa\_flags} la modalità \const{SA\_SIGINFO} che permette di utilizzare la -forma estesa \var{sa\_sigaction} (vedi sez.~\ref{sec:sig_sigaction}). In -questo modo tutti i segnali \textit{real-time} possono restituire al gestore -una serie di informazioni aggiuntive attraverso l'argomento -\struct{siginfo\_t}, la cui definizione è stata già vista in -fig.~\ref{fig:sig_siginfo_t}, nella trattazione dei gestori in forma estesa. +forma estesa \var{sa\_sigaction} del gestore (vedi +sez.~\ref{sec:sig_sigaction}). In questo modo tutti i segnali +\textit{real-time} possono restituire al gestore una serie di informazioni +aggiuntive attraverso l'argomento \struct{siginfo\_t}, la cui definizione è +stata già vista in fig.~\ref{fig:sig_siginfo_t}, nella trattazione dei gestori +in forma estesa. In particolare i campi utilizzati dai segnali \textit{real-time} sono \var{si\_pid} e \var{si\_uid} in cui vengono memorizzati rispettivamente il -\ids{PID} e l'\ids{UID} effettivo del processo che ha inviato il segnale, mentre -per la restituzione dei dati viene usato il campo \var{si\_value}. +\ids{PID} e l'\ids{UID} effettivo del processo che ha inviato il segnale, +mentre per la restituzione dei dati viene usato il campo \var{si\_value}. \begin{figure}[!htb] \footnotesize \centering - \begin{minipage}[c]{\textwidth} + \begin{minipage}[c]{0.8\textwidth} \includestruct{listati/sigval_t.h} \end{minipage} \normalsize @@ -2767,100 +2767,106 @@ per la restituzione dei dati viene usato il campo \var{si\_value}. \label{fig:sig_sigval} \end{figure} -Questo è una \direct{union} di tipo \struct{sigval} (la sua definizione è in +Detto campo, identificato con il tipo di dato \type{sigval\_t}, è una +\direct{union} di tipo \struct{sigval} (la sua definizione è in fig.~\ref{fig:sig_sigval}) in cui può essere memorizzato o un valore numerico, -se usata nella forma \var{sival\_int}, o un indirizzo, se usata nella forma +se usata nella forma \var{sival\_int}, o un puntatore, se usata nella forma \var{sival\_ptr}. L'unione viene usata dai segnali \textit{real-time} e da -vari meccanismi di notifica\footnote{un campo di tipo \type{sigval\_t} è - presente anche nella struttura \struct{sigevent} (definita in - fig.~\ref{fig:struct_sigevent}) che viene usata dai meccanismi di notifica - come quelli per \itindex{POSIX~Timer~API} i timer POSIX (vedi - sez.~\ref{sec:sig_timer_adv}), l'I/O asincrono (vedi - sez.~\ref{sec:file_asyncronous_io}) o le code di messaggi POSIX (vedi - sez.~\ref{sec:ipc_posix_mq}).} per restituire dati al gestore del segnale; -in alcune definizioni essa viene identificata anche con l'abbreviazione -\type{sigval\_t}. +vari meccanismi di notifica per restituire dati al gestore del segnale in +\var{si\_value}. Un campo di tipo \type{sigval\_t} è presente anche nella +struttura \struct{sigevent} (definita in fig.~\ref{fig:struct_sigevent}) che +viene usata dai meccanismi di notifica come quelli per +\itindex{POSIX~Timer~API} i timer POSIX (vedi sez.~\ref{sec:sig_timer_adv}), +l'I/O asincrono (vedi sez.~\ref{sec:file_asyncronous_io}) o le code di +messaggi POSIX (vedi sez.~\ref{sec:ipc_posix_mq}). A causa delle loro caratteristiche, la funzione \func{kill} non è adatta ad inviare segnali \textit{real-time}, poiché non è in grado di fornire alcun -valore per \struct{sigval}; per questo motivo lo standard ha previsto una -nuova funzione, \funcd{sigqueue}, il cui prototipo è: -\begin{prototype}{signal.h} - {int sigqueue(pid\_t pid, int signo, const union sigval value)} - - Invia il segnale \param{signo} al processo \param{pid}, restituendo al - gestore il valore \param{value}. - - \bodydesc{La funzione restituisce 0 in caso di successo e $-1$ in caso di - errore, nel qual caso \var{errno} assumerà uno dei valori: +valore per il campo \var{si\_value} restituito nella struttura +\struct{siginfo\_t} prevista da un gestore in forma estesa. Per questo motivo +lo standard ha previsto una nuova funzione, \funcd{sigqueue}, il cui prototipo +è: + +\begin{funcproto}{ +\fhead{signal.h} +\fdecl{int sigqueue(pid\_t pid, int signo, const union sigval value)} +\fdesc{Invia un segnale con un valore di informazione.} +} + +{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{EAGAIN}] la coda è esaurita, ci sono già \const{SIGQUEUE\_MAX} segnali in attesa si consegna. + \item[\errcode{EINVAL}] si è specificato un valore non valido per + \param{signo}. \item[\errcode{EPERM}] non si hanno privilegi appropriati per inviare il segnale al processo specificato. \item[\errcode{ESRCH}] il processo \param{pid} non esiste. - \item[\errcode{EINVAL}] si è specificato un valore non valido per - \param{signo}. \end{errlist} - ed inoltre \errval{ENOMEM}.} -\end{prototype} +} +\end{funcproto} + -Il comportamento della funzione è analogo a quello di \func{kill}, ed i -privilegi occorrenti ad inviare il segnale ad un determinato processo sono gli -stessi; un valore nullo di \param{signo} permette di verificare le condizioni -di errore senza inviare nessun segnale. +La funzione invia il segnale indicato dall'argomento \param{signo} al processo +indicato dall'argomento \param{pid}. Per il resto il comportamento della +funzione è analogo a quello di \func{kill}, ed i privilegi occorrenti ad +inviare il segnale ad un determinato processo sono gli stessi; un valore nullo +di \param{signo} permette di verificare le condizioni di errore senza inviare +nessun segnale. Se il segnale è bloccato la funzione ritorna immediatamente, se si è installato un gestore con \const{SA\_SIGINFO} e ci sono risorse disponibili, (vale a dire che c'è posto nella coda dei segnali \textit{real-time}) esso -viene inserito e diventa pendente; una volta consegnato riporterà nel campo -\var{si\_code} di \struct{siginfo\_t} il valore \const{SI\_QUEUE} e il campo -\var{si\_value} riceverà quanto inviato con \param{value}. Se invece si è -installato un gestore nella forma classica il segnale sarà generato, ma tutte -le caratteristiche tipiche dei segnali \textit{real-time} (priorità e coda) -saranno perse. +viene inserito e diventa pendente. Una volta consegnato il segnale il gestore +otterrà nel campo \var{si\_code} di \struct{siginfo\_t} il valore +\const{SI\_QUEUE} e nel campo \var{si\_value} il valore indicato +nell'argomento \param{value}. Se invece si è installato un gestore nella forma +classica il segnale sarà generato, ma tutte le caratteristiche tipiche dei +segnali \textit{real-time} (priorità e coda) saranno perse. Secondo lo standard POSIX la profondità della coda è indicata dalla costante -\const{SIGQUEUE\_MAX},\footnote{una della tante costanti di sistema definite - dallo standard POSIX che non abbiamo riportato esplicitamente in - sez.~\ref{sec:sys_limits}.} il suo valore minimo secondo lo standard, +\const{SIGQUEUE\_MAX}, una della tante costanti di sistema definite dallo +standard POSIX che non abbiamo riportato esplicitamente in +sez.~\ref{sec:sys_limits}. Il suo valore minimo secondo lo standard, \const{\_POSIX\_SIGQUEUE\_MAX}, è pari a 32. Nel caso di Linux la coda ha una dimensione variabile; fino alla versione 2.6.7 c'era un limite massimo globale che poteva essere impostato come parametro del kernel in -\sysctlfile{kernel/rtsig-max};\footnote{ed il valore predefinito era - pari a 1024.} a partire dal kernel 2.6.8 il valore globale è stato rimosso e -sostituito dalla risorsa \const{RLIMIT\_SIGPENDING} associata al singolo -utente, che può essere modificata con \func{setrlimit} come illustrato in +\sysctlfile{kernel/rtsig-max} ed il valore predefinito era pari a 1024. A +partire dal kernel 2.6.8 il valore globale è stato rimosso e sostituito dalla +risorsa \const{RLIMIT\_SIGPENDING} associata al singolo utente, che può essere +modificata con \func{setrlimit} come illustrato in sez.~\ref{sec:sys_resource_limit}. -Lo standard POSIX.1b definisce inoltre delle nuove funzioni che permettono di -gestire l'attesa di segnali specifici su una coda, esse servono in particolar -modo nel caso dei \itindex{thread} \textit{thread}, in cui si possono usare i -segnali \textit{real-time} come meccanismi di comunicazione elementare; la -prima di queste funzioni è \funcd{sigwait}, il cui prototipo è: -\begin{prototype}{signal.h} - {int sigwait(const sigset\_t *set, int *sig)} - - Attende che uno dei segnali specificati in \param{set} sia pendente. - - \bodydesc{La funzione restituisce 0 in caso di successo e $-1$ in caso di - errore, nel qual caso \var{errno} assumerà uno dei valori: +Lo standard POSIX.1b definisce inoltre delle nuove funzioni di sistema che +permettono di gestire l'attesa di segnali specifici su una coda, esse servono +in particolar modo nel caso dei \itindex{thread} \textit{thread}, in cui si +possono usare i segnali \textit{real-time} come meccanismi di comunicazione +elementare; la prima di queste è \funcd{sigwait}, il cui prototipo è: + +\begin{funcproto}{ +\fhead{signal.h} +\fdecl{int sigwait(const sigset\_t *set, int *sig)} +\fdesc{Attende la ricezione di un segnale.} +} +{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{EINTR}] la funzione è stata interrotta. \item[\errcode{EINVAL}] si è specificato un valore non valido per - \param{set}. \end{errlist} - ed inoltre \errval{EFAULT}.} -\end{prototype} + ed inoltre \errval{EFAULT} nel suo significato generico.} +\end{funcproto} -La funzione estrae dall'insieme dei segnali pendenti uno qualunque dei segnali -specificati da \param{set}, il cui valore viene restituito in \param{sig}. Se -sono pendenti più segnali, viene estratto quello a priorità più alta (cioè con -il numero più basso). Se, nel caso di segnali \textit{real-time}, c'è più di -un segnale pendente, ne verrà estratto solo uno. Una volta estratto il segnale -non verrà più consegnato, e se era in una coda il suo posto sarà liberato. Se -non c'è nessun segnale pendente il processo viene bloccato fintanto che non ne -arriva uno. +La funzione estrae dall'insieme dei segnali pendenti uno qualunque fra quelli +indicati nel \textit{signal set} specificato in \param{set}, il cui valore +viene restituito nella variabile puntata da \param{sig}. Se sono pendenti più +segnali, viene estratto quello a priorità più alta, cioè quello con il numero +più basso. Se, nel caso di segnali \textit{real-time}, c'è più di un segnale +pendente, ne verrà estratto solo uno. Una volta estratto il segnale non verrà +più consegnato, e se era in una coda il suo posto sarà liberato. Se non c'è +nessun segnale pendente il processo viene bloccato fintanto che non ne arriva +uno. Per un funzionamento corretto la funzione richiede che alla sua chiamata i segnali di \param{set} siano bloccati. In caso contrario si avrebbe un @@ -2870,47 +2876,45 @@ comportamento del sistema è indeterminato: il segnale può sia essere consegnato che essere ricevuto da \func{sigwait}, il tutto in maniera non prevedibile. -Lo standard POSIX.1b definisce altre due funzioni, anch'esse usate +Lo standard POSIX.1b definisce altre due funzioni di sistema, anch'esse usate prevalentemente con i \itindex{thread} \textit{thread}; \funcd{sigwaitinfo} e \funcd{sigtimedwait}, i relativi prototipi sono: -\begin{functions} - \headdecl{signal.h} - \funcdecl{int sigwaitinfo(const sigset\_t *set, siginfo\_t *info)} - - Analoga a \func{sigwait}, ma riceve anche le informazioni associate al - segnale in \param{info}. - - \funcdecl{int sigtimedwait(const sigset\_t *set, siginfo\_t *info, const - struct timespec *timeout)} - - Analoga a \func{sigwaitinfo}, con un la possibilità di specificare un - timeout in \param{timeout}. +\begin{funcproto}{ +\fhead{signal.h} +\fdecl{int sigwaitinfo(const sigset\_t *set, siginfo\_t *info)} +\fdesc{Attende un segnale con le relative informazioni.} +\fdecl{int sigtimedwait(const sigset\_t *set, siginfo\_t *info, const + struct timespec *timeout)} +\fdesc{Attende un segnale con le relative informazioni per un tempo massimo.} +} - - \bodydesc{Le funzioni restituiscono 0 in caso di successo e $-1$ in caso di - errore, nel qual caso \var{errno} assumerà uno dei valori già visti per - \func{sigwait}, ai quali si aggiunge, per \func{sigtimedwait}: +{Le funzioni ritornano $0$ in caso di successo e $-1$ per un errore, nel qual + caso \var{errno} assumerà uno gli stessi valori di \func{sigwait} ai quali + si aggiunge per \func{sigtimedwait}: \begin{errlist} \item[\errcode{EAGAIN}] si è superato il timeout senza che un segnale atteso - fosse emesso. + sia stato ricevuto. \end{errlist} } -\end{functions} +\end{funcproto} + Entrambe le funzioni sono estensioni di \func{sigwait}. La prima permette di ricevere, oltre al numero del segnale, anche le informazioni ad esso associate -tramite \param{info}; in particolare viene restituito il numero del segnale -nel campo \var{si\_signo}, la sua causa in \var{si\_code}, e se il segnale è -stato immesso sulla coda con \func{sigqueue}, il valore di ritorno ad esso -associato viene riportato in \var{si\_value}, che altrimenti è indefinito. - -La seconda è identica alla prima ma in più permette di specificare un timeout, -scaduto il quale ritornerà con un errore. Se si specifica un puntatore nullo -il comportamento sarà identico a \func{sigwaitinfo}, se si specifica un tempo -di timeout nullo, e non ci sono segnali pendenti la funzione ritornerà -immediatamente; in questo modo si può eliminare un segnale dalla coda senza -dover essere bloccati qualora esso non sia presente. +tramite l'argomento \param{info}; in particolare viene restituito il numero +del segnale nel campo \var{si\_signo}, la sua causa in \var{si\_code}, e se il +segnale è stato immesso sulla coda con \func{sigqueue}, il valore di ritorno +ad esso associato viene riportato in \var{si\_value}, che altrimenti è +indefinito. + +La seconda è identica alla prima ma in più permette di specificare un timeout +con l'argomento omonimo, scaduto il quale ritornerà con un errore. Se si +specifica per \param{timeoout} un puntatore nullo il comportamento sarà +identico a \func{sigwaitinfo}. Se si specifica un tempo di timeout nullo e non +ci sono segnali pendenti la funzione ritornerà immediatamente, in questo modo +si può eliminare un segnale dalla coda senza dover essere bloccati qualora +esso non sia presente. \itindbeg{thread} @@ -2933,29 +2937,31 @@ riceverlo fra due chiamate successive. % TODO: indicizzare i termini \itindex{POSIX~Timer~API} e HRT - Sia le funzioni per la gestione dei tempi viste in sez.~\ref{sec:sys_cpu_times} che quelle per la gestione dei timer di sez.~\ref{sec:sig_alarm_abort} sono state a lungo limitate dalla risoluzione 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 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 - \func{setitimer}, problemi per il massimo periodo di tempo copribile da - alcuni di questi orologi, come quelli associati al \textit{process time} - almeno fino a quando, con il kernel 2.6.16, non è stato rimosso il limite di - un valore a 32 bit per i \textit{jiffies}.} +dal timer di sistema che governa lo \textit{scheduler}, 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 tempi infatti erano basati sul numero di +\itindex{jiffies} \textit{jiffies} che vengono incrementati ad ogni +\textit{clock tick} del timer di sistema, il che comportava anche, come +accennato in sez.~\ref{sec:sig_alarm_abort} per \func{setitimer}, problemi per +il massimo periodo di tempo copribile da alcuni di questi orologi, come quelli +associati al \textit{process time} almeno fino a quando, con il kernel 2.6.16, +non è stato rimosso il limite di un valore a 32 bit per i \textit{jiffies}. + +\itindbeg{POSIX~Timer~API} Nelle architetture moderne però tutti i computer sono dotati di temporizzatori hardware che possono supportare risoluzioni molto elevate, ed in maniera del tutto indipendente dalla frequenza scelta per il timer di sistema che governa -lo \textit{scheduler};\footnote{normalmente si possono ottenere precisioni - fino al microsecondo, andando molto oltre in caso di hardware dedicato.} per -questo lo standard POSIX.1-2001 ha previsto una serie di nuove funzioni +lo \textit{scheduler}, normalmente si possono ottenere precisioni fino al +microsecondo, andando molto oltre in caso di hardware dedicato. + +Per questo lo standard POSIX.1-2001 ha previsto una serie di nuove funzioni relative a quelli che vengono chiamati ``\textsl{orologi} \textit{real-time}'', in grado di supportare risoluzioni fino al nanosecondo. Inoltre le CPU più moderne sono dotate a loro volta di contatori @@ -2966,27 +2972,27 @@ Per usare queste funzionalità ed ottenere risoluzioni temporali più accurate, occorre però un opportuno supporto da parte del kernel, ed i cosiddetti \itindex{High~Resolution~Timer~(HRT)} \textit{high resolution timer} che consentono di fare ciò sono stati introdotti nel kernel ufficiale solo a -partire dalla versione 2.6.21.\footnote{deve essere stata abilitata l'opzione - di compilazione \texttt{CONFIG\_HIGH\_RES\_TIMERS}, erano però disponibili - anche in precedenza come patch facenti parte dello sviluppo delle estensioni - \textit{real-time} del kernel, per cui alcune distribuzioni possono avere - questo supporto anche con versioni precedenti del kernel.} Le funzioni -definite dallo standard POSIX per gestire orologi ad alta definizione però -erano già presenti, essendo stata introdotte insieme ad altre funzioni per il -supporto delle estensioni \textit{real-time} con il rilascio del kernel 2.6, -ma la risoluzione effettiva era nominale. +partire dalla versione 2.6.21.\footnote{per il supporto deve essere stata + abilitata l'opzione di compilazione \texttt{CONFIG\_HIGH\_RES\_TIMERS}, il + supporto era però disponibile anche in precedenza nei patch facenti parte + dello sviluppo delle estensioni \textit{real-time} del kernel, per cui + alcune distribuzioni possono averlo anche con versioni precedenti del + kernel.} Le funzioni definite dallo standard POSIX per gestire orologi ad +alta definizione però erano già presenti, essendo stata introdotte insieme ad +altre funzioni per il supporto delle estensioni \textit{real-time} con il +rilascio del kernel 2.6, ma la risoluzione effettiva era nominale. A tutte le implementazioni che si rifanno a queste estensioni è richiesto di disporre di una versione \textit{real-time} almeno per l'orologio generale di sistema, quello che mantiene il \textit{calendar time} (vedi sez.~\ref{sec:sys_time_base}), che in questa forma deve indicare il numero di secondi e nanosecondi passati a partire dal primo gennaio 1970 (\textit{The - Epoch}).\footnote{si ricordi che l'orologio ordinario usato dal - \textit{calendar time} riporta solo un numero di secondi, e che la - risoluzione effettiva normalmente non raggiunge il nanosecondo (a meno di - hardware specializzato).} Oltre all'orologio generale di sistema possono -essere presenti altri tipi di orologi \textit{real-time}, ciascuno dei quali -viene identificato da un opportuno valore di una variabile di tipo + Epoch}). Si ricordi infatti che l'orologio ordinario usato dal +\textit{calendar time} riporta solo un numero di secondi, e che la risoluzione +effettiva normalmente non raggiunge il nanosecondo (a meno di hardware +specializzato). Oltre all'orologio generale di sistema possono essere +presenti altri tipi di orologi \textit{real-time}, ciascuno dei quali viene +identificato da un opportuno valore di una variabile di tipo \type{clockid\_t}; un elenco di quelli disponibili su Linux è riportato in tab.~\ref{tab:sig_timer_clockid_types}. @@ -3009,7 +3015,9 @@ tab.~\ref{tab:sig_timer_clockid_types}. \const{CLOCK\_MONOTONIC\_RAW}&Simile al precedente, ma non subisce gli aggiustamenti dovuti all'uso di NTP (viene usato per fare riferimento ad una fonte - hardware).\footnotemark\\ + hardware). Questo orologio è specifico di + Linux, ed è disponibile a partire dal kernel + 2.6.28.\\ \const{CLOCK\_PROCESS\_CPUTIME\_ID}& contatore del tempo di CPU usato da un processo (il \textit{process time} di sez.~\ref{sec:sys_cpu_times}, nel totale di @@ -3021,6 +3029,23 @@ tab.~\ref{tab:sig_timer_clockid_types}. (\textit{user time} e \textit{system time}) usato da un singolo \itindex{thread} \textit{thread}.\\ + \const{CLOCK\_BOOTTIME} & Identico a \const{CLOCK\_MONOTONIC} ma tiene + conto anche del tempo durante il quale il + sistema è stato sospeso (nel caso di + sospenzione in RAM o \textsl{ibernazione} su + disco. Questo orologio è specifico di Linux, + ed è disponibile a partire dal kernel + 2.6.39.\\ + \const{CLOCK\_REALTIME\_ALARM}&Identico a \const{CLOCK\_REALTIME}, ma se + usato per un timer il sistema sarà riattivato + anche se è in sospensione. Questo orologio è + specifico di Linux, ed è disponibile a + partire dal kernel 3.0.\\ + \const{CLOCK\_BOOTTIME\_ALARM}&Identico a \const{CLOCK\_BOOTTIME}, ma se + usato per un timer il sistema sarà riattivato + anche se è in sospensione. Questo orologio è + specifico di Linux, ed è disponibile a + partire dal kernel 3.0.\\ % \const{} & .\\ \hline \end{tabular} @@ -3029,14 +3054,11 @@ tab.~\ref{tab:sig_timer_clockid_types}. \label{tab:sig_timer_clockid_types} \end{table} -\footnotetext{specifico di Linux, introdotto a partire dal kernel 2.6.28, non - previsto da POSIX e non presente in altri sistemi unix-like.} % TODO: aggiungere le estensioni introdotte con il 2.6.38, verificandone il % funzionamento, vedi http://lwn.net/Articles/429595/ -% TODO: dal 2.6.39 anche CLOCK_BOOTTIME_ALARM e CLOCK_BOOTTIME, vedi -% http://lwn.net/Articles/429925/ -% TODP: dal 3.0 anche i cosiddetti Posix Alarm Timers, con +% TODO: dal 2.6.39 anche CLOCK_BOOTTIME_ALARM e CLOCK_BOOTTIME +% TODO: dal 3.0 anche i cosiddetti Posix Alarm Timers, con % CLOCK_REALTIME_ALARM vedi http://lwn.net/Articles/429925/ Per poter utilizzare queste funzionalità le \acr{glibc} richiedono che la @@ -3044,41 +3066,44 @@ macro \macro{\_POSIX\_C\_SOURCE} sia definita ad un valore maggiore o uguale di \texttt{199309L} (vedi sez.~\ref{sec:intro_gcc_glibc_std}), inoltre i programmi che le usano devono essere collegati con la libreria delle estensioni \textit{real-time} usando esplicitamente l'opzione -\texttt{-lrt}. Si tenga presente inoltre che la disponibilità di queste -funzionalità avanzate può essere controllato dalla definizione della macro -\macro{\_POSIX\_TIMERS} ad un valore maggiore di 0, e che le ulteriori macro +\texttt{-lrt}. + +Si tenga presente inoltre che la disponibilità di queste funzionalità avanzate +può essere controllato dalla definizione della macro \macro{\_POSIX\_TIMERS} +ad un valore maggiore di 0, e che le ulteriori macro \macro{\_POSIX\_MONOTONIC\_CLOCK}, \macro{\_POSIX\_CPUTIME} e \macro{\_POSIX\_THREAD\_CPUTIME} indicano la presenza dei rispettivi orologi di tipo \const{CLOCK\_MONOTONIC}, \const{CLOCK\_PROCESS\_CPUTIME\_ID} e -\const{CLOCK\_PROCESS\_CPUTIME\_ID}.\footnote{tutte queste macro sono definite - in \headfile{unistd.h}, che pertanto deve essere incluso per poterle - controllarle.} Infine se il kernel ha il supporto per gli \textit{high +\const{CLOCK\_PROCESS\_CPUTIME\_ID}; tutte queste macro sono definite in +\headfile{unistd.h}, che pertanto deve essere incluso per poterle +controllarle. Infine se il kernel ha il supporto per gli \textit{high resolution timer} un elenco degli orologi e dei timer può essere ottenuto tramite il file \procfile{/proc/timer\_list}. Le due funzioni che ci consentono rispettivamente di modificare o leggere il valore per uno degli orologi \textit{real-time} sono \funcd{clock\_settime} e \funcd{clock\_gettime}; i rispettivi prototipi sono: -\begin{functions} - \headdecl{time.h} - \funcdecl{int clock\_settime(clockid\_t clockid, const struct timespec *tp)} - \funcdecl{int clock\_gettime(clockid\_t clockid, struct timespec *tp)} - - Imposta o legge un orologio \textit{real-time}. - - \bodydesc{La funzione restituisce 0 in caso di successo e $-1$ in caso di - errore, nel qual caso \var{errno} assumerà uno dei seguenti valori: +\begin{funcproto}{ +\fhead{time.h} +\fdecl{int clock\_settime(clockid\_t clockid, const struct timespec *tp)} +\fdesc{Imposta un orologio \textit{real-time}.} +\fdecl{int clock\_gettime(clockid\_t clockid, struct timespec *tp)} +\fdesc{Legge un orologio \textit{real-time}.} +} + +{Le funzioni ritornano $0$ in caso di successo e $-1$ per un errore, nel qual + caso \var{errno} assumerà uno dei valori: \begin{errlist} + \item[\errcode{EFAULT}] l'indirizzo \param{tp} non è valido. \item[\errcode{EINVAL}] il valore specificato per \param{clockid} non è valido o il relativo orologio \textit{real-time} non è supportato dal sistema. \item[\errcode{EPERM}] non si ha il permesso di impostare l'orologio indicato (solo per \func{clock\_settime}). - \item[\errcode{EFAULT}] l'indirizzo \param{tp} non è valido. \end{errlist} } -\end{functions} +\end{funcproto} Entrambe le funzioni richiedono che si specifichi come primo argomento il tipo di orologio su cui si vuole operare con uno dei valori di @@ -3116,9 +3141,9 @@ orologio, la funzione è \funcd{clock\_getres} ed il suo prototipo è: \bodydesc{La funzione restituisce 0 in caso di successo e $-1$ in caso di errore, nel qual caso \var{errno} assumerà uno dei seguenti valori: \begin{errlist} + \item[\errcode{EFAULT}] l'indirizzo di \param{res} non è valido. \item[\errcode{EINVAL}] il valore specificato per \param{clockid} non è valido. - \item[\errcode{EFAULT}] l'indirizzo di \param{res} non è valido. \end{errlist} } \end{functions} @@ -3384,11 +3409,11 @@ identificatore, si può attivare o disattivare un allarme (in gergo \bodydesc{La funzione restituisce 0 in caso di successo e $-1$ in caso di errore, nel qual caso \var{errno} assumerà uno dei seguenti valori: \begin{errlist} + \item[\errcode{EFAULT}] si è specificato un indirizzo non valido + per \param{new\_value} o \param{old\_value}. \item[\errcode{EINVAL}] all'interno di \param{new\_value.value} si è specificato un tempo negativo o un numero di nanosecondi maggiore di 999999999. - \item[\errcode{EFAULT}] si è specificato un indirizzo non valido - per \param{new\_value} o \param{old\_value}. \end{errlist} } \end{functions} @@ -3506,9 +3531,9 @@ tempo mancante ad una sua eventuale scadenza, si deve utilizzare la funzione \bodydesc{La funzione restituisce 0 in caso di successo e $-1$ in caso di errore, nel qual caso \var{errno} assumerà uno dei seguenti valori: \begin{errlist} - \item[\errcode{EINVAL}] \param{timerid} non indica un timer valido. \item[\errcode{EFAULT}] si è specificato un indirizzo non valido per \param{curr\_value}. + \item[\errcode{EINVAL}] \param{timerid} non indica un timer valido. \end{errlist} } \end{functions} @@ -3552,6 +3577,10 @@ questo era stato attivato. Nel caso, poco probabile ma comunque possibile, che un timer venga cancellato prima della ricezione del segnale pendente per la notifica di una scadenza, il comportamento del sistema è indefinito. +\itindend{POSIX~Timer~API} + + + \subsection{Ulteriori funzioni di gestione} \label{sec:sig_specific_features} @@ -3621,14 +3650,14 @@ Installa un nuovo \textit{stack} per i segnali. errore, nel qual caso \var{errno} assumerà i valori: \begin{errlist} - \item[\errcode{ENOMEM}] la dimensione specificata per il nuovo - \textit{stack} è minore di \const{MINSIGSTKSZ}. - \item[\errcode{EPERM}] uno degli indirizzi non è valido. \item[\errcode{EFAULT}] si è cercato di cambiare lo \textit{stack} alternativo mentre questo è attivo (cioè il processo è in esecuzione su di esso). \item[\errcode{EINVAL}] \param{ss} non è nullo e \var{ss\_flags} contiene un valore diverso da zero che non è \const{SS\_DISABLE}. + \item[\errcode{ENOMEM}] la dimensione specificata per il nuovo + \textit{stack} è minore di \const{MINSIGSTKSZ}. + \item[\errcode{EPERM}] uno degli indirizzi non è valido. \end{errlist}} \end{prototype} @@ -3789,10 +3818,11 @@ parte l'uso di \type{sigjmp\_buf} per \param{env}, è assolutamente identica a % LocalWords: ENOSYS pthread ENOENT NULL attribute itimerspec new old ABSTIME % LocalWords: epoch multiplexing overrun res lpthread sec nsec curr one shot % LocalWords: delete stopped gdb alpha mips emulation locking ppoll epoll PGID +% LocalWords: pwait msgrcv msgsnd semop semtimedop runnable sigisemptyset %%% Local Variables: %%% mode: latex %%% TeX-master: "gapil" %%% End: -% LocalWords: pwait msgrcv msgsnd semop semtimedop runnable +% LocalWords: sigorset sigandset