2010-04-28 9 views
36

¿Cómo convierto manualmente los jiffies 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.Conversión de jiffies a mili segundos

+1

¿Cuál es la función utilizada en kernel 2.6? –

+0

@kaciula Vea jiffies_to_msecs() en include/linux/jiffies.h – tonylo

Respuesta

37

Como se dijo en una respuesta anterior, la velocidad a la que se incrementa jiffies es fija.

La forma estándar de especificar el tiempo para una función que acepta jiffies es utilizando 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 recuento jiffies para una función es el uso de HZ, así:

schedule_timeout(HZ/10); /* Timeout after 1/10 second */ 

En los casos más 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 */ 

Los dos últimos tienen un poco de un problema, sin embargo, como en un sistema con un paso de temporizador de 10 ms, HZ/100 es 1, y la precisión comienza a sufrir. 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!

Por lo tanto, la regla de oro es, tenga mucho cuidado al usar HZ para valores pequeños (los que se acercan a 1 jiffie).

Convertir a la inversa, se debería utilizar:

jiffies/HZ   /* jiffies to seconds */ 
jiffies * 1000/HZ /* jiffies to milliseconds */ 

Usted no debe esperar nada mejor que una precisión de milisegundos.

+0

¿Es posible obtener el valor HZ usando CLI? P.ej. después de leer utime de/proc/[pid]/stat en kernel 2.6, ¿puedo convertirlo fácilmente en segundos sin necesidad de compilarlo desde el código C? –

+1

Si está interactuando con HZ desde el espacio de usuario, use USER_HZ en su lugar. 'man 7 time' dice que use sysconf (_SC_CLK_TCK) para obtener este valor. –

+1

No veo una manera obvia de hacer esto desde un script de shell, pero generalmente es una constante a menos que haya estado haciendo cosas antinaturales con su kernel. En x86, USER_HZ es 100. –

13

Los archivos Jiffies están codificados en Linux 2.4. Compruebe 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 llamados timespec_to_jiffiesjiffies_to_timespec y donde se puede convertir de ida y vuelta entre un 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: que comprueban esta información en la versión 2.4.22.

+0

^para recordarnos los jiffies codificados. – PypeBros

4

me encontré con este código de ejemplo en kernelnewbies. Asegúrese 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; 
} 
Cuestiones relacionadas