Intente modificarlo de la siguiente manera, esto debería suponer que nunca va a perder una activación, pero tenga cuidado con ella, ya que ejecutar la prioridad en tiempo real puede bloquear su máquina si no se detiene, también es posible que necesite preparar las cosas para que su usuario tiene la capacidad de ejecutar cosas en prioridad de tiempo real (ver /etc/security/limits.conf
)
#include <sys/timerfd.h>
#include <time.h>
#include <string.h>
#include <stdint.h>
#include <stdio.h>
#include <sched.h>
int main(int argc, char *argv[])
{
int timerfd = timerfd_create(CLOCK_MONOTONIC,0);
int milliseconds = atoi(argv[1]);
struct itimerspec timspec;
struct sched_param schedparm;
memset(&schedparm, 0, sizeof(schedparm));
schedparm.sched_priority = 1; // lowest rt priority
sched_setscheduler(0, SCHED_FIFO, &schedparm);
bzero(&timspec, sizeof(timspec));
timspec.it_interval.tv_sec = 0;
timspec.it_interval.tv_nsec = milliseconds * 1000000;
timspec.it_value.tv_sec = 0;
timspec.it_value.tv_nsec = 1;
int res = timerfd_settime(timerfd, 0, &timspec, 0);
if(res < 0){
perror("timerfd_settime:");
}
uint64_t expirations = 0;
int iterations = 0;
while(res = read(timerfd, &expirations, sizeof(expirations))){
if(res < 0){ perror("read:"); continue; }
if(expirations > 1){
printf("%ld expirations, %d iterations\n", expirations, iterations);
break;
}
iterations++;
}
}
Si está utilizando hilos se debe utilizar en lugar de pthread_setschedparam
sched_setscheduler
.
En tiempo real también no se trata de latencia baja, se trata de garantías, RT significa que si desea despertar exactamente una vez por segundo en el segundo, usted, la programación normal no le da esto, podría decidir te despertaría 100ms más tarde, porque de todos modos tenía otro trabajo que hacer en ese momento. Si quiere despertarse cada 10ms y REALMENTE lo necesita, entonces debe configurarlo para ejecutarlo como una tarea en tiempo real, entonces el núcleo lo despertará cada 10ms sin falta.A menos que una tarea en tiempo real de mayor prioridad esté ocupada haciendo cosas.
Si necesita garantizar que su intervalo de activación es exactamente cierto tiempo, no importa si es 1ms o 1 segundo, no lo obtendrá a menos que ejecute como una tarea en tiempo real. Hay buenas razones para que el kernel le haga esto (el poder de ahorro es uno de ellos, el mayor rendimiento es otro, hay otros), pero está en su derecho hacerlo ya que nunca dijo que necesita mejores garantías. La mayoría de las cosas en realidad no tienen que ser tan precisas, o no deben perderse nunca, por lo que debes pensar detenidamente si realmente las necesitas o no.
citando http://www.ganssle.com/articles/realtime.htm
Una tarea en tiempo real duro o el sistema es uno donde una actividad simplemente debe ser completado - siempre - por un plazo especificado. La fecha límite puede ser en un intervalo de tiempo o tiempo particular, o puede ser la llegada de algún evento. Duro tareas en tiempo real fallan, por definición, si se pierden dicho plazo.
Tenga en cuenta esta definición no hace suposiciones sobre la frecuencia o período de las tareas. Un microsegundo o por semana - si falta la fecha límite induce un fallo, entonces la tarea tiene requisitos de tiempo real.
tiempo real blando es más o menos la misma, excepto que no cumplir un plazo, mientras no deseable, no es el fin del mundo (por ejemplo, vídeo y reproducción de audio en tiempo real son tareas suaves, que no quiere perder la visualización un marco, o se queda sin buffer, pero si lo haces es solo un momento momentáneo, y simplemente continúas). Si lo que estás tratando de hacer es 'suave' en tiempo real, no me molestaría en ejecutar en tiempo real la prioridad, ya que generalmente debes tener tus despertadores a tiempo (o al menos cerca de eso).
EDIT:
Si no se está ejecutando en tiempo real el kernel por defecto dar ningún temporizador que realice algún 'holgura' para que se pueda fusionar su solicitud para despertar con otros eventos que suceden en momentos cercanos a el que usted solicitó (es decir, si el otro evento está dentro de su 'tiempo de inactividad' no lo despertará en el momento en que lo solicitó, pero un poco antes o después, al mismo tiempo ya iba a hacer otra cosa, esto ahorra energía).
Por un poco más información ver High- (but not too high-) resolution timeouts y Timer slack (tenga en cuenta que no estoy seguro si cualquiera de esas cosas es exactamente lo que realmente está en el núcleo, ya que ambos esos artículos son sobre las discusiones de listas de correo lkml, sino algo así como la primera realidad está en el kernel
Mis datos sobre la zona son bastante oxidados. Suena que quieres hacer algo en tiempo real. Verifique Linuxes en tiempo real. De lo contrario, el programador utiliza granularidades más largas para evitar una sobrecarga superior. Es posible que desee ejecutar su proceso como RT (en tiempo real) uno ('man sched_setparam') y probablemente en la raíz. Para procesos normales (por ejemplo, juegos o multimedia), usted (1) espera en circuito cerrado o (2) en cada evento de temporizador calcule el error (esperado frente a tiempo de activación real) y lo incorpora a la cuenta cuando avanza el tiempo interno estado dependiente. – Dummy00001
Gracias por la sugerencia, pero no considero intervalos de 20 milisegundos como parte del dominio en tiempo real. Quiero decir, un sistema estándar al que se le pide que espere 10 milisegundos nunca debe esperar 21 milisegundos, la RT suena demasiado para eso. –
puede intentar configurar su programa para que se ejecute con prioridad en tiempo real, probablemente no necesite usar el kernel de RT Linux. La línea principal es bastante buena en tiempo real en estos días, y dado que nunca se perdió más de una expiración simplemente ejecutándose con prioridad RT debería ser suficiente para que nunca se pierda uno – Spudd86