#define \
time_before_eq(unknown, known) ((long)(known) - (long) (unknown) >= 0)
Параметр unknown
jiffies, а параметр known — значение, с которым его необходимо сравнить.Макрос time_after(unknown, known)
true, если момент времени unknown происходит после момента времени known, в противном случае возвращается значение false. Макрос time_before(unknown, known) возвращает значение true, если момент времени unknown происходит раньше, чем момент времени known, в противном случае возвращается значение false. Последние два макроса работают аналогично первым двум, за исключением того, что возвращается значение "истинно", если оба параметра равны друг другу.Версия кода из предыдущего примера, которая предотвращает ошибки, связанные с переполнением, будет выглядеть следующим образом.
unsigned long timeout = jiffies + HZ/2; /* значение лимита времени
равно 0.5 с */
/* выполним некоторые действия и проверим, не слишком ли это много
заняло времени ... */
if (time_after(jiffies, timeout}) {
/* мы превысили лимит времени — это ошибка ... */
} else {
/* мы не превысили лимит времени — это хорошо ... */
}
Если любопытно, каким образом эти макросы предотвращают ошибки, связанные с переполнением, то попробуйте подставить различные значения параметров. А затем представьте, что один из параметров переполнился, и посмотрите, что при этом произойдет.
Пространство пользователя и параметр HZ
Раньше изменение параметра НZ
Чтобы исправить это, код ядра должен нормировать все значения переменной jiffies
USER_HZ, равной значению параметра HZ, которое HZ исторически равно 100, то значение константы USER_HZ=100. Макрос jiffies_to_clock_t() используется для нормировки значения счетчика импульсов системного таймера, выраженного в единицах HZ, в значение счетчика импульсов, выраженное в единицах USER_HZ. Используемый макрос зависит от того, кратны ли значения параметров HZ и USER_HZ один другому. Если кратны, то этот макрос имеет следующий очень простой вид.#define jiffies_to_clock_t(x) ((x) / (HZ / USER_HZ))
Если не кратны, то используется более сложный алгоритм.
Функция jiffies_64_to_clock_t()
jiffies из единиц HZ в единицы USER_HZ.Эти функции используются везде, где значения данных, выраженных в единицах числа импульсов системного таймера в секунду, должны экспортироваться в пространство пользователя, как в следующем примере.
unsigned long start = jiffies;
unsigned long total_time;
/* выполнить некоторую работу ... */
total_time = jiffies - start;
printk("Это заняло %lu импульсов таймера\n",
jiffies_to_clock_t(total_time));
В пространстве пользователя передаваемое значение должно быть таким, каким оно было бы, если бы выполнялось равенство HZ=USER_HZ
printk("Это заняло %lu секунд\n", total time / HZ);