2010-04-28 11 views
36

Come convertire manualmente i jiffies in millisecondi e viceversa in Linux? So che il kernel 2.6 ha una funzione per questo, ma sto lavorando su 2.4 (compiti a casa) e sebbene abbia guardato il codice usa molte costanti macro che non ho idea se siano definite in 2.4.Conversione di jiffies in milli secondi

+1

Qual è la funzione utilizzata nel kernel 2.6? –

+0

@kaciula Vedi jiffies_to_msecs() in include/linux/jiffies.h – tonylo

risposta

37

Come una risposta precedente ha detto, la velocità con cui incrementi jiffies è fissa.

Il modo standard di specificare il tempo per una funzione che accetta jiffies utilizza la costante HZ.

Questa è l'abbreviazione di Hertz o il numero di tick al secondo. Su un sistema con un tick del timer impostato su 1ms, HZ = 1000. Alcune distribuzioni o architetture possono usare un altro numero (100 usato per essere comune).

Il metodo standard di specificare un conteggio jiffies per una funzione sta usando HZ, in questo modo:

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

Nei casi più semplici, questo funziona bene.

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 */ 

Questi ultimi due hanno un po 'un problema, tuttavia, come in un sistema con un timer tick 10 ms, HZ/100 è 1, e la precisione inizia a soffrire. È possibile che si verifichi un ritardo compreso tra 0,0001 e 1,999 tick (0-2 ms, in sostanza). Se hai provato a usare HZ/200 su un sistema di tick da 10 ms, la divisione in interi ti dà 0 jiffies!

Quindi la regola generale è, state molto attenti a usare HZ per valori piccoli (quelli che si avvicinano a 1 jiffie).

Per convertire l'altro modo, si usa:

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

Non si deve aspettare nulla di meglio di precisione micrometrica.

+0

È possibile ottenere il valore HZ utilizzando CLI? Per esempio. dopo aver letto utime da/proc/[pid]/stat sul kernel 2.6, posso convertirlo facilmente in secondi senza doverlo compilare dal codice C? –

+1

Se stai interagendo con HZ dallo spazio utente, usa invece USER_HZ. 'man 7 time' dice di usare sysconf (_SC_CLK_TCK) per recuperare questo valore. –

+1

Non vedo un modo ovvio di farlo da uno script di shell, ma è generalmente una costante a meno che non si stiano facendo cose innaturali al proprio kernel. Su x86 USER_HZ è 100. –

13

I jiffies sono codificati in Linux 2.4. Controllare la definizione di HZ, che è definita nell'architettura specifica param.h. Spesso è 100 Hz, ovvero un tick ogni (1 secondo/100 tick * 1000 ms/sec) 10 ms.

Ciò vale per i386 e HZ è definito in include/asm-i386/param.h.

Ci sono funzioni in include/linux/time.h chiamati timespec_to_jiffies e jiffies_to_timespec dove è possibile convertire avanti e indietro tra un struct timespec e 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: Ho controllato queste informazioni nella versione 2.4.22.

+0

^per ricordarci di jiffies hard-coded. – PypeBros

4

Ho trovato questo codice di esempio su kernelnewbies. Assicurati di collegarti 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; 
} 
Problemi correlati