Die aktuelle Zeit ermitteln

Kernel-Code kann immer auf die aktuelle Uhrzeit zugreifen, indem der Wert von jiffies ausgelesen wird. Die Tatsache, daß dieser Wert nur die Zeit seit dem letzten Booten angibt, ist normalerweise für den Treiber nicht relevant, weil er ohnehin nur so lange existiert, wie auch das System hochgefahren ist. Treiber können den aktuellen Wert von jiffies verwenden, um die Intervalle zwischen Ereignissen zu berechnen (um beispielsweise einfache Klicks von Doppelklicks in Maus-Gerätetreibern zu unterscheiden). jiffies ist also kurz gesagt fast immer ausreichend, wenn Sie Intervalle messen müssen; und wenn Sie sehr genaue Messungen für kurze Intervalle benötigen, können Sie immer noch prozessorspezifische Register verwenden.

Es ist unwahrscheinlich, daß ein Treiber jemals die aktuelle Uhrzeit wissen muß; das interessiert normalerweise nur Benutzerprogramme wie cron und at. Wenn so eine Fähigkeit benötigt wird, dann handelt es sich um eine sehr treiberspezifische Sache. In diesem Fall kann der Treiber die Uhrzeit problemlos von einem Benutzerprogramm bekommen, das die Konvertierung von der realen Uhrzeit in die Systemzeit leicht durchführen kann. Die direkte Verwendung der Uhrzeit in einem Treiber ist oft ein Zeichen dafür, daß eine Policy implementiert wird und Sie daher noch einmal einen genauen Blick darauf werfen sollten.

Wenn Ihr Treiber wirklich die aktuelle Uhrzeit wissen muß, dann kommt Ihnen die Funktion do_gettimeofday zu Hilfe. Die Funktion gibt nicht etwa den aktuellen Tag in der Woche oder etwas ähnliches zurück, sondern füllt statt dessen einen Zeiger auf eine struct timeval — genau wie der Systemaufruf gettimeofday — mit den üblichen Sekunden- und Mikrosekunden-Werten. Der Prototyp sieht folgendermaßen aus:



#include <linux/time.h>
void do_gettimeofday(struct timeval *tv);

In den Quellen steht, daß do_gettimeofday eine Auflösung “im Bereich von Mikrosekunden” auf vielen Architekturen hat. Die Präzision variiert aber von Architektur zu Architektur und kann in älteren Kerneln kleiner sein. Mit geringerer Präzision ist die aktuelle Zeit auch aus der Variablen xtime erhältlich (Typ struct timeval); es wird jedoch davon abgeraten, diesen Wert zu benutzen, weil Sie nicht atomar auf die timeval-Felder tv_sec und tv_usec zugreifen können, es sei denn, Sie schalten die Interrupts ab. Ab dem Kernel 2.2 kann man die Zeit schnell und sicher, aber möglicherweise mit geringerer Präzision, mit get_fast_time bekommen:


 void get_fast_time(struct timeval *tv);

Der Code zum Lesen der aktuellen Uhrzeit steht im Modul jit ("Just In Time") in den Quelldateien auf dem O'Reilly-FTP-Server. jit erzeugt eine Datei namens /proc/currentime, die beim Lesen drei Dinge in ASCII zurückgibt:

Wir verwenden eine dynamische /proc-Datei, weil das Modul so weniger Code enthält; es lohnt sich nicht, ein ganzes Gerät anzulegen, nur weil man drei Textzeilen zurückgeben möchte.

Wenn Sie cat mehrfach während eines Timer-Ticks aufrufen, sehen Sie den Unterschied zwischen xtime und do_gettimeofday, was die Tatsache widerspiegelt, daß xtime seltener aktualisiert wird:

morgana% cd /proc; cat currentime currentime currentime
gettime: 846157215.937221
xtime:   846157215.931188
jiffies: 1308094
gettime: 846157215.939950
xtime:   846157215.931188
jiffies: 1308094
gettime: 846157215.942465
xtime:   846157215.941188
jiffies: 1308095