Re: System-Zeitgeber programmieren

From: Oliver Fromme <olli(at)lurza.secnetix.de>
Date: Tue, 6 Mar 2007 16:31:51 +0100 (CET)

Marc Santhoff wrote:
> Oliver Fromme wrote:
> > Für welchen Zweck benötigst Du ihn denn?
>
> Das ist leider im Vorweg nicht zu sagen.

Dann kann man leider auch keine Empfehlungen für eine
Implementation geben.

> Ich persönlich brauche ihn, um 1s-Intervalle oder etwas mehr abzumessen,
> also durchaus geeignet.

Um etwas zu _messen_, ist ualarm() + Signale völlig unge-
eignet. Um ein Zeitintervall zu messen, ist es das Ein-
fachste und Effizienteste, an den beiden Endpunkten
gettimeofday() aufzurufen und dann die Differenz zu bilden.
Das ist unabhängig von HZ und deutlich präziser (unter
FreeBSD im Mikrosekunden-Bereich). Und portabel ist es
auch, allerdings kann auf anderen Systemen die Präzision
geringer sein (jedoch im allgemeinen nicht geringer als
die Scheduler-Frequenz).

> Hmm, derzeit 4.11 also HZ=100 ... ist aber nicht mehr lange so.

Wie gesagt, Du kannst es im Kernel auch anders einstellen,
d.h. Du kannst durchaus auch unter FreeBSD 4 einen Kernel
mit HZ=1000 (oder noch höher) compilieren.

> S.o., wie erreiche ich denn auch auf langsamerer Hardware leidlich
> genaue 1ms?

Wie gesagt, das kommt drauf an. Wenn Dir andere Prozesse
egal sind, kannst Du gettimeofday() in einer Busy-Loop
aufrufen und »pollen«. Das ist vermutlich das Präziseste,
was Du auf langsamer Hardware portabel machen kannst.

Wenn Du auf halbwegs aktueller i386-Hardware bist und eine
noch genauere Messung brauchst (sub-Mikrosekunden), kannst
Du perfmon(4) verwenden (per ioctl PMIOTSTAMP). Damit er-
hältst Du die volle Taktfrequenz-Auflösung des Prozessors;
genauer geht es nicht. Ist allerdings nicht portabel
(perfmon(4) gibt es in dieser Form nur unter FreeBSD und
DF, und auch nur auf i386-Hardware >= Pentium). Außerdem
kann sich die Frequenz unerwartet ändern, wenn powerd(8)
läuft, oder durch andere Einflüsse.

> Mit usleep() sollte es zumindest möglich sein,

Da muss ich Dich leider enttäuschen: Auch bei usleep() und
bei nanosleep() werden die Zeiten auf HZ aufgerundet.
Genauer wirst Du es ohne Busy-Loop (s.o.) nicht hinbekom-
men (und portabel schonmal gar nicht).

Signal-Delivery und das gesamte Process-Scheduling ist an
die HZ-Frequenz gebunden. Auf dieser Basis bekommst Du
also nichts Genaueres hin. Ich nehme an, dass auch Dein
altes GTK-Interface nicht genauer war, auch wenn es Werte
im ms-Auflösung akzeptierte.

> Ich hätte als Alternative noch eine Quelle, die teils in Assembler
> geschrieben ist und die Performance-Timer der x86-CPU benutzt, ich muß
> nochmal gucken, ob die auch auf anderer Hardware was tut ...

Da kannst Du auch ebensogut das perfmon(4)-Interface ver-
wenden; dann brauchst Du immerhin kein Assembler.

Gruß
   Olli

-- 
Oliver Fromme, secnetix GmbH & Co. KG, Marktplatz 29, 85567 Grafing b. M.
Handelsregister: Registergericht Muenchen, HRA 74606,  Geschäftsfuehrung:
secnetix Verwaltungsgesellsch. mbH, Handelsregister: Registergericht Mün-
chen, HRB 125758,  Geschäftsführer: Maik Bachmann, Olaf Erb, Ralf Gebhart
Any opinions expressed in this message are personal to the author and may
not necessarily reflect the opinions of secnetix GmbH & Co KG in any way.
FreeBSD-Dienstleistungen, -Produkte und mehr:  http://www.secnetix.de/bsd
Passwords are like underwear.  You don't share them,
you don't hang them on your monitor or under your keyboard,
you don't email them, or put them on a web site,
and you must change them very often.
To Unsubscribe: send mail to majordomo(at)de.FreeBSD.org
with "unsubscribe de-bsd-questions" in the body of the message
Received on Tue 06 Mar 2007 - 16:33:05 CET

search this site