I wish to write a C program which obtains the system time and hence
uses this time to print out its ntp equivalent.
Am I right in saying that the following is correct for the seconds part
of the ntp time?
long int ntp.seconds = time(NULL) + 2208988800;
How might I calculate the fraction part?
The fractional part to add obviously is 0ps ... ;-)
So the question for the fraction could be reduced to how accurate is the system clock.
gettimeofday() gets you micro seconds. clock_gettime() could get you nano seconds.
Anyhow I doubt you'll be reaching the theoratically possible resolution the 32bit wide value for the fraction allows (at least on a standard PC).
Related
Does anyboy have an idea how the time() function works?
I was looking online for implementations out of pure curiosity, but could only find the NetBSD implementation of difftime()
Also is there anything that describes the process of calculating the time (non system specific or system specific)?
Note: I am not looking for answers on how to use time() but how it actually works behind the scenes when I call it.
Somewhere deep down in your computer, typically in hardware, there's a clock oscillator running at some frequency f. For the purposes of this example let's say that it's operating at 1 kHz, or 1,000 cycles per second. Things are set up so that every cycle of the oscillator triggers a CPU interrupt.
There's also a low-level counter c. Every time the clock interrupt is triggered, the OS increments the counter. For the moment we'll imagine it increments it by 1, although this won't usually be the case in practice.
The OS also checks the value of the counter as it's incremented. When c equals 1,000, this means that exactly one second has gone by. At this point the OS does two things:
It increments another counter variable, the one that's keeping track of the actual time of day in seconds. We'll call this other counter t. (It's going to be a big number, so it'll be at least a 32-bit variable, or these days, 64 bits if possible.)
It resets c to 0.
Finally, when you call time(), the kernel simply returns you the current value of t. It's pretty simple, really!
Well, actually, it's somewhat more complicated than that. I've overlooked the details of how the value of the counter t gets set up initially, and how the OS makes sure that the oscillator is running at the right frequency, and a few other things.
When the OS boots, and if it's on a PC or workstation or mainframe or other "big" computer, it's typically got a battery-backed real-time clock it can use to set the initial value of t from. (If the CPU we're talking about is an embedded microcontroller, on the other hand, it may not have any kind of clock, and all of this is moot, and time() is not implemented at all.)
Also, when you (as root) call settimeofday, you're basically just supplying a value to jam into the kernel's t counter.
Also, of course, on a networked system, something like NTP is busy keeping the system's time up-to-date.
NTP can do that in two ways:
If it notices that t is way off, it can just set it to a new value, more or less as settimeofday() does.
If it notices that t is just a little bit off, or if it notices that the underlying oscillator isn't counting at quite the right frequency, it can try to adjust that frequency.
Adjusting the frequency sounds straightforward enough, but the details can get pretty complicated. You can imagine that the frequency f of the underlying oscillator is adjusted slightly. Or, you can imagine that f is left the same, but when the time interrupt fires, the numeric increment that's added to c is adjusted slightly.
In particular, it won't usually be the case that the kernel adds 1 to c on each timer interrupt, and that when c reaches 1,000, that's the indication that one second has gone by. It's more likely that the kernel will add a number like 1,000,000 to c on each timer interrupt, meaning that it will wait until c has reached 1,000,000,000 before deciding that one second has gone by. That way, the kernel can make more fine-grained adjustments to the clock rate: if things are running just a little slow, it can change its mind, and add 1,000,001 to c on each timer interrupt, and this will make things run just a tiny bit faster. (Something like one part per million, as you can pretty easily see.)
One more thing I overlooked is that time() isn't the only way of asking what the system time is. You can also make calls like gettimeofday(), which gives you a sub-second time stamp represented as seconds+microseconds (struct timeval), or clock_gettime(), which gives you a sub-second time stamp represented as seconds+nanoseconds (struct timespec). How are those implemented? Well, instead of just reading out the value of t, the kernel can also peek at c to see how far into the next second it is. In particular, if c is counting up to 1,000,000,000, then the kernel can give you microseconds by dividing c by 1,000, and it can give you nanoseconds by returning c directly.
Two footnotes:
(1) If we've adjusted the frequency, and we're adding 1,000,001 to c on each low-level timer tick, c will usually not hit 1,000,000,000 exactly, so the test when deciding whether to increment t will have to involve a greater-than-or-equal-to condition, and we'll have to subtract 1,000,000,000 from c, not just clear it. In other words, the code will look something like
if(c >= 1000000000) {
t++;
c -= 1000000000;
}
(2) Since time() and gettimeofday() are two of the simplest system calls around, and since programs calling them may (by definition) be particularly sensitive to any latency due to system call overhead, these are the calls that are most likely to be implemented based on the vDSO mechanism, if it's in use.
The C specification does not say anything about how library functions work. It only states the observable behavior. The internal workings is both compiler and platform dependent.
Synopsis
#include <time.h>
time_t time(time_t *timer);
Description
The time function determines the current calendar time. The encoding of the value is unspecified.
Returns
The time function returns the implementation's best approximation to the current calendar time. The value (time_t)(-1) is returned if the calendar time is not available. If timer is not a null pointer, the return value is also assigned to the object it points to.
https://port70.net/~nsz/c/c11/n1570.html
Here is one implementation:
time_t
time (timer)
time_t *timer;
{
__set_errno (ENOSYS);
if (timer != NULL)
*timer = (time_t) -1;
return (time_t) -1;
}
https://github.com/lattera/glibc/blob/master/time/time.c
I am trying to get process start time in kernel module.
I get the proc struct pointer, and from the proc I take field p_mstart ()
typedef struct proc {
.....
/*
* Microstate accounting, resource usage, and real-time profiling
*/
hrtime_t p_mstart; /* hi-res process start time */
this return me the number: 1976026375725303
struct proc* iterated_process_ptr = curproc
LOG("***KERNEL***: PID=%d, StartTime=%lld",iterated_process_ptr->p_pidp->pid_id, iterated_process_ptr->p_mstart);
What is this number ?
In the documentation solaris write:
The gethrtime() function returns the current high-resolution real time. Time is expressed as nanoseconds since some arbitrary time in the past.
And in the book Solaris Internals they write:
Within the process, the operating system maintains a high-resolution teimstamp that marks process start and terminate times, A p_mstart field, the process start time, is set in the kernel fork() code when the process is created.... it return 64-bit value expressed in nanosecond
The number 1976026375725303 does not make sense at all.
If i divide by 1,000,000,000 and then by 3600 in order to get hours, i get 528 hours, 22 days, but my uptime is 5 days..
Based on answer received at google group: comp.unix.solaris.
Instead of going to proc -> p_mstart
I need to take
iterated_process_ptr ->p_user.u_start
This bring me the same struct (timestruc_t) as userspace
typedef struct psinfo {
psinfo ->pr_start; /* process start time, from the epoch */
The number 1976026375725303 does not make sense at all.
Yes it does. Per the very documentation that you quoted:
Time is expressed as nanoseconds since some arbitrary time in the
past.
Thus, the value can be used to calculate how long ago the process started:
hrtime_t howLongAgo = gethrtime() - p->p_mstart;
That produces a value in nanoseconds for how long ago the process started.
And note that the value produced is accurate - the value from iterated_process_ptr ->p_user.u_start is subject to system clock changes, so you can't say, "This process has been running for 3 hours, 15 minutes, and 3 seconds" unless you also know the system clock hasn't been reset or modified in any way.
Per the Solaris 11 gethrtime.9F man page:
Description
The gethrtime() function returns the current high-resolution real
time. Time is expressed as nanoseconds since some arbitrary time in
the past; it is not correlated in any way to the time of day, and
thus is not subject to resetting or drifting by way of adjtime(2) or
settimeofday(3C). The hi-res timer is ideally suited to performance
measurement tasks, where cheap, accurate interval timing is required.
Return Values
gethrtime() always returns the current high-resolution real time.
There are no error conditions.
...
Notes
Although the units of hi-res time are always the same (nanoseconds),
the actual resolution is hardware dependent. Hi-res time is guaranteed
to be monotonic (it does not go backward, it does not periodically
wrap) and linear (it does not occasionally speed up or slow down for
adjustment, as the time of day can), but not necessarily unique: two
sufficiently proximate calls might return the same value.
The time base used for this function is the same as that for
gethrtime(3C). Values returned by both of these functions can be
interleaved for comparison purposes.
looking for assistance on getting the real, user, sys times of functions within my C program. For instance how long it took to read in a file. I have been looking at the #include and using the time() function with the -p flag but I am striking out on the execution of this. I guess my question is if I have:
time_t total_time;
time_t start, end;
start = time(-p, &start);
<some code>
end = time(-p, &end);
printf("real = %e, user = %S, sys = %S\n", ???????????);
I understand the differences between the three times, just don't know the proper execution of getting the results.
Check time()'s return value:
The value returned generally represents the number of seconds since 00:00 hours, Jan 1, 1970 UTC (i.e., the current unix timestamp). Although libraries may use a different representation of time: Portable programs should not use the value returned by this function directly, but always rely on calls to other elements of the standard library to translate them to portable types (such as localtime, gmtime or difftime).
To display the real time, read this answer.
For user and system, read: How to measure user/system cpu time for a piece of program?
The real elapsed time can be determined by calling time() before and after, and subtracting the results. If you want to be portable, you should use the difftime function to perform the subtraction, because the return value from time() is not guaranteed to be a number.
If you are using a POSIX compliant system, however, the return value from time() will be the number of seconds since the epoch, so you could just subtract them to get the elapsed seconds.
If you wanted a higher resolution result, you could use gettimeofday(), which returns a timeval struct containing millisecond resolution time.
The most portable way to access the user & system times would be to call the clock() C library function, however you have noted in your comments to #gsamaras that your system does not have this function.
Depending on the system you are working with, you may be able to call the system functions times() or getrusage(). getrusage() would be easier to use, because it returns the values as timeval structs, which contain seconds and milliseconds. times() returns clock ticks which you would have to convert if you wanted actual time units.
If your program is threaded, and you are using Linux, getrusage() offers an additional advantage: you can get the resource consumption for the current thread.
Whichever function you choose the process would be to obtain the initial reading, the final reading, and subtract the two results to see the time consumed by your function.
I need to do precision timing to the 1 us level to time a change in duty cycle of a pwm wave.
Background
I am using a Gumstix Over Water COM (https://www.gumstix.com/store/app.php/products/265/) that has a single core ARM Cortex-A8 processor running at 499.92 BogoMIPS (the Gumstix page claims up to 1Ghz with 800Mhz recommended) according to /proc/cpuinfo. The OS is an Angstrom Image version of Linux based of kernel version 2.6.34 and it is stock on the Gumstix Water COM.
The Problem
I have done a fair amount of reading about precise timing in Linux (and have tried most of it) and the consensus seems to be that using clock_gettime() and referencing CLOCK_MONOTONIC is the best way to do it. (I would have liked to use the RDTSC register for timing since I have one core with minimal power saving abilities but this is not an Intel processor.) So here is the odd part, while clock_getres() returns 1, suggesting resolution at 1 ns, actual timing tests suggest a minimum resolution of 30517ns or (it can't be coincidence) exactly the time between a 32.768KHz clock ticks. Here's what I mean:
// Stackoverflow example
#include <stdio.h>
#include <time.h>
#define SEC2NANOSEC 1000000000
int main( int argc, const char* argv[] )
{
// //////////////// Min resolution test //////////////////////
struct timespec resStart, resEnd, ts;
ts.tv_sec = 0; // s
ts.tv_nsec = 1; // ns
int iters = 100;
double resTime,sum = 0;
int i;
for (i = 0; i<iters; i++)
{
clock_gettime(CLOCK_MONOTONIC, &resStart); // start timer
// clock_nanosleep(CLOCK_MONOTONIC, 0, &ts, &ts);
clock_gettime(CLOCK_MONOTONIC, &resEnd); // end timer
resTime = ((double)resEnd.tv_sec*SEC2NANOSEC + (double)resEnd.tv_nsec
- ((double)resStart.tv_sec*SEC2NANOSEC + (double)resStart.tv_nsec);
sum = sum + resTime;
printf("resTime = %f\n",resTime);
}
printf("Average = %f\n",sum/(double)iters);
}
(Don't fret over the double casting, tv_sec in a time_t and tv_nsec is a long.)
Compile with:
gcc soExample.c -o runSOExample -lrt
Run with:
./runSOExample
With the nanosleep commented out as shown, the result is either 0ns or 30517ns with the majority being 0ns. This leads me to believe that CLOCK_MONOTONIC is updated at 32.768kHz and most of the time the clock has not been updated before the second clock_gettime() call is made and in cases where the result is 30517ns the clock has been updated between calls.
When I do the same thing on my development computer (AMD FX(tm)-6100 Six-Core Processor running at 1.4 GHz) the minimum delay is a more constant 149-151ns with no zeros.
So, let's compare those results to the CPU speeds. For the Gumstix, that 30517ns (32.768kHz) equates to 15298 cycles of the 499.93MHz cpu. For my dev computer that 150ns equates to 210 cycles of the 1.4Ghz CPU.
With the clock_nanosleep() call uncommented the average results are these:
Gumstix: Avg value = 213623 and the result varies, up and down, by multiples of that min resolution of 30517ns
Dev computer: 57710-68065 ns with no clear trend. In the case of the dev computer I expect the resolution to actually be at the 1 ns level and the measured ~150ns truly is the time elapsed between the two clock_gettime() calls.
So, my question's are these:
What determines that minimum resolution?
Why is the resolution of the dev computer 30000X better than the Gumstix when the processor is only running ~2.6X faster?
Is there a way to change how often CLOCK_MONOTONIC is updated and where? In the kernel?
Thanks! If you need more info or clarification just ask.
As I understand, the difference between two environments(Gumstix and your Dev-computer) might be the underlying timer h/w they are using.
Commented nanosleep() case:
You are using clock_gettime() twice. To give you a rough idea of what this clock_gettime() will ultimately get mapped to(in kernel):
clock_gettime -->clock_get() -->posix_ktime_get_ts -->ktime_get_ts() -->timekeeping_get_ns()
-->clock->read()
clock->read() basically reads the value of the counter provided by underlying timer driver and corresponding h/w. A simple difference with stored value of the counter in the past and current counter value and then nanoseconds conversion mathematics will yield you the nanoseconds elapsed and will update the time-keeping data structures in kernel.
For example , if you have a HPET timer which gives you a 10 MHz clock, the h/w counter will get updated at 100 ns time interval.
Lets say, on first clock->read(), you get a counter value of X.
Linux Time-keeping data structures will read this value of X, get the difference 'D'compared to some old stored counter value.Do some counter-difference 'D' to nanoseconds 'n' conversion mathematics, update the data-structure by 'n'
Yield this new time value to the user space.
When second clock->read() is issued, it will again read the counter and update the time.
Now, for a HPET timer, this counter is getting updated every 100ns and hence , you will see this difference being reported to the user-space.
Now, Let's replace this HPET timer with a slow 32.768 KHz clock. Now , clock->read()'s counter will updated only after 30517 ns seconds, so, if you second call to clock_gettime() is before this period, you will get 0(which is majority of the cases) and in some cases, your second function call will be placed after counter has incremented by 1, i.e 30517 ns has elapsed. Hence , the value of 30517 ns sometimes.
Uncommented Nanosleep() case:
Let's trace the clock_nanosleep() for monotonic clocks:
clock_nanosleep() -->nsleep --> common_nsleep() -->hrtimer_nanosleep() -->do_nanosleep()
do_nanosleep() will simply put the current task in INTERRUPTIBLE state, will wait for the timer to expire(which is 1 ns) and then set the current task in RUNNING state again. You see, there are lot of factors involved now, mainly when your kernel thread (and hence the user space process) will be scheduled again. Depending on your OS, you will always face some latency when your doing a context-switch and this is what we observe with the average values.
Now Your questions:
What determines that minimum resolution?
I think the resolution/precision of your system will depend on the underlying timer hardware being used(assuming your OS is able to provide that precision to the user space process).
*Why is the resolution of the dev computer 30000X better than the Gumstix when the processor is only running ~2.6X faster?*
Sorry, I missed you here. How it is 30000x faster? To me , it looks like something 200x faster(30714 ns/ 150 ns ~ 200X ? ) .But anyway, as I understand, CPU speed may or may not have to do with the timer resolution/precision. So, this assumption may be right in some architectures(when you are using TSC H/W), though, might fail in others(using HPET, PIT etc).
Is there a way to change how often CLOCK_MONOTONIC is updated and where? In the kernel?
you can always look into the kernel code for details(that's how i looked into it).
In linux kernel code , look for these source files and Documentation:
kernel/posix-timers.c
kernel/hrtimer.c
Documentation/timers/hrtimers.txt
I do not have gumstix on hand, but it looks like your clocksource is slow.
run:
$ dmesg | grep clocksource
If you get back
[ 0.560455] Switching to clocksource 32k_counter
This might explain why your clock is so slow.
In the recent kernels there is a directory /sys/devices/system/clocksource/clocksource0 with two files: available_clocksource and current_clocksource. If you have this directory, try switching to a different source by echo'ing its name into second file.
Anybody knows, how to get real value of clock per sec? clock() from time.h returns clocks from start of my process, so it need to be divided by CLOCKS_PER_SEC, but this constant has always value 1000000.
Is there some POSIX standard for this?
That's how it specified in the C specification.
If you want to measure elapsed time, there are other (and better) functions, like gettimeofday for example.