Skip to content

fix: make rt_tick_t 64-bit on ARCH_CPU_64BIT and improve clock time precision#10749

Open
lygstate wants to merge 1 commit into
RT-Thread:masterfrom
lygstate:rt_tick_t_64_bit
Open

fix: make rt_tick_t 64-bit on ARCH_CPU_64BIT and improve clock time precision#10749
lygstate wants to merge 1 commit into
RT-Thread:masterfrom
lygstate:rt_tick_t_64_bit

Conversation

@lygstate

@lygstate lygstate commented Sep 25, 2025

Copy link
Copy Markdown
Contributor

拉取/合并请求描述:(PR description)

continue work of #9008

Fixes overflow of clock_gettime rt_ktime_boottime_get_ns thoroughly

Currently the return value of clock_gettime and rt_ktime_boottime_get_ns are restricted by rt_ktime_cputimer_getres, as the value of rt_ktime_cputimer_getres are not exactly represent the frequency of the clock, directly using rt_ktime_cputimer_getfrq will ensure the return value of rt_ktime_boottime_get_ns be more exact.
And also add function rt_muldiv_u64 rt_muldiv_u32 for not losing precision when convert between cputimer and hrtimer and nanoseconds.

Because rt_ktime_boottime_get_ns depends on rt_ktime_cputimer_getcnt and rt_ktime_cputimer_getcnt depends rt_tick_get
So the rt_tick_t should be 64bit for long running program.

Use #if defined(ARCH_CPU_64BIT) is for
future allow rt_tick_t can be 64bit on 32bit CPU.

Tick count should not be restricted to the CPU

[

为什么提交这份PR (why to submit this PR)

你的解决方案是什么 (what is your solution)

请提供验证的bsp和config (provide the config and bsp)

  • BSP:
  • .config:
  • action:

]

当前拉取/合并请求的状态 Intent for your PR

必须选择一项 Choose one (Mandatory):

  • 本拉取/合并请求是一个草稿版本 This PR is for a code-review and is intended to get feedback
  • 本拉取/合并请求是一个成熟版本 This PR is mature, and ready to be integrated into the repo

代码质量 Code Quality:

我在这个拉取/合并请求中已经考虑了 As part of this pull request, I've considered the following:

  • 已经仔细查看过代码改动的对比 Already check the difference between PR and old code
  • 代码风格正确,包括缩进空格,命名及其他风格 Style guide is adhered to, including spacing, naming and other styles
  • 没有垃圾代码,代码尽量精简,不包含#if 0代码,不包含已经被注释了的代码 All redundant code is removed and cleaned up
  • 所有变更均有原因及合理的,并且不会影响到其他软件组件代码或BSP All modifications are justified and not affect other components or BSP
  • 对难懂代码均提供对应的注释 I've commented appropriately where code is tricky
  • 代码是高质量的 Code in this PR is of high quality
  • 已经使用formatting 等源码格式化工具确保格式符合RT-Thread代码规范 This PR complies with RT-Thread code specification
  • 如果是新增bsp, 已经添加ci检查到.github/ALL_BSP_COMPILE.json 详细请参考链接BSP自查

@github-actions

Copy link
Copy Markdown

👋 感谢您对 RT-Thread 的贡献!Thank you for your contribution to RT-Thread!

为确保代码符合 RT-Thread 的编码规范,请在你的仓库中执行以下步骤运行代码格式化工作流。
To ensure your code complies with RT-Thread's coding style, please run the code formatting workflow by following the steps below.


🛠 操作步骤 | Steps

  1. 前往 Actions 页面 | Go to the Actions page
    点击进入工作流 → | Click to open workflow →

  2. 点击 Run workflow | Click Run workflow

  • 设置需排除的文件/目录(目录请以"/"结尾)
    Set files/directories to exclude (directories should end with "/")
  • 将目标分支设置为 \ Set the target branch to:rt_tick_t_64_bit
  • 设置PR number为 \ Set the PR number to:10749
  1. 等待工作流完成 | Wait for the workflow to complete
    格式化后的代码将自动推送至你的分支。
    The formatted code will be automatically pushed to your branch.

完成后,提交将自动更新至 rt_tick_t_64_bit 分支,关联的 Pull Request 也会同步更新。
Once completed, commits will be pushed to the rt_tick_t_64_bit branch automatically, and the related Pull Request will be updated.

如有问题欢迎联系我们,再次感谢您的贡献!💐
If you have any questions, feel free to reach out. Thanks again for your contribution!

@github-actions

github-actions Bot commented Sep 25, 2025

Copy link
Copy Markdown

📌 Code Review Assignment

🏷️ Tag: components

Reviewers: Maihuanyi

