[PATCH 0/5] v2: Progress toward absolute time intervals

Pavel Pisa ppisa4lists at pikron.com
Sun Jul 17 23:21:08 UTC 2016


Hello Gedare,

On Friday 15 of July 2016 19:22:17 Gedare Bloom wrote:
> >
> > cpukit/score/include/rtems/score/percpu.h
> >
> > typedef enum {
> >   /**
> >    * @brief Index for relative per-CPU watchdog header.
> >    *
> >    * The reference time point for this header is current ticks value
> >    * during insert.  Time is measured in clock ticks.
> >    */
> >   PER_CPU_WATCHDOG_RELATIVE,
> >
> >   /**
> >    * @brief Index for absolute per-CPU watchdog header.
> >    *
> >    * The reference time point for this header is the POSIX Epoch.  Time
> > is * measured in nanoseconds since POSIX Epoch.
> >    */
> >   PER_CPU_WATCHDOG_ABSOLUTE,
> >
> >   /**
> >    * @brief Count of per-CPU watchdog headers.
> >    */
> >   PER_CPU_WATCHDOG_COUNT
> > } Per_CPU_Watchdog_index;
> >
> > It is little complicated that each is in different time scale
> > but support is there. But if I do not miss something,
> > your clock_nanosleep() does not distinguish between queues.
>
> I think the WATCHDOG_ABSOLUTE is in ticks also, Sebastian?

I have not found time to analyze code again and deeper.
Sebastian clarification would help.
Is one queue intended as monotonic and another one are
real-time (wall clock time) which can be adjusted?

> > There are four cases for clock_nanosleep() and if only
> > two queues are used then they should be used next way
> >
> >   CLOCK_REALTIME && TIMER_ABSTIME = 0
> >     should use PER_CPU_WATCHDOG_RELATIVE queue
> >     value should be added to
> >     _TOD_Get_zero_based_uptime_as_timespec( &current_time );
> >     and converted to ticks or converted the first
> >     and then added to _Watchdog_Ticks_since_boot added
> >
> >   CLOCK_REALTIME && TIMER_ABSTIME = 1
> >     should use PER_CPU_WATCHDOG_RELATIVE queue
> >     value needs to be only converted to ticks
> >
> >   CLOCK_MONOTONIC && TIMER_ABSTIME = 0
> >     should use PER_CPU_WATCHDOG_ABSOLUTE queue
> >     value has to be added to value retrieved by
> >       _TOD_Get_as_timespec( &current_time );
> >           getnanouptime(struct timespec *tsp)
> >     with nanoseconds field overflow correction then converted
> >     somewhere to uint64_t packed timespec value by
> >     _Watchdog_Ticks_from_timespec
> >
> >   CLOCK_MONOTONIC && TIMER_ABSTIME = 1
> >     should use PER_CPU_WATCHDOG_ABSOLUTE queue
> >     value needs only to be repacked by _Watchdog_Ticks_from_timespec
> >
> > But I am not sure if the queues are really intended that way,
> > one as monotonic and the second as realtime or if they are there
> > only to spedup/eliminate complete conversion from timespec to ticks.
> >
> > But if there is option to set and adjust CLOCK_REALTIME there has to
> > be some other/completely separated queue for monotonic time based
> > operations.
>
> The RELATIVE queue bases the timeout from when the thread is added,
> and the timeout interval only takes into consideration the ticks that
> have actually elapsed since.

The queues are per CPU not per single task as I read the code.
So the PER_CPU_WATCHDOG_RELATIVE should be monotonic equivalent.

> The ABSOLUTE queue checks the system time _Timecounter_Getnanotime()
> to see if the timeout has been reached.
>
> Now I think I fixed my logic to use the relative queue for the
> monotonic clock, so it only considers actual ticks, and the absolute
> queue for the realtime clock so that if the timecounter gets adjusted
> it would cause the timeout to fire. Now, I'm not quite certain if/how
> the timecounter gets updated.
>
> > void _Watchdog_Insert(
> >   Watchdog_Header  *header,
> >   Watchdog_Control *the_watchdog,
> >   uint64_t          expire
> > )
> >
> >     if ( expire < parent_watchdog->expire ) {
> >       link = _RBTree_Left_reference( parent );
> >     } else {
> >       link = _RBTree_Right_reference( parent );
> >       new_first = old_first;
> >     }
>
> Yes this could be done but I don't know how much it matters. A ticket
> may be opened at least, if you feel strongly this should be considered
> later.

It is not critical for now.

> > Generally, I am not 100% sure about mapping to actual RTEMS code
> > but the concept of realtime and monotonic time is critical
> > for control applications.
>
> Agreed. Thanks for the feedback. I had spent a lot more time on
> building the score infrastructure than on thinking through the POSIX
> issues here.

It would be nice to have this part clean. I think that Linux clocksources
and clock event devices/timers are done right way. There has been
many considerations and approaches between 64-bit nanosecond scale
and something which could be faster on 32-bit systems when timespec
is used. I have not checked that now, but as I know implementation
settled on 64-bit nanoseconds. This allows to enhance timers and system
to use high resolution and tickless modes.

So I would personally tend to use the same. Conversion from timespec
to 64-bit ns is not horrible. Conversion back is quite expensive.
It seems that Linux kernel does not found something better then
real division (at least on x86). See

  http://lxr.free-electrons.com/source/kernel/time/time.c#L476

On the other hand, calling between different clock sources
nanosecond based time can be quite efficient and changed
to 32-bit x 64-bit multiply and 64-bit shift right.
The quotients and shifts can be precomputed for both directions
and it can be quite fast.
 

Best wishes,

                Pavel



More information about the devel mailing list