web-dev-qa-db-fra.com

Conversion de jiffies en millisecondes

Comment convertir manuellement des jiffies en millisecondes et vice versa sous Linux? Je sais que le noyau 2.6 a une fonction pour cela, mais je travaille sur 2.4 (devoirs) et bien que j'aie regardé le code, il utilise beaucoup de constantes macro que je n'ai aucune idée si elles sont définies en 2.4.

43
EpsilonVector

Comme une réponse précédente l'a dit, le taux auquel jiffies incréments est fixe.

La manière standard de spécifier l'heure pour une fonction qui accepte jiffies utilise la constante HZ.

C'est l'abréviation de Hertz, ou le nombre de ticks par seconde. Sur un système avec une minuterie réglée sur 1 ms, HZ = 1000. Certaines distributions ou architectures peuvent utiliser un autre nombre (100 était commun).

La manière standard de spécifier un nombre jiffies pour une fonction utilise HZ, comme ceci:

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

Dans la plupart des cas simples, cela fonctionne 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 */

Ces deux derniers ont un peu de problème, cependant, comme sur un système avec une minuterie de 10 ms, HZ/100 est 1 et la précision commence à souffrir. Vous pouvez obtenir un retard n'importe où entre 0,0001 et 1,999 ticks de minuterie (0-2 ms, essentiellement). Si vous avez essayé d'utiliser HZ/200 sur un système de ticks de 10 ms, la division entière vous donne 0 jiffies!

Donc, la règle de base est, soyez très prudent en utilisant HZ pour les petites valeurs (celles qui approchent de 1 jiffie).

Pour convertir dans l'autre sens, vous utiliseriez:

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

Vous ne devriez pas vous attendre à mieux que la précision en millisecondes.

45
Eric Seppanen

Les fichiers Jiffies sont codés en dur sous Linux 2.4. Vérifiez la définition de HZ, qui est définie dans la structure spécifique à l'architecture param.h. Il s'agit souvent de 100 Hz, ce qui correspond à un tick toutes les (1 sec/100 ticks * 1000 ms/sec) 10 ms.

Cela est vrai pour i386 et HZ est défini dans include/asm-i386/param.h.

Il y a des fonctions dans include/linux/time.h appelé timespec_to_jiffies et jiffies_to_timespec où vous pouvez effectuer des conversions entre _ struct timespec et 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;
    }

Note: J'ai vérifié ces informations dans la version 2.4.22.

14
indiv

J'ai trouvé cet exemple de code sur kernelnewbies . Assurez-vous de créer un lien avec -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;
 }
5
Anthony Giorgio

Pour obtenir la valeur USER_HZ (voir les commentaires sous la réponse acceptée) à l'aide de CLI:

getconf CLK_TCK
1
P. Cahyna