\includestruct{listati/sigval_t.h}
\end{minipage}
\normalsize
- \caption{La unione \structd{sigval\_t}.}
+ \caption{La definizione dell'unione \structd{sigval}, definita anche come
+ tipo \type{sigval\_t}.}
\label{fig:sig_sigval}
\end{figure}
-Questo è una \ctyp{union} di tipo \struct{sigval\_t} (la sua definizione è in
+Questo è una \ctyp{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
\var{sival\_ptr}. L'unione viene usata dai segnali \textit{real-time} e da
vari meccanismi di notifica\footnote{un campo di tipo \struct{sigval\_t} è
presente anche nella struttura \struct{sigevent} (definita in
- fig.~\ref{fig:file_sigevent}) che viene usata dai meccanismi di notifica
- come quelli per 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 come \code{union sigval}.
+ fig.~\ref{fig:struct_sigevent}) che viene usata dai meccanismi di notifica
+ come quelli per 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}.
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\_t}; per questo motivo lo standard ha previsto una
+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 sigval\_t value)}
+ {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}.
segnale in \param{info}.
\funcdecl{int sigtimedwait(const sigset\_t *set, siginfo\_t *info, const
- struct timespec *timout)}
+ struct timespec *timeout)}
Analoga a \func{sigwaitinfo}, con un la possibilità di specificare un
timeout in \param{timeout}.
amministrativi.\\
\const{CLOCK\_MONOTONIC} & Orologio che indica un tempo monotono
crescente (a partire da un tempo iniziale non
- specificati) che non può essere modificato.\\
+ specificato) che non può essere modificato.\\
\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).\footnotemark\\
\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
\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 \texttt{unistd.h}, che peranto deve essere incluso per poterle
+ in \texttt{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
-tremite il file \procfile{/proc/timer\_list}.
+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
\func{clock\_getcpuclockid} (che tratteremo a breve), il secondo argomento
invece è sempre il puntatore \param{tp} ad una struttura \struct{timespec}
(vedi fig.~\ref{fig:sys_timespec_struct}) che deve essere stata
-precedentemente allocata; nel primo caso questa devrà anche essere stata
+precedentemente allocata; nel primo caso questa dovrà anche essere stata
inizializzata con il valore che si vuole impostare sull'orologio, mentre nel
secondo verrà restituito al suo interno il valore corrente dello stesso.
}
\end{functions}
-La funzione richiede come primo argomento l'indicazione dell' orologio di cui
+La funzione richiede come primo argomento l'indicazione dell'orologio di cui
si vuole conoscere la risoluzione (effettuata allo stesso modo delle due
precedenti) e questa verrà restituita in una struttura \struct{timespec}
all'indirizzo puntato dall'argomento \param{res}.
Come accennato il valore di questa risoluzione dipende sia dall'hardware
disponibile che dalla implementazione delle funzioni, e costituisce il limite
-minimo di un intervallo di tempo che si può indicare, qualunque valore si
+minimo di un intervallo di tempo che si può indicare. Qualunque valore si
voglia utilizzare nelle funzioni di impostazione che non corrisponda ad un
multiplo intero di questa risoluzione, sarà troncato in maniera automatica.
Con i sistemi multiprocessore infatti ogni singola CPU ha i suoi registri
interni, e se ciascuna di esse utilizza una base di tempo diversa (se cioè il
-clock del processore non è unico) avendo queste in genere frequenze
-leggermente diverse, otterremo dei valori dei contatori scorrelati fra loro
-senza possibilità di sincronizzazione.
+segnale di temporizzazione inviato ai processori non ha una sola provenienza)
+in genere ciascuna di queste potrà avere delle frequenze leggermente diverse,
+e si otterranno pertanto dei valori dei contatori scorrelati fra loro, senza
+nessuna possibilità di sincronizzazione.
Il problema si presenta, in forma più lieve, anche se la base di tempo è la
stessa, dato che un sistema multiprocessore non avvia mai tutte le CPU allo
Ottiene l'identificatore dell'orologio di CPU usato da un processo.
- \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:
+ \bodydesc{La funzione restituisce 0 in caso di successo o un numero positivo
+ in caso di errore, nel qual caso \var{errno} assumerà uno dei seguenti
+ valori:
\begin{errlist}
- \item[\errcode{ENOSYS}] non e.
- \item[\errcode{EPERM}] l'indirizzo di \param{res} non è valido.
- \item[\errcode{ENOENT}] non c'è modo di avere un
+ \item[\errcode{ENOSYS}] non c'è il supporto per ottenere l'orologio relativo
+ al \textit{process time} di un altro processo, e \param{pid} non
+ corrisponde al processo corrente.
+ \item[\errcode{EPERM}] il chiamante non ha il permesso di accedere alle
+ informazioni relative al processo \param{pid}.
\item[\errcode{ESRCH}] non esiste il processo \param{pid}.
\end{errlist}
}
\end{functions}
-% TODO trattare gli orologi ad alta definizione e le funzioni POSIX per gli
-% stessi cioè:
-% clock_getres clock_gettime clock_settime (vedi man page)
+La funzione ritorna l'identificativo di un orologio di sistema associato ad un
+processo indicato tramite l'argomento \param{pid}. Un utente normale, posto
+che il kernel sia sufficientemente recente da supportare questa funzionalità,
+può accedere soltanto ai dati relativi ai propri processi.
-Abbiamo visto in sez.~\ref{sec:sig_alarm_abort} come l'interfaccia di
-\func{setitimer} derivata da BSD presenti delle limitazioni,\footnote{in
- particolare la possibilità di perdere un segnale sotto carico.} tanto che
-nello standard POSIX.1-2008 questa viene marcata come obsoleta, e ne viene
-fortemente consigliata la sostituzione con nuova interfaccia definita dallo
-standard POSIX.1-2001 che va sotto il nome di \textit{Posix Timer API}.
+Del tutto analoga a \func{clock\_getcpuclockid}, ma da utilizzare per ottenere
+l'orologio associato ad un \textit{thread} invece che a un processo, è
+\funcd{pthread\_getcpuclockid},\footnote{per poter usare la funzione, come per
+ qualunque funzione che faccia riferimento ai \textit{thread}, occorre
+ effettuare il collegamento alla relativa libreria di gestione compilando il
+ programma con \texttt{-lpthread}.} il cui prototipo è:
+\begin{functions}
+ \headdecl{pthread.h}
+ \headdecl{time.h}
-La \textit{system call} per la nuova interfaccia sono stata introdotte a
-partire dal kernel 2.6, ma fino al kernel 2.6.16 la precisione degli allarmi
-era limitata dalla risoluzione del timer di sistema, e solo a partire dal
-kernel 2.6.21, con la implementazione delle temporizzazioni ad alta
-definizione, la risoluzione corrisponde a quella fornita dall'hardware
-disponibile.
+ \funcdecl{int pthread\_getcpuclockid(pthread\_t thread, clockid\_t *clockid)}
+
+ Ottiene l'identificatore dell'orologio di CPU associato ad un
+ \textit{thread}.
+
+ \bodydesc{La funzione restituisce 0 in caso di successo o un numero positivo
+ in caso di errore, nel qual caso \var{errno} assumerà uno dei seguenti
+ valori:
+ \begin{errlist}
+ \item[\errcode{ENOENT}] la funzione non è supportata dal sistema.
+ \item[\errcode{ESRCH}] non esiste il \textit{thread} identificato
+ da \param{thread}.
+ \end{errlist}
+}
+\end{functions}
+
+
+Con l'introduzione degli orologi ad alta risoluzione è divenuto possibile
+ottenere anche una gestione più avanzata degli allarmi; abbiamo già visto in
+sez.~\ref{sec:sig_alarm_abort} come l'interfaccia di \func{setitimer} derivata
+da BSD presenti delle serie limitazioni,\footnote{in particolare la
+ possibilità di perdere un segnale sotto carico.} tanto che nello standard
+POSIX.1-2008 questa viene marcata come obsoleta, e ne viene fortemente
+consigliata la sostituzione con nuova interfaccia definita dallo standard
+POSIX.1-2001 che va sotto il nome di \textit{Posix Timer API}. Questa
+interfaccia è stata introdotta a partire dal kernel 2.6, anche se il supporto
+di varie funzionalità è stato aggiunto solo in un secondo tempo.
Una delle principali differenze della nuova interfaccia è che un processo può
utilizzare un numero arbitrario di timer; questi vengono creati (ma non
Crea un nuovo timer Posix.
\bodydesc{La funzione restituisce 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}:
+ errore, nel qual caso \var{errno} assumerà uno dei seguenti valori:
\begin{errlist}
\item[\errcode{EAGAIN}] fallimento nel tentativo di allocare le strutture
dei timer.
}
\end{functions}
-La funzione richiede tre argomenti, il primo serve ad indicare quale tipo di
-orologio
-
-
- fig.~\ref{fig:file_sigevent}
+La funzione richiede tre argomenti: il primo argomento serve ad indicare quale
+tipo di orologio si vuole utilizzare e prende uno dei valori di
+tab.~\ref{tab:sig_timer_clockid_types},\footnote{di detti valori però non è
+ previsto l'uso di \const{CLOCK\_MONOTONIC\_RAW} mentre
+ \const{CLOCK\_PROCESS\_CPUTIME\_ID} e \const{CLOCK\_THREAD\_CPUTIME\_ID}
+ sono disponibili solo a partire dal kernel 2.6.12.} si può così fare
+riferimento sia ad un tempo assoluto che al tempo utilizzato dal processo (o
+\textit{thread}) stesso.
+
+Il secondo argomento richiede una trattazione più dettagliata, in quanto
+introduce una struttura di uso generale, \struct{sigevent}, che viene
+utilizzata anche da altre funzioni, come quelle per l'I/O asincrono (vedi
+sez.~\ref{sec:file_asyncronous_io}) o le code di messaggi POSIX (vedi
+sez.~\ref{sec:ipc_posix_mq})) e che serve ad indicare in maniera generica un
+meccanismo di notifica.
\begin{figure}[!htb]
\footnotesize \centering
\includestruct{listati/sigevent.h}
\end{minipage}
\normalsize
- \caption{La struttura \structd{sigevent}, usata per specificare le modalità
- di notifica degli eventi relativi alle operazioni di I/O asincrono.}
- \label{fig:file_sigevent}
+ \caption{La struttura \structd{sigevent}, usata per specificare in maniera
+ generica diverse modalità di notifica degli eventi.}
+ \label{fig:struct_sigevent}
\end{figure}
+La struttura \struct{sigevent} (accessibile includendo \texttt{time.h}) è
+riportata in fig.~\ref{fig:struct_sigevent};\footnote{la definizione effettiva
+ dipende dall'implementazione, quella mostrata è la versione descritta nella
+ pagina di manuale di \func{timer\_create}.} il campo \var{sigev\_notify} è il
+più importante essendo quello che indica le modalità della notifica, gli altri
+dipendono dal valore che si è specificato per \var{sigev\_notify}, si sono
+riportati in tab.~\ref{tab:sigevent_sigev_notify}. La scelta del meccanismo di
+notifica viene fatta impostando uno dei valori di
+tab.~\ref{tab:sigevent_sigev_notify} per \var{sigev\_notify}, e fornendo gli
+eventuali ulteriori argomenti necessari a secondo della scelta
+effettuata. Diventa così possibile indicare l'uso di un segnale o l'esecuzione
+(nel caso di uso dei \textit{thread}) di una funzione di modifica in un
+\textit{thread} dedicato.
+
+\begin{table}[htb]
+ \footnotesize
+ \centering
+ \begin{tabular}[c]{|l|p{10cm}|}
+ \hline
+ \textbf{Valore} & \textbf{Significato} \\
+ \hline
+ \hline
+ \const{SIGEV\_NONE} & Non viene inviata nessuna notifica.\\
+ \const{SIGEV\_SIGNAL} & La notifica viene effettuata inviando al processo
+ chiamante il segnale specificato dal campo
+ \var{sigev\_signo}; se il gestore di questo
+ segnale è stato installato con
+ \const{SA\_SIGINFO} gli verrà restituito il
+ valore specificato con \var{sigev\_value} (una
+ \ctyp{union} \texttt{sigval}, la cui definizione
+ è in fig.~\ref{fig:sig_sigval}) come valore del
+ campo \var{si\_value} di \struct{siginfo\_t}.\\
+ \const{SIGEV\_THREAD} & La notifica viene effettuata creando un nuovo
+ \itindex{thread} \textit{thread} che esegue la
+ funzione di notifica specificata da
+ \var{sigev\_notify\_function} con argomento
+ \var{sigev\_value}, se diverso da \val{NULL} il
+ \textit{thread} viene creato con gli attributi
+ specificati da \var{sigev\_notify\_attribute}.\\
+ \const{SIGEV\_THREAD\_ID}& Invia la notifica come segnale (con le stesse
+ modalità di \const{SIGEV\_SIGNAL}) che però viene
+ recapitato al \textit{thread} indicato dal campo
+ \var{sigev\_notify\_thread\_id}. Questa modalità
+ è una estensione specifica di Linux, creata come
+ supporto per le librerie di gestione dei
+ \textit{thread}, pertanto non deve essere usata
+ da codice normale.\\
+ \hline
+ \end{tabular}
+ \caption{Valori possibili per il campo \var{sigev\_notify} in una struttura
+ \struct{sigevent}.}
+ \label{tab:sigevent_sigev_notify}
+\end{table}
+
+Nel caso di \func{timer\_create} occorrerà passare alla funzione come secondo
+argomento l'indirizzo di una di queste strutture per indicare le modalità con
+cui si vuole essere notificati della scadenza del timer, se non si specifica
+nulla (passando un valore \val{NULL}) verrà inviato il segnale
+\const{SIGALRM} al processo corrente, o per essere più precisi verrà
+utilizzato un valore equivalente all'aver specificato \const{SIGEV\_SIGNAL}
+per \var{sigev\_notify}, \const{SIGALRM} per \var{sigev\_signo} e
+l'identificatore del timer come valore per \var{sigev\_value.sival\_int}.
+
+
+Il terzo argomento deve essere l'indirizzo di una variabile di tipo
+\type{timer\_t} dove sarà scritto l'identificativo associato al timer appena
+creato, da usare in tutte le successive funzioni di gestione. Una volta creato
+questo identificativo resterà univoco all'interno del processo stesso fintanto
+che il timer non viene cancellato.
+
+Si tenga presente che eventuali POSIX timer creati da un processo non vengono
+ereditati dai processi figli creati con \func{fork} e che vengono cancellati
+nella esecuzione di un programma diverso attraverso una delle funzioni
+\func{exec}. Si tenga presente inoltre che il kernel prealloca l'uso di un
+segnale \textit{real-time} per ciascun timer che viene creato con
+\func{timer\_create}; dato che ciascuno di essi richiede un posto nella coda
+dei segnali \textit{real-time}, il numero massimo di timer utilizzabili da un
+processo è limitato dalle dimensioni di detta coda, ed anche, qualora questo
+sia stato impostato, dal limite \const{RLIMIT\_SIGPENDING}
+
+Una volta creato il timer \func{timer\_create} ed ottenuto il relativo
+identificatore, si può attivare o disattivare un allarme (in gergo
+\textsl{armare} o \textsl{disarmare} il timer) con la funzione
+\funcd{timer\_settime}, il cui prototipo è:
+\begin{functions}
+ \headdecl{signal.h}
+ \headdecl{time.h}
+
+ \funcdecl{int timer\_settime(timer\_t timerid, int flags, const struct
+ itimerspec *new\_value, struct itimerspec *old\_value)}
+
+ Arma o disarma il timer POSIX.
+
+ \bodydesc{La funzione restituisce 0 in caso di successo e $-1$
+ in caso di errore, nel qual caso \var{errno} assumerà
+ errore, nel qual caso \var{errno} assumerà uno dei seguenti valori:
+ \begin{errlist}
+ \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}
+
+La funzione richiede che si indichi la scadenza del timer con
+l'argomento \param{new\_value}, che deve essere specificato come puntatore ad
+una struttura di tipo \struct{itimerspec}, la cui definizione è riportata in
+fig.~\ref{fig:struct_itimerspec}; se il puntatore \param{old\_value} è diverso
+da \val{NULL} il valore corrente della scadenza verrà restituito in una
+analoga struttura, ovviamente in entrambi i casi le strutture devono essere
+state allocate.
+\begin{figure}[!htb]
+ \footnotesize \centering
+ \begin{minipage}[c]{15cm}
+ \includestruct{listati/itimerspec.h}
+ \end{minipage}
+ \normalsize
+ \caption{La struttura \structd{itimerspec}, usata per specificare la
+ scadenza di un allarme.}
+ \label{fig:struct_itimerspec}
+\end{figure}
+Ciascuno dei due campi di \struct{itimerspec} indica un tempo, da specificare
+con una precisione fino al nanosecondo tramite una struttura \struct{timespec}
+(la cui definizione è riportata fig.~\ref{fig:sys_timespec_struct}). Il campo
+\var{it\_value} indica la prima scadenza dell'allarme. Di default, quando il
+valore di \param{flag} è nullo, questo valore viene considerato come un
+intervallo relativo al tempo corrente,\footnote{il primo allarme scatterà cioè
+ dopo il numero di secondi e nanosecondi indicati da questo campo.} se invece
+si usa per \param{flag} il valore \const{TIMER\_ABSTIME}, \var{it\_value}
+viene considerato come valore assoluto rispetto al valore dell'orologio a cui
+è associato il timer.\footnote{quindi a seconda dell'orologio che si usa, si
+ può indicare sia un tempo assoluto, se si opera rispetto all'orologio di
+ sistema (nel qual caso il valore deve essere in secondi e nanosecondi dalla
+ \textit{epoch}) o come un certo numero di secondi o nanosecondi rispetto
+ alla partenza di un orologio di CPU.}
+
+Il campo \var{it\_interval} consente invece di importare un allarme periodico,
+se il suo valore è nullo (se cioè sono nulli tutti e due i valori di detta
+struttura \struct{timespec}) l'allarme scatterà una sola volta secondo quando
+indicato con \var{it\_value}, altrimenti il valore specificato verrà preso
+come estensione del periodo di ripetizione della generazione dell'allarme.
+
+Se si indica un tempo
% TODO trattare i Posix timer, e le fuzioni:
\subsection{Le interfacce per la notifica attraverso i file descriptor}
\label{sec:sig_signalfd_eventfd}
-
+
+I segnali sono uno dei meccanismi classici, presenti da sempre nei sistemi
+unix-like, per effettuare notifiche ai processi, la loro interfaccia però si è
+dimostrata quasi subito poco azzeccata, in particolare per i problemi che si
+vengono a creare con le funzioni di gestione dell'I/O multiplexing (vedi
+sez.~\ref{sec:file_multiplexing}).\footnote{i temi trattati in questa sezione
+ presuppongono la conoscenza dell'I/O multiplexing si consiglia pertanto una
+ lettura di sez.~\ref{sec:file_multiplexing} qualora non si conosca
+ l'argomento. } Per questo motivo nello sviluppo del kernel si è pensato di
+introdurre un meccanismo alternativo per la notifica dei segnali (ed anche di
+eventi generici) basato direttamente sull'uso di file descriptor.
+
+
+
% TODO trattare qui eventfd signalfd e timerfd introdotte con il 2.6.22
% timerfd è stata tolta nel 2.6.23 e rifatta per bene nel 2.6.25
% LocalWords: openat readlinkat renameat symlinkat unlinkat utimensat utimes
% LocalWords: LinuxThread NTPL Library clockid evp timerid sigev notify high
% LocalWords: resolution CONFIG RES patch REALTIME MONOTONIC RAW NTP CPUTIME
+% LocalWords: tick calendar The Epoch list getcpuclockid capability CAP getres
+% LocalWords: ENOSYS pthread ENOENT NULL attribute itimerspec new old ABSTIME
+% LocalWords: epoch multiplexing
%%% Local Variables: