Updated: April 19, 2023 |
We've seen the clock source CLOCK_REALTIME, and mentioned that a POSIX-conforming implementation may supply as many different clock sources as it feels like, provided that it at least provides CLOCK_REALTIME.
What is a clock source? Simply put, it's an abstract source of timing information. If you want to put it into real life concepts, your personal watch is a clock source; it measures how fast time goes by. Your watch will have a different level of accuracy than someone else's watch. You may forget to wind your watch, or get it new batteries, and time may seem to freeze for a while. Or, you may adjust your watch, and all of a sudden time seems to jump. These are all characteristics of a clock source.
(QNX Neutrino provides some special clock sources that you can use to track how much CPU time a process or thread uses, but they're beyond the scope of this chapter. See Monitoring execution times in the Understanding the Microkernel's Concept of Time chapter of the QNX Neutrino Programmer's Guide.)
Under QNX Neutrino, CLOCK_REALTIME is based off of the current time of day clock that the OS provides. (In the examples below, we refer to this as QNX Neutrino time.) This means that if the system is running, and suddenly someone adjusts the time forward by 5 seconds, the change may or may not adversely affect your programs (depending on what you're doing). Let's look at a sleep (30); call:
Real time | QNX Neutrino time | Activity |
---|---|---|
11:22:05 | 11:22:00 | sleep (30); |
11:22:15 | 11:22:15 | Clock gets adjusted to 11:22:15; it was 5 seconds too slow! |
11:22:35 | 11:22:35 | sleep (30); wakes up |
Beautiful! The thread did exactly what you expected: at 11:22:00 it went to sleep for thirty seconds, and at 11:22:35 (thirty elapsed seconds later) it woke up. Notice how the sleep() appeared to sleep for 35 seconds, instead of 30; in real, elapsed time, though, only 30 seconds went by because QNX Neutrino's clock got adjusted ahead by five seconds (at 11:22:15).
The kernel knows that the sleep() call is a relative timer, so it takes care to ensure that the specified amount of real time elapses.
Now, what if, on the other hand, we had used an absolute timer, and at 11:22:00 in QNX Neutrino time told the kernel to wake us up at 11:22:30?
Real time | QNX Neutrino time | Activity |
---|---|---|
11:22:05 | 11:22:00 | Wake up at 11:22:30 |
11:22:15 | 11:22:15 | Clock gets adjusted as before |
11:22:30 | 11:22:30 | Wakes up |
This too is just like what you'd expect—you wanted to be woken up at 11:22:30, and (in spite of adjusting the time) you were. However, in real time, the timer expired after 25 seconds, instead of the full 30. Depending on the application, this could be a problem.