EPICS Home

Experimental Physics and Industrial Control System


 
2002  <20032004  2005  2006  2007  2008  2009  2010  2011  2012  2013  2014  2015  2016  2017  2018  2019  2020  2021  2022  2023  2024  Index 2002  <20032004  2005  2006  2007  2008  2009  2010  2011  2012  2013  2014  2015  2016  2017  2018  2019  2020  2021  2022  2023  2024 
<== Date ==> <== Thread ==>

Subject: RE: EPICS Timer Roundoff
From: "Jeff Hill" <[email protected]>
To: "'Andrew Johnson'" <[email protected]>, "'Marty Kraimer'" <[email protected]>
Cc: "'Ken Evans'" <[email protected]>, <[email protected]>, <[email protected]>, <[email protected]>, <[email protected]>
Date: Mon, 10 Mar 2003 11:03:47 -0700
Let me briefly review that with the epics timer library we
currently have two types of timer queues: active and passive. The
active queues are generic. That is, there can be as many of them
as you like with each one running independently at a specified
thread scheduling priority. They do not require specialized
hardware as is the case with high precision timers such as the
vxWorks auxiliary timers (more on this below). The active timer
queues provide timer delays using epicsThreadSleep(). The passive
queues allow the user to implement the delay scheduling policy
using whatever facilities he deems most appropriate including
specialized high precision hardware or some other system call
such as select(), poll(), or some event blocking call in the Xt
library.

Please recall also my acronym for the minimum delay quantum in
epicsThreadSleep() - ETSMDQ.

Note also that below I use the notation [n,m] to indicate a
random variable RV in the range n<=RV<=m.

> 
> However I don't like the idea of making the minimum timer delay
> less than the one specified - if the application wants to
> subtract half of the quantum from the number it passes 
> in that's Ok though. I assume that's what Jeff meant, I 
> just wanted to clarify the point...

The job of the active timer queues is to provide a timer delay
that averages out as close as possible to the delay that the user
specifies.

We know, but the user is frequently unaware of, the fact that
when we ask the OS to sleep for f seconds in epicsThreadSleep()
that the OS actually provides us with a delay of f + [0,ETSMDQ].
This behavior is a side effect of scheduler efficiency
requirements, and also required to prevent infinite loops in
portable programs that have a loop that happens to sleep for a
delay that is less than ETSMDQ, and it appears to be a universal
feature in the OS that we have encountered, and is stipulated by
the EPICS OSI interface. 

So I will argue that when we are implementing *active* (read
epicsThreadSleep() scheduled) timer queues that if the user
requests a timer delay of f seconds that we should make our delay
request to epicsThreadSleep be f - ETSMDQ/2 seconds so that the
resulting delay will be f + [-ETSMDQ/2, +ETSMDQ/2]. Of course,
when the timer delay is less than ETSMDQ we will end up with a
delay of [0, ETSMDQ]. Again, that can't be avoided if we are to
have portable short period timers that don't result in infinite
loops.

These are certainly details that could become a useful part of
the ADG.

> Note that some versions of Linux provide high resolution
timers,
> in which the timer resolution is much better than the 
> system clock tick.

I suspect that this will be a similar situation to the sys aux
clock in vxWorks where we have a generic OS interface to
hardware. An OSI interface to this type of timer could be a quite
useful extension using the passive timer interface that would
tend to be provided in base, used in application specific
situations, but less often used as a fundamental building block
upon which other base components are constructed. The reason
being that the number of and even the existence of one instance
of, these hardware timers can't be guaranteed. There can also be
resource contention issues between programs that expect to be
independent of each other. So there is the potential problem of
one program's timer expire callback not running because some
other program's timer expire callback is computing pi.
Nevertheless, these limitations do not subtract from the
usefulness of hardware based timer queues in certain specific
situations.

In the timer library, I must interface with a generic timer queue
scheduler implementation. At first, there was the need to inform
a specific timer queue scheduling implementation when it needed
to reschedule because the user just finished installing a timer
with a shorter duration than the current next timer to expire.

Last Thursday I was looking at the fact that the timer's
expiration time is stored in the timer as an EPICS time stamp,
but the scheduling policy is known only by a derived version of
the timer queue. To address this issue I was toying with the idea
of adding a new virtual function to the timer queue scheduler
interface which provides the value of ETSMDQ. This would allow
high precision timer queues to return an ETSMDQ of zero (or
nearly zero). This sleepQuantum() virtual function would be used
to properly initial the EPICS time stamp specifying the timer's
expiration time. Below is what I am currently experimenting with.

class epicsTimerQueueNotify {   
public:
    // called when a new timer is inserted into the queue and the
    // delay to the next expire has changed
    virtual void reschedule () = 0;
    // if their is a quantum in the timer queue's sleep interval
    // return this quantum in seconds otherwise return zero.
    virtual double sleepQuantum () = 0;
protected:
    virtual ~epicsTimerQueueNotify () = 0;
};


Jeff



Navigate by Date:
Prev: Re: R3.14.2 schedule Janet Anderson
Next: Bug in MSI Ralph Lange
Index: 2002  <20032004  2005  2006  2007  2008  2009  2010  2011  2012  2013  2014  2015  2016  2017  2018  2019  2020  2021  2022  2023  2024 
Navigate by Thread:
Prev: RE: R3.14.2 Kenneth Evans, Jr.
Next: Bug in MSI Ralph Lange
Index: 2002  <20032004  2005  2006  2007  2008  2009  2010  2011  2012  2013  2014  2015  2016  2017  2018  2019  2020  2021  2022  2023  2024