Skip to content

POSIX clock_gettime() is discontinuous #8009

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
d3zd3z opened this issue May 29, 2018 · 1 comment
Closed

POSIX clock_gettime() is discontinuous #8009

d3zd3z opened this issue May 29, 2018 · 1 comment
Assignees
Labels
bug The issue is a bug, or the PR is fixing a bug priority: medium Medium impact/importance bug

Comments

@d3zd3z
Copy link
Collaborator

d3zd3z commented May 29, 2018

The implementation of clock_gettime() when called with CLOCK_MONOTONIC is non-monotonic (it jumps backward) about once a second after the first time that the k_cycle_get_32() counter wraps. On the FRDM-K64F, this means the result is incorrect after about 35 seconds, and is never correct from then on.

The problem is that the k_cycle_get_32() is used mod sys_clock_hw_cycles_per_sec. Unless the hw cycles per sec is a power of two, the overflow will not occur on a second boundary. This effectively means that this sub-second value is completely meaningless after the counter wraps the first time.

I can suggest two solutions, a short-term and a better fix:

  1. Use the lower precision 'ms' value from `k_uptime_get() to set the nanosecond field. The value will be less "accurate", but a less accurate number is still more useful than a completely meaningless value that is currently used.
  2. Longer term, keep a proper 64-bit counter by watching the k_cycle_get_32 counter, noticing overflows, and using them to increment an upper-32-bit counter. It might be best to just have a k_cycle_get_64() counter, and use that for the monotonic time.
@nashif nashif added the bug The issue is a bug, or the PR is fixing a bug label May 29, 2018
@d3zd3z
Copy link
Collaborator Author

d3zd3z commented May 30, 2018

Putting a little more thought into this, this is actually a bit harder. If implementing 2 above, we would need to make sure that we didn't read the counter in between it wrapping and the upper bits being set. It would probably take coordination with the IRQ handler, which would make accesses slower.

Perhaps 1 is the best solution. At least for TLS use of the time, the clock only needs to be accurate to within a few minutes, and certainly not more accurate than 1ms.

@nashif nashif added the priority: medium Medium impact/importance bug label May 31, 2018
ramakrishnapallala pushed a commit to ramakrishnapallala/zephyr that referenced this issue Jun 2, 2018
Use k_uptime_get() to compute both tv_sec and tv_nsec members
of timespec structure.

Fixes zephyrproject-rtos#8009

Signed-off-by: Ramakrishna Pallala <[email protected]>
nashif pushed a commit that referenced this issue Jun 2, 2018
Use k_uptime_get() to compute both tv_sec and tv_nsec members
of timespec structure.

Fixes #8009

Signed-off-by: Ramakrishna Pallala <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug The issue is a bug, or the PR is fixing a bug priority: medium Medium impact/importance bug
Projects
None yet
Development

No branches or pull requests

3 participants