It's always a bad idea to add a Kconfig option which changes the
visible behavior difference for the same function,
how could we write a program which uses CLOCKS_PER_SEC behaviour
consistently regardless of the option value?
so, it's better to make it always confirm the spec or not change it at all.

On Fri, Oct 23, 2026 at 4:11 PM Marco C. <[email protected]> wrote:

> Hello,
>
> I want to discuss a breaking change before I open the pull request, as
> CONTRIBUTING.md 1.13 asks.
>
> The problem
>
> In NuttX, CLOCKS_PER_SEC is the system tick rate (1000000 /
> CONFIG_USEC_PER_TICK, 100 by default), and clock() returns system
> ticks. POSIX requires CLOCKS_PER_SEC to be 1000000 on XSI systems:
>
> https://pubs.opengroup.org/onlinepubs/9799919799/basedefs/time.h.html
> https://pubs.opengroup.org/onlinepubs/9799919799/functions/clock.html
>
> Issue #3516 (2021) reported this:
> https://github.com/apache/nuttx/issues/3516. A comment there says that
> ISO C allows any value. That is correct, but programs written for
> POSIX systems expect 1000000, and the Open POSIX Test Suite checks it
> (conformance/interfaces/clock/2-1.c). Also, the same macro has two
> meanings in NuttX today: 22 files in arch/, drivers/, fs/ and sched/
> use CLOCKS_PER_SEC as the tick rate, where CLK_TCK or TICK_PER_SEC is
> the correct name.
>
> The proposal, in three steps
>
> 1. nuttx-apps: netutils/ftpc and system/cpuload use CLK_TCK for the
> tick rate. CLK_TCK has the same value as CLOCKS_PER_SEC today, so
> nothing changes.
> 2. nuttx: the 22 files use CLK_TCK for the tick rate. The generated
> code does not change.
> 3. nuttx, the breaking change: CLOCKS_PER_SEC is 1000000 and clock()
> returns microseconds. times() and sysconf(_SC_CLK_TCK) stay in ticks
> (CLK_TCK). clock_t is int64_t, so the value does not overflow.
>
> Steps 1 and 2 do not change behaviour. I can send them as normal pull
> requests now. Only step 3 needs the vote.
>
> What breaks with step 3
>
> - Code that uses CLOCKS_PER_SEC as the number of ticks per second, for
> example to convert seconds into a timeout for wd_start() or
> nxsig_usleep(). Quick fix: use CLK_TCK or TICK_PER_SEC.
> - Code that divides clock() by CLOCKS_PER_SEC needs no change.
> - In protected and kernel builds, clock() is a system call. Programs
> built with the old header must be built again.
>
> The resolution of clock() does not change: it still advances once per
> tick. Only the unit changes. clock() also still returns the time since
> boot, not the processor time of the process (the other point of
> #3516); this proposal does not change that.
>
> A non-breaking alternative
>
> A Kconfig option selects CLOCKS_PER_SEC = 1000000, and it is off by
> default. Steps 1 and 2 stay the same. The problem: the value of a
> standard macro then depends on the configuration, so code that uses
> CLOCKS_PER_SEC as the tick rate breaks only in some configurations,
> and later.
>
> Tests so far
>
> QEMU (qemu-armv8a:knsh): a test program checks CLOCKS_PER_SEC, and
> that clock() and times() both measure 0.5 s of processor time
> correctly. ostest passes on qemu-armv8a:nsh. Seven configurations
> build (flat, protected and kernel; arm64, armv7-m, rv64, x86_64).
> Before a vote, I will add build and ostest logs from real hardware of
> more than one architecture, as CONTRIBUTING.md 1.14 requires.
>
> Questions
>
> 1. Do you agree with the change, or do you prefer the Kconfig option?
> 2. Is it OK to send steps 1 and 2 now as normal pull requests?
>
> Thank you,
> Marco Casaroli
>

Reply via email to