\begin{funcproto}{
\fhead{unistd.h}
\fdecl{int nanosleep(const struct timespec *req, struct timespec *rem)}
-\fdesc{Pone il processo in pausa per un periodo di tempo.}
+\fdesc{Pone il processo in pausa per un intervallo di tempo.}
}
{La funzione ritorna $0$ se l'attesa viene completata e $-1$ per un errore,
occorrerà almeno attendere la successiva interruzione del timer di sistema,
cioè un tempo che a seconda dei casi può arrivare fino a 1/\const{HZ}, (sempre
che il sistema sia scarico ed il processa venga immediatamente rimesso in
-esecuzione); per questo motivo il valore restituito in \param{rem} è sempre
-arrotondato al multiplo successivo di 1/\const{HZ}.
+esecuzione). Per questo motivo il valore restituito in \param{rem} è sempre
+arrotondato al multiplo successivo di 1/\const{HZ}.
Con i kernel della serie 2.4 in realtà era possibile ottenere anche pause più
precise del centesimo di secondo usando politiche di \itindex{scheduler}
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à
+specifica per \param{timeout} 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
\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
+ sospensione in RAM o \textsl{ibernazione} su
disco. Questo orologio è specifico di Linux,
ed è disponibile a partire dal kernel
2.6.39.\\
\end{table}
-% Note: aggiungere le estensioni introdotte, verificandone il
-% funzionamento, vedi http://lwn.net/Articles/429595/
% NOTE: dal 2.6.39 anche CLOCK_BOOTTIME_ALARM e CLOCK_BOOTTIME
% NOTE: dal 3.0 anche i cosiddetti Posix Alarm Timers, con
% CLOCK_REALTIME_ALARM vedi http://lwn.net/Articles/429925/
Linux, create per rispondere ad alcune esigenze specifiche, come quella di
tener conto di eventuali periodi di sospensione del sistema, e presenti solo
nelle versioni più recenti del kernel. In particolare gli ultimi due,
-contraddistinti dal suffusso \texttt{\_ALARM}, hanno un impiego particolare,
+contraddistinti dal suffisso \texttt{\_ALARM}, hanno un impiego particolare,
derivato dalle esigenze emerse con Android per l'uso di Linux sui cellulari,
che consente di creare timer che possono scattare, riattivando il sistema,
anche quando questo è in sospensione. Per il loro utilizzo è prevista la
% TODO, dal 2.6.39 aggiunta clock_adjtime
-% TODO manca clock_nanosleep, referenziata in sez.~\ref{sec:sig_gen_beha}
Con l'introduzione degli orologi ad alta risoluzione è divenuto possibile
ottenere anche una gestione più avanzata degli allarmi; abbiamo già visto in
\begin{figure}[!htb]
\footnotesize \centering
- \begin{minipage}[c]{\textwidth}
+ \begin{minipage}[c]{0.8\textwidth}
\includestruct{listati/sigevent.h}
\end{minipage}
\normalsize
\begin{figure}[!htb]
\footnotesize \centering
- \begin{minipage}[c]{\textwidth}
+ \begin{minipage}[c]{0.8\textwidth}
\includestruct{listati/itimerspec.h}
\end{minipage}
\normalsize
per \param{flags} il valore \const{TIMER\_ABSTIME}, che al momento è l'unico
valore valido per \param{flags}, allora \var{it\_value} viene considerato come
un valore assoluto rispetto al valore usato dall'orologio a cui è associato il
-timer.\footnote{quindi a seconda dei casi lo si potrà indicare o come un tempo
- assoluto, quando si opera rispetto all'orologio di sistema (nel qual caso il
- valore deve essere in secondi e nanosecondi dalla \textit{epoch}) o come
- numero di secondi o nanosecondi rispetto alla partenza di un orologio di
- CPU, quando si opera su uno di questi.} Infine un valore nullo di
-\var{it\_value}, dover per nullo si intende con valori nulli per entrambi i
-campi \var{tv\_sec} e \var{tv\_nsec}, può essere utilizzato, indipendentemente
-dal tipo di orologio utilizzato, per disarmare l'allarme.
+timer.
+
+Quindi a seconda dei casi si potrà impostare un timer o con un tempo assoluto,
+quando si opera rispetto all'orologio di sistema (nel qual caso il valore deve
+essere in secondi e nanosecondi dalla \textit{epoch}) o con un numero di
+secondi o nanosecondi rispetto alla partenza di un orologio di CPU, quando si
+opera su uno di questi. Infine un valore nullo di \var{it\_value}, dove per
+nullo si intende con valori nulli per entrambi i campi \var{tv\_sec} e
+\var{tv\_nsec}, può essere utilizzato, indipendentemente dal tipo di orologio
+utilizzato, per disarmare l'allarme.
Il campo \var{it\_interval} di \struct{itimerspec} viene invece utilizzato per
impostare un allarme periodico. Se il suo valore è nullo, se cioè sono nulli
passate prima della ricezione della notifica dell'allarme.
É infatti possibile, qualunque sia il meccanismo di notifica scelto, che
-quest'ultima venga ricevuta dopo che il timer è scaduto più di una
-volta.\footnote{specialmente se si imposta un timer con una ripetizione a
- frequenza elevata.} Nel caso dell'uso di un segnale infatti il sistema mette
-in coda un solo segnale per timer,\footnote{questo indipendentemente che si
- tratti di un segnale ordinario o \textit{real-time}; per questi ultimi
- sarebbe anche possibile inviare un segnale per ogni scadenza, questo però
- non viene fatto per evitare il rischio, tutt'altro che remoto, di riempire
- la coda.} e se il sistema è sotto carico o se il segnale è bloccato, prima
-della sua ricezione può passare un intervallo di tempo sufficientemente lungo
-ad avere scadenze multiple, e lo stesso può accadere anche se si usa un
-\textit{thread} di notifica.
+quest'ultima venga ricevuta dopo che il timer è scaduto più di una volta,
+specialmente se si imposta un timer con una ripetizione a frequenza
+elevata. Nel caso dell'uso di un segnale infatti il sistema mette in coda un
+solo segnale per timer,\footnote{questo indipendentemente che si tratti di un
+ segnale ordinario o \textit{real-time}, per questi ultimi sarebbe anche
+ possibile inviare un segnale per ogni scadenza, questo però non viene fatto
+ per evitare il rischio, tutt'altro che remoto, di riempire la coda.} e se il
+sistema è sotto carico o se il segnale è bloccato, prima della sua ricezione
+può passare un intervallo di tempo sufficientemente lungo ad avere scadenze
+multiple, e lo stesso può accadere anche se si usa un \textit{thread} di
+notifica.
Per questo motivo il gestore del segnale o il \textit{thread} di notifica può
ottenere una indicazione di quante volte il timer è scaduto dall'invio della
tempo mancante ad una sua eventuale scadenza, si deve utilizzare la funzione
di sistema \funcd{timer\_gettime}, il cui prototipo è:
-
\begin{funcproto}{
\fhead{time.h}
\fdecl{int timer\_gettime(timer\_t timerid, int flags, struct
}
\end{funcproto}
-
La funzione restituisce nella struttura \struct{itimerspec} puntata
da \param{curr\_value} il tempo restante alla prossima scadenza nel campo
\var{it\_value}. Questo tempo viene sempre indicato in forma relativa, anche
un timer venga cancellato prima della ricezione del segnale pendente per la
notifica di una scadenza, il comportamento del sistema è indefinito.
+Infine a partire dal kernel 2.6 e per le versioni della \acr{libc} superiori
+alla 2.1, si può utilizzare la nuova interfaccia dei timer Posix anche per le
+funzioni di attesa, per questo è disponibile la funzione di sistema
+\funcd{clock\_nanosleep}, il cui prototipo è:
+
+\begin{funcproto}{
+\fhead{time.h}
+\fdecl{int clock\_nanosleep(clockid\_t clock\_id, int flags, const struct
+ timespec *request,\\
+\phantom{int clock\_nanosleep(}struct timespec *remain)}
+\fdesc{Pone il processo in pausa per un tempo specificato.}
+}
+
+{La funzione ritorna $0$ in caso di successo ed un valore positivo per un
+ errore, espresso dai 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 o indicato un orologio
+ non valido.
+ \end{errlist}
+ ed inoltre \errval{EFAULT} nel suo significato generico.}
+\end{funcproto}
+
+I due argomenti \param{request} e \param{remain} sono identici agli analoghi di
+\func{nanosleep} che abbiamo visto in sez.~\ref{sec:sig_pause_sleep}, ed hanno
+lo stesso significato. L'argomento \param{clock\_id} consente di indicare
+quale orologio si intende utilizzare per l'attesa con uno dei valori della
+prima parte di tab.~\ref{tab:sig_timer_clockid_types} (eccetto
+\const{CLOCK\_THREAD\_CPUTIME\_ID}). L'argomento \param{flags} consente di
+modificare il comportamento della funzione, il suo unico valore valido al
+momento è \const{TIMER\_ABSTIME} che, come per \func{timer\_settime} indica di
+considerare il tempo indicato in \param{request} come assoluto anziché
+relativo.
+
+Il comportamento della funzione è analogo a \func{nanosleep}, se la chiamata
+viene interrotta il tempo rimanente viene restituito in \param{remain}.
+Utilizzata normalmente con attese relative può soffrire degli stessi problemi
+di deriva di cui si è parlato in sez.~\ref{sec:sig_pause_sleep} dovuti ad
+interruzioni ripetute per via degli arrotondamenti fatti a questo tempo. Ma
+grazie alla possibilità di specificare tempi assoluti con \param{flags} si può
+ovviare a questo problema ricavando il tempo corrente con
+\func{clock\_gettime}, aggiungendovi l'intervallo di attesa, ed impostando
+questa come tempo assoluto.
+
+Si tenga presente che se si è usato il valore \const{TIMER\_ABSTIME}
+per \param{flags} e si è indicato un tempo assoluto che è già passato la
+funzione ritorna immediatamente senza nessuna sospensione. In caso di
+interruzione da parte di un segnale il tempo rimanente viene restituito
+in \param{remain} soltanto se questo non è un puntatore \val{NULL} e non si è
+specificato \const{TIMER\_ABSTIME} per \param{flags} .
+
+% TODO manca clock_nanosleep, referenziata in sez.~\ref{sec:sig_gen_beha}
+
\itindend{POSIX~Timer~API}
\begin{figure}[!htb]
\footnotesize \centering
- \begin{minipage}[c]{\textwidth}
+ \begin{minipage}[c]{0.8\textwidth}
\includestruct{listati/stack_t.h}
\end{minipage}
\normalsize
Abbiamo visto in fig.~\ref{fig:sig_sleep_incomplete} come si possa usare
\func{longjmp} per uscire da un gestore rientrando direttamente nel corpo
-del programma; sappiamo però che nell'esecuzione di un gestore il segnale
+del programma, sappiamo però che nell'esecuzione di un gestore il segnale
che l'ha invocato viene bloccato, e abbiamo detto che possiamo ulteriormente
modificarlo con \func{sigprocmask}.
Resta quindi il problema di cosa succede alla maschera dei segnali quando si
esce da un gestore usando questa funzione. Il comportamento dipende
-dall'implementazione; in particolare la semantica usata da BSD prevede che sia
+dall'implementazione. In particolare la semantica usata da BSD prevede che sia
ripristinata la maschera dei segnali precedente l'invocazione, come per un
normale ritorno, mentre quella usata da System V no.
sez.~\ref{sec:intro_gcc_glibc_std}.
Lo standard POSIX però prevede anche la presenza di altre due funzioni
-\funcd{sigsetjmp} e \funcd{siglongjmp}, che permettono di decidere quale dei
-due comportamenti il programma deve assumere; i loro prototipi sono:
-\begin{functions}
- \headdecl{setjmp.h}
-
- \funcdecl{int sigsetjmp(sigjmp\_buf env, int savesigs)} Salva il contesto
- dello \textit{stack} per un \index{salto~non-locale} salto non-locale.
-
- \funcdecl{void siglongjmp(sigjmp\_buf env, int val)} Esegue un salto
- non-locale su un precedente contesto.
+\funcd{sigsetjmp} e \funcd{siglongjmp}, che permettono di decidere in maniera
+esplicita quale dei due comportamenti il programma deve assumere; i loro
+prototipi sono:
+
+\begin{funcproto}{
+\fhead{setjmp.h}
+\fdecl{int sigsetjmp(sigjmp\_buf env, int savesigs)}
+\fdesc{Salva il contesto dello \textit{stack} e la maschera dei segnali.}
+\fdecl{void siglongjmp(sigjmp\_buf env, int val)}
+\fdesc{Ripristina il contesto dello \textit{stack} e la maschera dei segnali.}
+}
- \bodydesc{Le due funzioni sono identiche alle analoghe \func{setjmp} e
- \func{longjmp} di sez.~\ref{sec:proc_longjmp}, ma consentono di specificare
- il comportamento sul ripristino o meno della maschera dei segnali.}
-\end{functions}
+{La funzioni sono identiche alle analoghe \func{setjmp} e \func{longjmp} di
+ sez.~\ref{sec:proc_longjmp} ed hanno gli stessi errori e valori di uscita.}
+\end{funcproto}
Le due funzioni prendono come primo argomento la variabile su cui viene
salvato il contesto dello \itindex{stack} \textit{stack} per permettere il
\index{salto~non-locale} salto non-locale; nel caso specifico essa è di tipo
\type{sigjmp\_buf}, e non \type{jmp\_buf} come per le analoghe di
sez.~\ref{sec:proc_longjmp} in quanto in questo caso viene salvata anche la
-maschera dei segnali.
+maschera dei segnali.
Nel caso di \func{sigsetjmp}, se si specifica un valore di \param{savesigs}
-diverso da zero la maschera dei valori sarà salvata in \param{env} e
-ripristinata in un successivo \func{siglongjmp}; quest'ultima funzione, a
-parte l'uso di \type{sigjmp\_buf} per \param{env}, è assolutamente identica a
+diverso da zero la maschera dei valori verrà salvata in \param{env} insieme al
+contesto dello \itindex{stack} \textit{stack} usato per il salto non
+locale. Se così si è fatto la maschera dei segnali verrà ripristinata in una
+successiva chiamata a \func{siglongjmp}. Quest'ultima, a parte l'uso di un
+valore di \param{env} di tipo \type{sigjmp\_buf}, è assolutamente identica a
\func{longjmp}.
% 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
+% LocalWords: pwait msgrcv msgsnd semop semtimedop runnable sigisemptyset HRT
+% LocalWords: sigorset sigandset BOOTTIME Android request remain
%%% Local Variables:
%%% mode: latex
%%% TeX-master: "gapil"
%%% End:
-% LocalWords: sigorset sigandset