In a long-running server program (built in C) in a Posix (Linux) environment: what is the best approach to get a function to execute at a specific time in the future? It doesn't need to execute in any particular thread, but the accuracy of the execution time needs to be a few milliseconds. General approaches or specific code is appreciated.
There are some high resolution clock functions in the GNU C library (sys/timex.h), so although they are not POSIX, they will be portable linux wise.
High Accuracy Clock -- The GNU C Library
Those functions are prefixed 'ntp' although they do not require or make use of any ntp service, so the relationship is purely superficial.
Beware that although the granularity is in microseconds, the linux kernel has a userspace latency of 10ms so don't bother or expect anything more accurate than that.
Once you have the current high resolution time, you could then calculate a duration and use (posix) nanosleep (but again, round to 10ms) to set a delay. There is also a clock_nanosleep which might be of interest.
You should look up posix timers. It gives you a simple interface to scheduling future work. You can manage it to send you a signal in x seconds/ nanoseconds (ad then you can put your function as it's signal handler). Lookup timer_create
Related
I am writing a device driver and want to benchmark a few pieces of code to get a feel for where I could be experiencing some bottlenecks. As a result, I want to time a few segments of code.
In userspace, I'm used to using clock_gettime() with CLOCK_MONOTONIC. Looking at the kernel sources (note that I am running kernel 4.4, but will be upgrading eventually), it appears I have a few choices:
getnstimeofday()
getrawmonotonic()
get_monotonic_coarse()
getboottime()
For convenience, I have written a function (see below) to get me the current time. I am currently using getrawmonotonic() because I figured this is what I wanted. My function returns the current time as a ktime_t, so then I can use ktime_sub() to get the elapsed time between two times.
static ktime_t get_time_now(void) {
struct timespec time_now;
getrawmonotonic(&time_now);
return timespec_to_ktime(time_now);
}
Given the available high resolution clocking functions (jiffies won't work for me), what is the best function for my given application? More generally, I'm interested in any/all documentation about these functions and the underlying clocks. Primarily, I am curious if the clocks are affected by any timing adjustments and what their epochs are.
Are you comparing measurements you're making in the kernel directly with measurements you've made in userspace? I'm wondering about your choice to use CLOCK_MONOTONIC_RAW as the timebase in the kernel, since you chose to use CLOCK_MONOTONIC in userspace. If you're looking for an analogous and non-coarse function in the kernel which returns CLOCK_MONOTONIC (and not CLOCK_MONOTONIC_RAW) time, look at ktime_get_ts().
It's possible you could also be using raw kernel ticks to be measuring what you're trying to measure (rather than jiffies, which represent multiple kernel ticks), but I do not know how to do that off the top of my head.
In general if you're trying to find documentation about Linux timekeeping, you can take a look at Documentation/timers/timekeeping.txt. Usually when I try to figure out kernel timekeeping I also unfortunately just spend a lot of time reading through the kernel source in time/ (time/timekeeping.c is where most of the functions you're thinking of using right now live... it's not super well-commented, but you can probably wrap your head around it with a little bit of time). And if you're feeling altruistic after learning, remember that updating documentation is a good way to contribute to the kernel :)
To your question at the end about how clocks are affected by timing adjustments and what epochs are used:
CLOCK_REALTIME always starts at Jan 01, 1970 at midnight (colloquially known as the Unix Epoch) if there are no RTC's present or if it hasn't already been set by an application in userspace (or I guess a kernel module if you want to be weird). Usually the userspace application which sets this is the ntp daemon, ntpd or chrony or similar. Its value represents the number of seconds passed since 1970.
CLOCK_MONTONIC represents the number of seconds passed since the device was booted up, and if the device is suspended at a CLOCK_MONOTONIC value of x, when it's resumed, it resumes with CLOCK_MONOTONIC set to x as well. It's not supported on ancient kernels.
CLOCK_BOOTTIME is like CLOCK_MONOTONIC, but has time added to it across suspend/resume -- so if you suspend at a CLOCK_BOOTTIME value of x, for 5 seconds, you'll come back with a CLOCK_BOOTTIME value of x+5. It's not supported on old kernels (its support came about after CLOCK_MONOTONIC).
Fully-fleshed NTP daemons (not SNTP daemons -- that's a more lightweight and less accuracy-creating protocol) set the system clock, or CLOCK_REALTIME, using settimeofday() for large adjustments ("steps" or "jumps") -- these immediately affect the total value of CLOCK_REALTIME, and using adjtime() for smaller adjustments ("slewing" or "skewing") -- these affect the rate at which CLOCK_REALTIME moves forward per CPU clock cycle. I think for some architectures you can actually tune the CPU clock cycle through some means or other, and the kernel implements adjtime() this way if possible, but don't quote me on that. From both the bulk of the kernel's perspective and userspace's perspective, it doesn't actually matter.
CLOCK_MONOTONIC, CLOCK_BOOTTIME, and all other friends slew at the same rate as CLOCK_REALTIME, which is actually fairly convenient in most situations. They're not affected by steps in CLOCK_REALTIME, only by slews.
CLOCK_MONOTONIC_RAW, CLOCK_BOOTTIME_RAW, and friends do NOT slew at the same rate as CLOCK_REALTIME, CLOCK_MONOTONIC, and CLOCK_BOOTIME. I guess this is useful sometimes.
Linux provides some process/thread-specific clocks to userspace (CLOCK_PROCESS_CPUTIME_ID, CLOCK_THREAD_CPUTIME_ID), which I know nothing about. I do not know if they're easily accessible in the kernel.
gettimeofday() is hardware dependent with RTC.
Can some one suggest how we can avoid the use of the same in Application Programming.
How we can approach the use of System ticks ?
thanks in advance !
To get time in ticks you might like to use times().
However is is not clear whether those ticks are measured from boot-time.
From man times:
RETURN VALUE
times() returns the number of clock ticks that have elapsed since an
arbitrary point in the past. [...]
[...]
NOTES
On Linux, the "arbitrary point in the past" from which the return
value of times() is measured has varied across kernel versions. On
Linux 2.4 and earlier this point is the moment the system was booted.
Since Linux 2.6, this point is (2^32/HZ) - 300 (i.e., about 429
million) seconds before system boot time. This variability across
kernel versions (and across UNIX implementations), combined with the
fact that the returned value may overflow the range of clock_t, means
that a portable application would be wise to avoid using this value.
To measure changes in elapsed time, use clock_gettime(2) instead.
Reading this using clock_gettitme() with the CLOCK_BOOTTIME timer might be the more secure and more portable way to go. If this function and/or timer is available for system without RTC I'm not sure. Others are encouraged to clarfiy this.
I have a small program that needs to be run in a small Linux embedded system (ARM). It is written in C. It needs to poll some data (2x64-bit) from an API provided by the system manufacturer, and then do some calculations and send the data through the network. The data should be polled around 30 times every second (30Hz).
What would be the best way to do it in C? I've seen solutions using sleep(), but it does not seem to be the best option for the job.
I suggest consider using the poll(2) multiplexing syscall to do the polling.
notice that when poll is waiting and polling for input, it does not consume any CPU
If the processing of each event takes some significant time (e.g. a millisecond or more) you may want to recompute the delay.
You could use timerfd_create(2) (and give both your device file descriptor and your timer fd to poll). See also timer_create(2)...
Perhaps clock_gettime(2) could be useful.
And reading time(7) is definitely useful. Perhaps also the Advanced Linux Programming book.
sleep() suspends execution in seconds, if you are looking for a more accurate sleep()-like function, use usleep() which suspends execution in microseconds, or nanosleep() in nanoseconds.
I would like to measure the ping time between a sender process and a consumer.
Both processes run on the same physical host, Linux 64 bit.
I'm currently using clock_gettime(CLOCK_REALTIME, &cur_ts);.
I basically capture the current timestamp cur_ts and send it to consumer process; as soon as it's being received on the other end I then invoke clock_gettime(CLOCK_REALTIME, &cur_ts); again in the second process and subtract the two times.
Is this procedure accurate to measure ping between two processes? Should I be using something different?
Thanks
Yes
You are using the correct interface. This is a Posix-specified HRT (High Resolution Timer) that is available in modern Loonix, and your use is the canonical standard.
For ping resolutions it probably doesn't matter, but it's possible to use CLOCK_MONOTONIC, especially for short intervals. Under other conditions, CLOCK_REALTIME may be more accurate. However, the exact meaning of these clocks is not specified by Posix, and on Linux, I believe all of them are subject to NTP adjustments. That's a good thing for long intervals, at least.
On Linux, to get access to the underlying hardware clock without NTP adjustments, you have to go off the Posix reservation and use CLOCK_MONOTONIC_RAW.
http://pubs.opengroup.org/onlinepubs/9699919799/functions/clock_gettime.html
I've been converting the main loop of an embedded linux program to run on a server and one of the nice to haves will be to run non-root. The program is in charge of periodically requesting an IO scan from a network device - every 2ms. Today I replaced the use of /dev/rtc with a call to nanosleep. In this particular case we can get away with plenty of latency but I'm wondering if the nanosleep call can be left in for the case when we're running on the embedded device with more strict timing requirements (which is the case for bigger projects). Is there a big difference in performance?
It depends on the Linux kernel version. From the time(7) manpage:
High-Resolution Timers
Before Linux 2.6.21, the accuracy of timer and sleep system calls (see below) was also limited by the
size of the jiffy.
Since Linux 2.6.21, Linux supports high-resolution timers (HRTs), optionally configurable via CON‐
FIG_HIGH_RES_TIMERS. On a system that supports HRTs, the accuracy of sleep and timer system calls is
no longer constrained by the jiffy, but instead can be as accurate as the hardware allows (microsec‐
ond accuracy is typical of modern hardware).
Note: "jiffy" is the timer tick frequency mentioned in the answer by "Greg". Also note that the system calls that this refers to includes nanosleep().
That is, if you have a recent enough version of the kernel on your embedded target, nanosleep() should be good enough. If you have an older kernel version, you're indeed limited by the clock tick frequency, and in that case you might have problems as 2 ms is quite close to the 1 ms tick frequency with CONFIG_HZ=1000.
Man-page for nanosleep suggests that kernel-timers are used, making it sensitive to the value of "HZ" (the kernel "tick"). The tick is commonly 1000HZ (1ms), however for an embedded system this value may not necessarily be the same, you can configure it with kernel parameters depending on what timing sources you have available.
Since /dev/rtc uses interrupts it doesn't tie you to HZ so timing could be more sensitive. Of course that also depends on your RTC hardware.
If in doubt, make a thin abstraction which lets you set a time and pass a callback so you can switch between implementations, and as always with embedded systems - measure it on the real device.