Hai ragione a non aspettarti che i timer si attivino presto, e non lo fanno. L'apparente l'attivazione anticipata è dovuta al fatto che non stai misurando il tempo dalla scadenza del timer precedente:stai misurando il tempo dal precedente gettimeofday()
chiamata. Se c'è stato un ritardo tra la scadenza del timer e l'effettiva pianificazione del processo, vedrai questo gettimeofday()
in ritardo, e il successivo in anticipo dello stesso importo .
Invece di registrare la differenza tra i successivi gettimeofday()
chiamate, prova a registrare i tempi assoluti restituiti, quindi confronta i tempi restituiti con N * 100 ms dopo il tempo iniziale.
Se vuoi PREEMPT_RT
per aiutarti, dovrai impostare una politica di pianificazione in tempo reale per il tuo programma di test (SCHED_FIFO
o SCHED_RR
), che richiede root.
Ho apportato alcune modifiche al tuo codice e principalmente ho sostituito il timer
come segue ed eseguire il processo come progresso RT (SCHED_FIFO).
setitimer() -> timer_create()/timer_settime()
gettimeofday() -> clock_gettime()
il mio banco di prova è CPU i9-9900k e Linux con patch PREEMPT-RT con kernel 5.0.21. L'intervallo di tempo del timer è di 1 ms e il programma esegue circa 10 ore per generare il seguente risultato.
Eseguo anche Cyclictest
(basato su nanosleep()
) sulla mia macchina e mostra un migliore controllo della latenza (latenza massima inferiore a 15us). Quindi, secondo me, se vuoi realizzare da solo un timer ad alta risoluzione, potrebbe essere utile un thread RT autonomo che esegue nanosleep su un core isolato. Sono nuovo nel sistema RT, i commenti sono i benvenuti.