Преобразование jiffies в миллисекунды - PullRequest
43 голосов
/ 28 апреля 2010

Как вручную преобразовать jiffies в миллисекунды и наоборот в Linux? Я знаю, что в ядре 2.6 есть функция для этого, но я работаю над 2.4 (домашняя работа), и хотя я посмотрел на код, он использует множество макроконстант, которые я понятия не имею, определены ли они в 2.4.

Ответы [ 4 ]

45 голосов
/ 29 апреля 2010

Как и в предыдущем ответе, фиксированная скорость увеличения jiffies.

Стандартный способ задания времени для функции, которая принимает jiffies, использует константу HZ.

Это аббревиатура для Герц, или число тиков в секунду. В системе с таймером таймера, установленным на 1 мс, HZ = 1000. В некоторых дистрибутивах или архитектурах может использоваться другой номер (обычно 100).

Стандартный способ задания количества jiffies для функции - это использование HZ, например:

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

В большинстве простых случаев это работает нормально.

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

Однако у последних двух есть небольшая проблема, поскольку в системе с тиковым таймером 10 мс, HZ/100 равен 1, и точность начинает снижаться. Вы можете получить задержку в диапазоне от 0,0001 до 1,999 таймера (по существу, 0-2 мс). Если вы попытались использовать HZ/200 в системе тиков 10 мсек, целочисленное деление даст вам 0 jiffies!

Так что эмпирическое правило: будьте очень осторожны, используя HZ для крошечных значений (те, которые приближаются к 1 jiffie).

Чтобы конвертировать другим способом, вы должны использовать:

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

Вы не должны ожидать ничего лучше, чем точность в миллисекундах.

14 голосов
/ 28 апреля 2010

Jiffies жестко запрограммированы в Linux 2.4. Проверьте определение HZ, которое определено в архитектуре param.h. Часто это 100 Гц, что составляет один такт каждый (1 сек / 100 тактов * 1000 мс / сек) 10 мс.

Это верно для i386, а HZ определено в include/asm-i386/param.h.

В include/linux/time.h есть функции, называемые timespec_to_jiffies и jiffies_to_timespec, где вы можете конвертировать между struct timespec и 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;
    }

Примечание: Я проверил эту информацию в версии 2.4.22.

5 голосов
/ 29 января 2013

Я нашел этот пример кода на kernelnewbies . Убедитесь, что вы связались с -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;
 }
1 голос
/ 10 апреля 2018

Чтобы получить значение USER_HZ (см. Комментарии под принятым ответом) с помощью CLI:

getconf CLK_TCK
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...