Как вручную конвертировать jiffies в миллисекунды и наоборот в Linux? Я знаю, что у ядра 2.6 есть функция для этого, но я работаю над 2.4 (домашнее задание), и хотя я смотрел на код, он использует множество макроконстантов, о которых я понятия не имею, если они определены в 2.4.
Преобразование jiffies в миллисекунды
Ответ 1
Как было сказано в предыдущем ответе, скорость, с которой приращения jiffies
фиксированы.
Стандартный способ указания времени для функции, принимающей jiffies
, использует константу HZ
.
Это аббревиатура для Hertz или количество тиков в секунду. В системе с таймером, установленным в 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 */
Вы не должны ожидать ничего лучше, чем миллисекундная точность.
Ответ 2
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.
Ответ 3
Я нашел этот пример кода на 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;
}
Ответ 4
Ответ на # 3875801 также может быть отменен