
Dear Graeme Russ,
In message 4E1CE6EC.1030900@gmail.com you wrote:
Also remember that if we are looking to inherit nanosecond time base from Linux, it will be extremely unlikely that every board will support a native 1ns clock source. Typical examples would be 33MHz (~30ns) or 66MHz (~15ns). In any case, there will be a lot of variance between boards, so we will still need to cater for arbitrary resolutions
Please note that Linux makes no assumption of a 1 ns clock source. We should hav eno problems on this front.
It's just macros. And we don't need to use them all. Actually time_after() is all that's needed to satisfy our current usage.
Oh please, macro, inline function, function - They are all API 'functions'
- As you stated before, the bigger the API, the more people will abuse is
by using the wrong functions. You stated that you want to keep the public profile of the API as small and tight as possible by rejecting the additional functions previously proposed.
OK, so let's start with time_after() only.
Agreed - As said before (for the time being) the return value of any arbitrary call to time() means nothing. It _may_ mean the number of nanoseconds since power-up, but this is by no means guaranteed.
Actually, I do agree will Bill - time() is probably not the best name - get_current_ns() or similar may be more meaningful (I still have not had a chance to look at the Linux code)
If you don't want to use time, then let's use get_time() please - this is close enough to the existing name so everybody familiar with the code recognizes it immediately.
void udelay(u32 usec) { u64 then = time() + (u64)usec * (u64)1000;
while (!time_after(time(), then)) ... do something, like trigger watchdogs etc ... }
Yes, that is how I always imagined udelay()
...except that udelay() is guaranteed to be available very early in the initialization sequence, long before we have "normal" timer services which may - for example - be interrupt based.
For 'elapsed time' it should be sufficient to store the start value of time() as early as possible in the (architecture specific) code.
I did mean 'elapsed between two code locations' such as profiling the init functions - That was what API function #3 was all about.
Sounds trivial: store the value of time() and the begin and the end of the interval and compute the difference?
OK, this is a new philosophy for the mix. I think it is a good one for the record. But since we will always use time_after(time(), then) why don't we simplify it to:
u64 start = time(); ... if (time_elapsed_since(start, TIMEOUT)) { /* handle timeout */ }
This does not fit. time_elapsed_since() suggests it returns the length of the interval, i. e. a number of tiume units - but it does something different.
I like the time_after() approach very much because it does exactly what the name says, and nothing more - so you can use it in a number of ways - I recognise good old UNIX philosophy here: do one simple thing, and do it well.
Regarding the "we will always use time_after(time() ...) - we might want to check if we really have to use time() here (and in a number of other places - or if we can manage to come up with a simple timestamp variable, similar to what jiffies is in Linux. That would simplify the code even further. [Maybe "#define jiffies time()"? ;-) }
Do we? What exactly is the needed resolution of the underlying hardware timer? So far, it appears sufficient to have it ticking with 1000 Hz or more. Are there really systems that cannot provide that? The only architecture I remember that seemed prolematic was NIOS - but then the NIOS documentation suggests that this might actually be solvable.
Yes, but as stated before, there is a FPGA gate count trade-off which may not always be possible. Plus, you break existing boards
Understood. Well, how work the Linux timers on these boards, then?
Best regards,
Wolfgang Denk