Учитывая, что jiffies
- это значение без знака, простое сравнение безопасно для одной точки обхода (где знаковые значения будут переходить с положительного на отрицательный), но не безопасно для другой точки (где знаковые значения будут переходить с отрицательного на положительное) и где значения без знака перепрыгивают с высокого на низкое). Это защита от этого второго пункта, который должен решить макрос.
Существует фундаментальное предположение, что timeout
первоначально рассчитывалось как jiffies + some_offset
в некоторый предшествующий недавний момент времени, в частности, менее половины диапазона переменных. Если вы пытаетесь измерить время дольше, чем это, то все пойдет не так, и вы получите неправильный ответ.
Если мы притворимся, что jiffies
имеет 16-битную ширину для удобства объяснения (аналогично другим ответам):
timeout > jiffies
Это сравнение без знака, которое предназначено для возврата true, если мы еще не достигли тайм-аута. Некоторые примеры:
timeout == 0x0300, jiffies == 0x0100
: результат верный, как и ожидалось.
timeout == 0x8100, jiffies == 0x7F00
: результат верный, как и ожидалось.
timeout == 0x0100, jiffies == 0xFF00
: упс, результат ложный, но мы на самом деле не достигли тайм-аута, он просто обернул счетчик.
timeout == 0x0100, jiffies == 0x0300
: результат ложный, как и ожидалось.
timeout == 0x7F00, jiffies == 0x8100
: результат ложный, как и ожидалось.
timeout == 0xFF00, jiffies == 0x0100
: упс, результат верен, но мы действительно передали тайм-аут.
time_before (jiffies, timeout)
Это делает сравнение со знаком разницы значений, а не самих значений, и снова ожидается, что вернет true, если время ожидания еще не достигнуто. При условии, что приведенное выше предположение подтверждается, те же примеры:
timeout == 0x0300, jiffies == 0x0100
: результат верный, как и ожидалось.
timeout == 0x8100, jiffies == 0x7F00
: результат верный, как и ожидалось.
timeout == 0x0100, jiffies == 0xFF00
: результат верный, как и ожидалось.
timeout == 0x0100, jiffies == 0x0300
: результат ложный, как и ожидалось.
timeout == 0x7F00, jiffies == 0x8100
: результат ложный, как и ожидалось.
timeout == 0xFF00, jiffies == 0x0100
: результат ложный, как и ожидалось.
Если смещение, которое вы использовали при расчете timeout
, слишком велико или вы пропустили слишком много времени после вычисления timeout
, то результат все равно может быть неправильным. например. если вы вычисляете timeout
один раз, но затем продолжаете тестировать его несколько раз, то time_before
первоначально будет истинным, затем изменится на ложное по истечении времени смещения - и затем снова вернется к истинному по истечении 0x8000 (хотя долго, это зависит от частоты тиков). Вот почему, когда вы достигаете тайм-аута, вы должны помнить об этом и перестать проверять время (или пересчитать новый тайм-аут).
В реальном ядре jiffies
длиннее 16 бит, поэтому его завертывание займет больше времени, но все же возможно, если машина будет работать достаточно долго. (И, как правило, он устанавливается для обертки вскоре после загрузки, чтобы быстрее обнаруживать эти ошибки.)