Changed Files (Click to expand)
  • components/drivers/clock_time/arch/aarch64/cputimer.c
  • components/drivers/clock_time/arch/risc-v/virt64/cputimer.c
  • components/drivers/clock_time/clock_boottime.c
  • components/drivers/clock_time/clock_hrtimer.c
  • components/drivers/clock_time/clock_time_core.c
  • components/drivers/clock_time/clock_timer.c
  • components/drivers/include/drivers/clock_time.h
  • components/drivers/rtc/dev_soft_rtc.c
  • components/libc/compilers/common/ctime.c

🏷️ Tag: components_libc

Reviewers: GorrayLi mysterywolf

Changed Files (Click to expand)
  • components/libc/compilers/common/ctime.c

🏷️ Tag: documentation

Reviewers: CXSforHPU GorrayLi lianux-mm

Changed Files (Click to expand)
  • documentation/6.components/device-driver/clock_time/clock_time_core.md
  • documentation/6.components/device-driver/clock_time/clock_time_core_zh.md

🏷️ Tag: kernel

Reviewers: GorrayLi ReviewSun hamburger-os lianux-mm wdfk-prog xu18838022837

Changed Files (Click to expand)
  • src/rttypes.c

📊 Current Review Status (Last Updated: 2026-06-17 14:14 CST)

  • CXSforHPU Pending Review
  • GorrayLi Pending Review
  • Maihuanyi Pending Review
  • ReviewSun Pending Review
  • hamburger-os Pending Review
  • lianux-mm Pending Review
  • mysterywolf Pending Review
  • wdfk-prog Pending Review
  • xu18838022837 Pending Review

📝 Review Instructions

  1. 维护者可以通过单击此处来刷新审查状态: 🔄 刷新状态
    Maintainers can refresh the review status by clicking here: 🔄 Refresh Status

  2. 确认审核通过后评论 LGTM/lgtm
    Comment LGTM/lgtm after confirming approval

  3. PR合并前需至少一位维护者确认
    PR must be confirmed by at least one maintainer before merging

ℹ️ 刷新CI状态操作需要具备仓库写入权限。
ℹ️ Refresh CI status operation requires repository Write permission.

@lygstate lygstate force-pushed the rt_tick_t_64_bit branch 3 times, most recently from 0bc44ca to 5839f13 Compare September 27, 2025 01:50
@CLAassistant

CLAassistant commented Sep 27, 2025

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

@lygstate lygstate force-pushed the rt_tick_t_64_bit branch 2 times, most recently from c448a01 to 264c203 Compare September 27, 2025 10:06
@lygstate lygstate force-pushed the rt_tick_t_64_bit branch 3 times, most recently from 28b2e48 to d8c1321 Compare October 13, 2025 18:31
@Rbb666 Rbb666 requested a review from Copilot October 16, 2025 06:52

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR fixes overflow issues in clock_gettime and rt_ktime_boottime_get_ns by improving time conversion precision and enabling 64-bit tick counts on 64-bit architectures. The changes replace the previous resolution-based approach with direct frequency-based calculations to ensure more accurate timing operations.

Key changes:

  • Introduces precision-preserving multiplication/division functions (rt_muldiv_u64, rt_muldiv_u32)
  • Makes rt_tick_t 64-bit on 64-bit architectures to support long-running programs
  • Replaces resolution-based time calculations with frequency-based conversions throughout the timing subsystem

Reviewed Changes

Copilot reviewed 12 out of 12 changed files in this pull request and generated no comments.

Show a summary per file
File Description
src/rttypes.c Adds new multiplication/division functions for precision-preserving arithmetic
include/rttypes.h Declares the new rt_muldiv_u64 and rt_muldiv_u32 functions
include/rtdef.h Makes RT_TICK_MAX 64-bit on 64-bit architectures
components/libc/compilers/common/ctime.c Updates timer implementations to use frequency-based calculations
components/drivers/rtc/dev_soft_rtc.c Updates RTC resolution calculation
components/drivers/ktime/src/ Refactors timing subsystem to use frequency instead of resolution
bsp/rockchip/rk3500/driver/hwtimer/ Updates hardware timer interface
Comments suppressed due to low confidence (2)

src/rttypes.c:1

  • Corrected spelling of 'loseless' to 'lossless'.
