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 >
