What Time Is It?
There are several functions that you can use to determine the current time, for use in timestamps or for calculating execution times:
- This is the fastest generic time function we have. It's fast because it just reads from the qtime entries from the system page (see SYSPAGE_ENTRY()). You can find the code for time() on our external web server at http://cvs.qnx.com/cgi-bin/cvsweb.cgi/lib/c/time/time.c; you can use this code directly in your program to save a function call.
- The kernel call for time functions. Using CLOCK_MONOTONIC is typically better than using CLOCK_REALTIME because the monotonic clock is always increasing, so you don't have to worry about someone's changing the clock. Changing the realtime clock just modifies SYSPAGE_ENTRY(qtime)->nsec_tod_adjust to be the difference between the monotonic and realtime clocks.
- A POSIX cover function for ClockTime(). You can find its source at http://cvs.qnx.com/cgi-bin/cvsweb.cgi/lib/c/1b/clock_gettime.c.
All the above methods have an accuracy based on the system timer tick. If you need more accuracy, you can use ClockCycles(). This function is implemented differently for each processor, so there are tradeoffs. The implementation tries to be as quick as possible, so it tries to use a CPU register if possible. Because of this, to get accurate times on SMP machines, you need to use thread affinity to lock the thread to a processor, because each processor can have a ClockCycles() base value that may not synchronized with the values on other processors.
Some caveats for each processor:
- Reads 64 bits from one of two CPU registers (the TIMEBASE or a SPR), depending on the processor. A runtime check determines which register to use. On the PPC 400 series, a fault occurs and the fault handler maps the PPC400 SPRs to the normal SPRs.
- Reads from a 32-bit register, but this register is privileged. If I/O privileges aren't set, then a fault occurs, and the handler returns the value.
- Reads from a 64-bit register, except for 386s and 486s, where it causes a fault and the fault handler reads from an external clock chip.
- Reads from a 32-bit on-chip clock.
- Always faults, and the fault handler reads from an external clock chip to make a 64-bit value.
To convert the cycle number to real time, use SYSPAGE_ENTRY(qtime)->cycles_per_sec.
|SH and MIPS are based on a 32-bit clock, so they can wrap around. You should use ClockCycles() only for short durations.|
If you need a very short delay (e.g. for accessing hardware), you should look at the nanospin* functions. They basically do a while loop to a calibrated number of iterations to delay the proper amount of time (see http://cvs.qnx.com/cgi-bin/cvsweb.cgi/lib/c/qnx/nanospin_count.c and http://cvs.qnx.com/cgi-bin/cvsweb.cgi/lib/c/qnx/nanospin_ns_to_count.c) This wastes CPU, so you should use it only if necessary.