linux - ultima - Convirtiendo jiffies en mili segundos
ultima version de linux (4)
¿Cómo convierto jiffies manualmente a milisegundos y viceversa en Linux? Sé que kernel 2.6 tiene una función para esto, pero estoy trabajando en 2.4 (tarea) y aunque miré el código, usa muchas macro constantes que no tengo idea si están definidas en 2.4.
Como dijo una respuesta anterior, la tasa a la que se incrementa el jiffies
es fija.
La forma estándar de especificar el tiempo para una función que acepta jiffies
es usar la constante HZ
.
Esa es la abreviatura de Hertz, o la cantidad de tics por segundo. En un sistema con una marca de temporizador establecida en 1 ms, HZ = 1000. Algunas distribuciones o arquitecturas pueden usar otro número (100 solía ser común).
La forma estándar de especificar un conteo de jiffies
para una función es usando HZ
, así:
schedule_timeout(HZ / 10); /* Timeout after 1/10 second */
En la mayoría de los casos simples, esto funciona bien.
2*HZ /* 2 seconds in jiffies */
HZ /* 1 second in jiffies */
foo * HZ /* foo seconds in jiffies */
HZ/10 /* 100 milliseconds in jiffies */
HZ/100 /* 10 milliseconds in jiffies */
bar*HZ/1000 /* bar milliseconds in jiffies */
Sin embargo, esos dos últimos tienen un pequeño problema, ya que en un sistema con un tic del temporizador de 10 ms, HZ/100
es 1, y la precisión comienza a deteriorarse. Puede obtener un retraso en cualquier punto entre 0,0001 y 1,999 tics del temporizador (0-2 ms, esencialmente). ¡Si trataste de usar HZ/200
en un sistema de tics de 10ms, la división entera te da 0 jiffies!
Entonces, la regla general es, tener mucho cuidado al usar HZ para valores pequeños (los que se acercan a 1 jiffie).
Para convertir de la otra manera, usaría:
jiffies / HZ /* jiffies to seconds */
jiffies * 1000 / HZ /* jiffies to milliseconds */
No debe esperar nada mejor que la precisión de milisegundos.
Los Jiffies están codificados en Linux 2.4. Verifique la definición de HZ
, que se define en el param.h
específico de la arquitectura. A menudo es 100 Hz, que es una marca cada (1 seg / 100 tics * 1000 ms / seg) 10 ms.
Esto es válido para i386, y HZ se define en include/asm-i386/param.h
.
Hay funciones en include/linux/time.h
llamadas timespec_to_jiffies
y jiffies_to_timespec
donde se puede convertir de ida y vuelta entre struct timespec
y jiffies
:
#define MAX_JIFFY_OFFSET ((~0UL >> 1)-1)
static __inline__ unsigned long
timespec_to_jiffies(struct timespec *value)
{
unsigned long sec = value->tv_sec;
long nsec = value->tv_nsec;
if (sec >= (MAX_JIFFY_OFFSET / HZ))
return MAX_JIFFY_OFFSET;
nsec += 1000000000L / HZ - 1;
nsec /= 1000000000L / HZ;
return HZ * sec + nsec;
}
static __inline__ void
jiffies_to_timespec(unsigned long jiffies, struct timespec *value)
{
value->tv_nsec = (jiffies % HZ) * (1000000000L / HZ);
value->tv_sec = jiffies / HZ;
}
Nota: Revisé esta información en la versión 2.4.22.
Encontré este código de muestra en kernelnewbies . Asegúrate de vincular con -lrt
#include <unistd.h>
#include <time.h>
#include <stdio.h>
int main()
{
struct timespec res;
double resolution;
printf("UserHZ %ld/n", sysconf(_SC_CLK_TCK));
clock_getres(CLOCK_REALTIME, &res);
resolution = res.tv_sec + (((double)res.tv_nsec)/1.0e9);
printf("SystemHZ %ld/n", (unsigned long)(1/resolution + 0.5));
return 0;
}
La respuesta al # 3875801 también puede ser reveladora