Re: $BASETIME (^T) inaccurate?
by haukex (Archbishop) on Apr 11, 2023 at 06:59 UTC
|
It's running on an rPi4
Raspberry Pis don't have a Real-Time Clock with a backup battery, meaning on boot they have no idea what time it actually is, and they need to set the system time from an external source like an NTP server every time. time will change based on adjustments to the system time; if you're starting your script on boot or the system clock drifts and is adjusted by NTP during its runtime the measurement will be affected. If you want to know how long your script has actually been running in real-world time, independently of changes to the system clock, one way to do that is:
use Time::HiRes qw/clock_gettime CLOCK_MONOTONIC/;
my $start_time_s = clock_gettime(CLOCK_MONOTONIC);
...
my $run_time_s = clock_gettime(CLOCK_MONOTONIC) - $start_time_s;
See the documentation of clock_gettime for details - you may even want to use CLOCK_MONOTONIC_RAW depending on your requirements.
Edit: Better link to manpage | [reply] [d/l] [select] |
Re: $BASETIME (^T) inaccurate?
by ikegami (Patriarch) on Apr 11, 2023 at 19:13 UTC
|
$^T returns PL_basetime, which is obtained using the C code time(&PL_basetime) executed at startup.
time returns the value returned by the C code time(NULL)
So $^T - time is based on two readings of the clock obtained using time, which we know accurately returns the system time.
On Linux, Unix::Uptime->uptime uses /proc/uptime.
I don't know how this is calculated. If it's based on a counter counting ticks or similar, it wouldn't be based on the clock. Such an approach would result in a different amount than a difference in clock times if the clock is adjusted between the readings.
Updated to add more.
| [reply] [d/l] [select] |
Re: $BASETIME (^T) inaccurate?
by LanX (Saint) on Apr 11, 2023 at 02:42 UTC
|
> the program uptime will be larger than the system uptime, by about 15 mins!
It would help to know which of both has the accurate number.
FWIW: Unix::Uptime::Linux seems to read from /proc/uptime
| [reply] [d/l] |
Re: $BASETIME (^T) inaccurate?
by Anonymous Monk on Apr 12, 2023 at 03:25 UTC
|
Linux uptime accounts for changes in the system clock. That is: If you advance the clock 15minute, uptime advances its starting time by 15 minutes.
$^T is simply the value of the time when your program started, and time is value of time now. So if the clock has advanced, the difference between these values will advance. Basically: deltas in perl 'time' cannot be used to judge time elapsed. They can only tell you what system clock was a two points.
| [reply] |
|
|
| [reply] [d/l] [select] |
|
|
| [reply] |
Re: $BASETIME (^T) inaccurate?
by MikeL (Acolyte) on Apr 12, 2023 at 17:49 UTC
|
I've made some temporary changes to the program to help work on this, namely at program startup it now saves the time of day, UnixUptime, and ^T value. I'll try to observe regularly and see what happens.
Much of the discussion until now has been about how changing the system time could affect this. I assure you, I'm not changing the system time. ntpd could be getting involved, but that would only involve at most, tenths of seconds. | [reply] [d/l] |
|
|
I assure you, I'm not changing the system time. ntpd could be getting involved, but that would only involve at most, tenths of seconds.
I explained that on a Raspberry Pi, NTP is most definitely involved (if connected to a network), and the time jumps are quite significant. Unless of course you've written your code in a way that it is not started on boot, but waits until the first time the NTP server is queried to start running, but you made no mention of that. You also mention "time of day, UnixUptime, and ^T value" but not the monotonic clock.
| [reply] |
Re: $BASETIME (^T) inaccurate?
by MikeL (Acolyte) on May 18, 2023 at 17:13 UTC
|
I've finally gotten this to do it again, and actually had time to look at it in detail.
The program is started automatically at boot by /etc/rc.local
At startup time, the program now saves in globals:
AppStrtTime = time();
AppStrtBasetime = $^T;
UnixUpAtAppStrt = Unix::Uptime->uptime();
The next afternoon I query the program and get:
System uptime: (81700) 0d 22:41:40
Program uptime: (82550) 0d 22:55:50
UnixUpAtAppStrt: 27
AppStrtTime: 1684095442
AppStartBasetime: 1684095441
time() now: 1684177991
^T now: 1684095441
Armed with these numbers, reality check:
UnixUpAtAppStrt = 27 -- sounds reasonable - boot to Perl app startup took half minute
AppStrtTime follows within a second of AppStrtBasetime -- seems right as ^T was set when the app started, which would be before the code in the app actually started to execute and perform the time() call
^T now -- matches the ^T from startup, it has not changed
With AppStrtTime time, and assuming UnixUpAtAppStrt was correct, the actual system startup time was:
1684095442 - 27 = 1684095415
Subtracting that from time now():
1684177991 - 1684095415 = 82576
yet:
Unix::Uptime->uptime() = 81700
WRONG! This should be 82576.
If it was only a few seconds off, I wouldn't have even noticed, but it's off by 14+ mins in under 24 hours!
Maybe some day I'll have a look at Unix::Uptime, but it may be a while - like years.
| [reply] |
|
|
too bad you didn't investigate the real reason this is happening: NTP.
| [reply] |
|
|
I'm really confident that it's not NTP causing the problem. The program sends me txt msgs throughout the day, including the time of day to seconds. I've never seen it appear to be out of whack. Doing a 'date' at the command line also seems accurate.
Tell me this - if the command line time on the rPi is correct right now, and I do a 'shutdown -r now', when it restarts, would the time be way (15 mins) off?
I did a vanilla noobs installation - doing a 'ps ax | grep ntp' I do not see NTPD running. This means that NTP is not changing the time under the running program, right? Does linux have some default occasional NTP run that I don't know about?
Thanks for your thoughts!
| [reply] |