Jan Kiszka wrote:
<snip>
Simple example, based on native skin:
Call rt_sem_p with a timeout provided in nanoseconds.
aperiodic mode
--------------
timeout = 100000000; // 1 ms
...
rt_sem_p(&sem, timeout);
periodic mode
-------------
timeout = 100000000; // 1 ms
...
rt_sem_p(&sem, rt_timer_ns2ticks(timeout));
Now you have two different code fragments serving the same purpose, only
performing under different timer modes. No big problem for the
application that knows how it configured the timer, but anything at
lower levels always has to check for the current mode.
I do not understand yet the portability problem of TSC values, but the
inconsistency issue on SMP systems was new to me and make your choice a
bit more comprehensible. Does moving to nanoseconds really solve the
problem? The clocks used in aperiodic mode will not run synchronised nor
will they be started at (almost) the same time, will they? So, all
absolute times (taken on CPU A and applied on CPU B) might still be
inconsistent.
We hold per-cpu timer lists, so TSC bases are never mixed, even if
timers can be migrated explicitely, but in such a case, they are always
re-inited. IOW, outstanding timers don't migrate.
I would personally vote for a more consistent way: either ticks or
nanoseconds - in both modes. Actually, I would prefer the tick
variant at nucleus level.
What would such tick represent in aperiodic mode, time-wise?
For me, ticks are what the system timer uses internally in the
respective mode: TSCs?! Then it becomes more understandable to the
developer that one always has to convert human-processable time to
internal units.
I feel that you would be doing the job of the interface, assuming poorly
written conversion routines and particular patterns of use that would
make your app issue conversion requests at 50Khz. However, AFAIK,
POSIX's timespecs do not deal with TSCs either, likely because the
common pattern of use for timed services involves heavy-weight blocking
operations, and you don't do those inside a tight loop, unless your
system is going wild and never blocks. There, my perception is that the
cost of converting nanoseconds to ticks is nothing compared to the cost
of grabbing the resource associated to a synchronization object or even
the task being put to sleep.
Now, for the particular case of a periodic task with say, a 20 us work
cycle, the timeout as nanoseconds is not an issue, since the period is
converted once when the task is made periodic, then the internally
converted value is used with no further conversion needed by the
nucleus, in order to wait for the next release point in the CPU timeline.
Well, it's indeed just a matter of perception, and I understand that
people wanting to get the maximum of each CPU cycle on a 386 might find
my reasoning totally bugous. This said, everything is a question of
balance, and I strongly feel that there are many other much more
time-consuming issues to solve, which unlike - the conversions - are on
the critical path. What I think we buy with the nanosecond-based
timespecs is ease-of-use, portability and consistency. But hey, maybe
it's just me returning -ENOBRAIN in wild loop?! o:) In any case, I will
have no problem recognizing that I've been wrong on this, but for that,
I would need actual facts and figures on common real-world test cases.
Frankly, a really bothering issue regarding timer performance for me is
clearly not conversion issues, but rather the way outstanding aperiodic
timers are linked to a single queue, so that a braindead linear search
is required to add a timer to the list. That, is clearly something we
will work on as part of our scalability effort.
Well, I just read through xntimer_do_timers again and I remembered it
correctly: you don't actually make use of nanoseconds as tick
abstraction in aperiodic mode. Otherwise, you should store all timer
dates as nanoseconds and convert the current time to ns before starting
to compare it with the pending timers. This way it is now should not
provide any advantage on SMP boxes, should it?
The advantage of using nanoseconds externally is meant for the user, not
for the timing code which only deals with TSCs internally, added to the
fact that the per-cpu timer lists are used in SMP, so no timebase
mismatch occurs.
--
Philippe.