2011-01-17 11 views
2

Jiffies Counter gibt eine vorzeichenlose Ganzzahl der Größe vier Bytes zurück. Wenn der Zähler den Maximalwert erreicht, startet er erneut von 0 aus. Ich subtrahiere den letzten Wert mit dem alten Wert, um die Dauer zu erhalten. Also, wie sollte ich für einen Fall so denken, dass, wenn der alte Wert von maximalem Wert ist und neuer Wert mehr als Null ist, so dass ich eine falsche Dauer bekomme?Jiffies Counter Over Flow + Linux

Antwort

7

Sie müssen nichts tun, Sie haben die richtige Dauer (solange Sie alle Berechnungen mit vier Bytes vorzeichenlosen Ganzzahlen durchführen). Das ist die Magie von Integer-Werten, die als binäre Arithmetik mit fester Breite implementiert sind.

Hier ist ein Beispiel mit 8 Bits unsigned Ganzzahlen. Sie können sogar sehen, dass der Unterschied auch dann noch gültig ist, wenn ein Überlauf vorliegt.

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 
    ... 

Ihr einziges Problem kommt, wenn die Dauer auf den Maximalwert des Zählers nicht kleine verglichen wird, das heißt, wenn sie größer als die Hälfte des Maximalwertes sein können.

+0

Hi.Thanks für die Antwort.Konsult, dass ich zwei Variablen wie folgt haben: old_time, new_time.In einer kontinuierlichen while-Schleife werde ich wie "if ((new_time-old_time) == 15)", also 15 Sekunden, überwachen. Aber wenn ein Überlauf passiert, verpasse ich diese bestimmte Dauer. Gibt es einen Fall, um dieses Szenario zu behandeln? – Joy

+0

Nein, du wirst es nicht VERPASSEN, das ist der Punkt meiner Antwort: Selbst im Falle eines Überlaufs wird das Ergebnis von "new_time-old_time" 15 sein. –

0

Dieser Hinweis ist nur korrekt, wenn Ihre beiden Ereignisse a und b, a tatsächlich vor b aufgetreten sind und der Abstand zwischen ihnen kleiner als 2^(32-1) ist. Wenn Sie (b-a) berechnen, erhalten Sie die richtige Antwort. Wenn Sie den kleineren vorzeichenlosen Wert von dem größeren unsignierten Wert subtrahieren (denken Sie, dass sie ihre Zeitordnung definiert), dann können Sie das Negativ der gewünschten Antwort erhalten.

Also müssen Sie auch eine neue zirkuläre Vergleichsoperation berücksichtigen (siehe Linux time_after, time_before und sie verwenden, usw.).

Sowohl signierte als auch vorzeichenlose Vergleiche wären falsch, weil Counter, die umbrechen, nicht genau das Gleiche sind wie vorzeichenbehaftete oder vorzeichenlose Nummern. Betrachten 8-Bit-Fall:

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 

Der Hauptunterschied zwischen den mit und ohne Vorzeichen-Werte mit der gleichen Anzahl von Bits sind die Implementierungen der Vergleichsoperatoren. Signed versus unsigned ist signifikant bei der Zuweisung zu einem Wert mit mehr Bits wegen der Entscheidung zu unterschreiben, verlängern Sie negative Werte mit 1s oder 0s.

eine neue Definition von weniger als Betrachten für Zahlen ausgelegt, die um Einschlag:

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

Dieser Vergleich funktioniert so lange, wie der tatsächliche Abstand zwischen dem ersten und dem zweiten Wert ist immer kleiner als 2^(32-1).

Stellen Sie sich einen Kreis mit 256 Positionen vor und die Zähler a und b im Uhrzeigersinn. Wenn a b mit weniger als 2^(8-1) Schritten erreichen kann, dann "a < b". Es ist ein Vergleich, der berücksichtigt Einwickeln, und es ist weder unterzeichnet noch unsigned:

#define LT_CIRCULAR_LONG(a,b) ((((long)(b)-(long)(a)) < 0)==0) 

Deshalb ist time_after so aussieht, dass es funktioniert. Die Abgüsse von b und a separat stellen sicher, dass das Zeichen sich ausdehnt. Einen Wert zu signieren und auf weniger als Null zu prüfen, ist ein Trick, um das hohe Bit zu testen.

Ich beobachte einen Kollegen Entwickler befassen sich mit diesem Problem mit Jiffies im Augenblick (dh: -300 Jiffies), und habe es mit TCP-Sequenznummern und ein paar andere ähnliche Zähler gesehen. Also, 2s Kompliment zu sein, behandelt nicht alles.