Случай Jiffies Counter Over Flow + Linux - PullRequest
       8

Случай Jiffies Counter Over Flow + Linux

2 голосов
/ 17 января 2011

Счетчик Jiffies возвращает целое число без знака размером четыре байта. когда счетчик достигает максимального значения, он снова перезапускается с 0. Я вычту последнее значение со старым значением, чтобы получить продолжительность. Так, как я должен рассмотреть для случая, когда старое значение имеет максимальное значение, а новое значение больше нуля, так что я получу неправильную длительность?

Ответы [ 2 ]

6 голосов
/ 17 января 2011

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

Вот пример с 8-битными целыми числами без знака. Вы можете видеть, что даже при переполнении разница остается в силе.

236 - 221 = 11101100 - 11011101 = 11101100 + 00100011 = 00001111 = 15
251 - 236 = 11111011 - 11101100 = 11111011 + 00010100 = 00001111 = 15
 10 - 251 = 00001010 - 11111011 = 00001010 + 00000101 = 00001111 = 15
 25 -  10 = 00011001 - 00001010 = 00011001 + 11110110 = 00001111 = 15
   ...

Ваша единственная проблема возникает, когда длительность не мала по сравнению с максимальным значением счетчика, т.е. когда она может быть больше половины максимального значения.

0 голосов
/ 11 февраля 2015

Этот совет верен только в том случае, если ваши два события a и b, a действительно произошли до b, а расстояние между ними меньше 2 ^ (32-1). Если вы рассчитаете (б-а), то вы получите правильный ответ. Если вы вычтите меньшее беззнаковое значение из большего беззнакового (думая, что определяет порядок их времени), то вы можете получить отрицательный ответ на ваш вопрос.

Итак, вам необходимо учесть новую операцию циклического сравнения (см. Linux time_after, time_before и используйте их и т. Д.).

Сравнение как со знаком, так и со знаком без знака было бы неправильным, потому что счетчики, которые оборачиваются, не совсем то же самое, что числа со знаком или без знака. Рассмотрим 8-битный случай:

a=250, b=20   #8-bit sequence number a was created before b
a=120, b=130  #8-bit sequence number a was created before b

Основным различием между знаковыми и беззнаковыми значениями с одинаковым количеством битов являются реализации операторов сравнения. Подписанный и неподписанный имеет значение при присвоении значения с большим количеством битов, поскольку решение подписать расширение отрицательных значений с 1 или 0.

Рассмотрим новое определение меньше, чем предназначенное для чисел, которые охватывают:

LT_CIRCULAR_32(250,5)     == True   //like signed?   
LT_CIRCULAR_32(0,11)      == True
LT_CIRCULAR_32(127,138)   == True   //like unsigned?

Это сравнение работает до тех пор, пока фактическое расстояние между первым и вторым значением всегда меньше 2 ^ (32-1).

Представьте себе круг с 256 позициями на нем и счетчиками a и b, движущимися по часовой стрелке. Если a может достичь b с шагом менее 2 ^ (8-1), тогда "a #define LT_CIRCULAR_LONG(a,b) ((((long)(b)-(long)(a)) < 0)==0) Вот почему time_after выглядит так, как оно. Приведения b и a по отдельности гарантируют, что знаки расширяются. Создание значения со знаком и проверка на значение меньше нуля - хитрость для проверки старшего бита.

Я наблюдаю, как один из разработчиков сейчас решает эту проблему с jiffies (то есть: -300 jiffies), и видел ее с порядковыми номерами TCP и несколькими другими аналогичными счетчиками. Таким образом, комплимент 2s не справляется со всем этим.

...