/*

src/rttypes.c:1

  • Corrected spelling of 'loseless' to 'lossless'.
/*

@lygstate

Copy link
Copy Markdown
Contributor Author

@Rbb666 ping

@github-actions github-actions Bot added the BSP: Rockchip BSP related with Rockchip label Jun 17, 2026
@lygstate lygstate requested a review from Cathy-lulu as a code owner June 17, 2026 05:21
@github-actions github-actions Bot added the Doc This PR/issue related with documents label Jun 17, 2026
@lygstate lygstate changed the title Fixes clock_gettime and rt_ktime_boottime_get_ns fix: make rt_tick_t 64-bit on ARCH_CPU_64BIT and improve clock time precision Jun 17, 2026
@lygstate

lygstate commented Jun 17, 2026

Copy link
Copy Markdown
Contributor Author

ping for review, and avoid newly conflict like #11111
@Rbb666 @Guozhanxin @BernardXiong

After this, unlock #10735 would be strait-forward

…recision

- Make rt_tick_t and RT_TICK_MAX 64-bit when ARCH_CPU_64BIT is defined

- Add rt_muldiv_u64() and rt_muldiv_u32() for lossless counter and nanosecond conversions

- Convert boottime, clock_gettime, POSIX timers, and hrtimer paths with clock source frequency instead of scaled resolution

- Rewrite rt_clock_time_counter_to_ns() and rt_clock_time_ns_to_counter() with rt_muldiv_u64() for the VDSO path

- Remove RT_CLOCK_TIME_RESMUL, res_scale, and scaled-resolution APIs:

  - res_scale was only a fixed-point multiplier for resolution math (res_scaled = 1e9 * res_scale / freq); it did not customize clock frequency

  - All in-tree devices always used the default RT_CLOCK_TIME_RESMUL value, so the field provided no real per-board tuning

  - Converting through res_scaled introduced extra rounding error compared with using get_freq() directly

  - Custom frequency remains available through rt_clock_time_ops.get_freq, rt_clock_time_source_init(), and rt_clock_time_device_register()

  - Drop RT_CLOCK_TIME_RESMUL, struct rt_clock_time_device.res_scale, rt_clock_time_get_res_scaled(), rt_clock_time_get_event_res_scaled(), and rt_clock_hrtimer_getres()

- Port the original ktime fixes to the clock_time API

- Keep soft-timer fallback rounding in _hrtimer_cnt_to_tick() so sub-tick timeouts schedule at least one OS tick

- Update clock_time core documentation
case CLOCK_THREAD_CPUTIME_ID:
res->tv_sec = 0;
res->tv_nsec = (rt_clock_time_get_res_scaled() / RT_CLOCK_TIME_RESMUL);
res->tv_nsec = (rt_uint32_t)(NANOSECOND_PER_SECOND / rt_clock_time_get_freq());

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the clock source frequency is 0, it will divide by zero; it is recommended to add a check.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good catch, I do it as a plain replace of rt_clock_time_get_res_scaled, so it's exposed a existing issue.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It can be placed in components/drivers/clock_time/clock_time_core.c as a static helper, or a new clock_time private header such as clock_time_internal.h can be added for clock_boottime.c and clock_hrtimer.c to share.

unsigned long remain_cnt;
rt_tick_t remain_cnt;
rt_uint64_t remain_relative_cnt;
const rt_uint64_t freq = rt_clock_time_get_freq();

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is recommended to check if freq == 0 first and return an error, similar to rt_clock_boottime_get_*().

Comment thread src/rttypes.c
}

/**
* https://ridiculousfish.com/blog/posts/labor-of-division-episode-v.html

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please ensure your comments conform to Doxygen's comment style. See: https://rt-thread.github.io/rt-thread/page_howto_doxygen.html

Comment thread src/rttypes.c

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

rt_muldiv_u64() is a numeric helper, not a type primitive. Adding src/rttypes.c just for this function makes the rttypes module misleading. Since current users are all clock-time conversions, please keep it private under components/drivers/clock_time/ first. If it is intended as a generic helper, place it together with existing 64-bit division helpers such as rt_do_div / rt_div_u64 instead of exposing it from rttypes.h.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about rt_time_muldiv_u64 or other name? or _rt_muldiv_u64 for private usage only?

Comment thread src/rttypes.c
return ((rt_uint64_t)q1 << 32) | q0;
}

rt_uint64_t rt_muldiv_u64(rt_uint64_t a, rt_uint64_t b, rt_uint64_t c, rt_uint64_t *r)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

rt_muldiv_u64() is documented as a lossless helper, and the copied u128_div_u64_u64() comment says that when the quotient requires more than 64 bits it should return the max value. However, the current implementation does:

numhi = numhi % den;

when numhi >= den, which silently discards the overflow part and returns a truncated quotient.

For example, rt_muldiv_u64(UINT64_MAX, 2, 1, NULL) returns UINT64_MAX - 1, while the mathematical result is larger than UINT64_MAX. This is risky because the helper is used for time conversions, where truncating an overflowed timeout/counter value can produce a much smaller delay than requested.

Please either implement the documented saturation behavior, e.g. return RT_UINT64_MAX and set the remainder consistently when the quotient does not fit in 64 bits, or explicitly document the truncation semantics and avoid using this helper on paths where overflow is possible.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Arch: ARM/AArch64 BSP related with arm BSP: Rockchip BSP related with Rockchip BSP component: drivers/ktime component: drivers/rtc component: drivers Component Doc This PR/issue related with documents Kernel PR has src relate code libcpu

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants