Hello Greg, Thank you very much for looking at this. You are right that in NuttX today CLOCKS_PER_SEC is the rate of the system timer, and that a timer interrupt at 1 MHz would not work on small parts or with a 32.768 kHz timer. I am sorry that my first mail did not make this clear: the proposal does not change the timer or its interrupt rate.
What I would like to change is only the unit of the value that clock() returns. As I understand the standards, they use two different values: - ISO C (7.23.1 in N1256) says that CLOCKS_PER_SEC "expands to an expression with type clock_t (described below) that is the number per second of the value returned by the clock function". POSIX adds that it is one million on XSI systems, and its clock() page says: "The resolution on any particular system need not be to microsecond accuracy." - The timer tick rate is the unit of times(). POSIX gets it with sysconf(_SC_CLK_TCK); its <time.h> page says: "To obtain the number of clock ticks per second returned by the times() function, applications should call sysconf(_SC_CLK_TCK)." In NuttX that tick rate is TICK_PER_SEC and CLK_TCK, from CONFIG_USEC_PER_TICK, and it would stay exactly as it is. clock() would still advance once per tick (or at the timer resolution in a tickless build). It would only report the system time in microseconds, from clock_systime_timespec(). So a board with a 100 Hz tick or a 32.768 kHz timer keeps its interrupt rate, and the timer frequency does not have to divide one million. The 13 in-tree configurations with CONFIG_USEC_PER_TICK=1 (for example qemu-intel64:nsh and arty_a7:nsh-tickless) already have CLOCKS_PER_SEC = 1000000 today. They are all tickless, so they do not take an interrupt every microsecond. Do you see a problem with this that I missed? I would be grateful for your advice. Thank you, Marco Casaroli On Fri, Oct 23, 2026 at 2:40 PM Gregory Nutt <[email protected]> wrote: > > CLOCKS_PER_SEC is the rate of the system time (timer interrupts for those > that use interrupts). A couple comments: > > An interrupt rate of 1,000,000/sec is probably not sustainable in lower end > micro-controllers. These would typically prefer an interrupt rate of 100 or > 1,000. > > The 1,000,000 may also not be representable by some hardware. For example, > the system timer might be a base frequency of 32.768 Hz. 1,000,000 is not a > multiple of 32.768 > ________________________________ > From: Marco C. <[email protected]> > Sent: Friday, October 23, 2026 1:41 AM > To: [email protected] <[email protected]> > Subject: Re: [DISCUSS] Breaking change: make CLOCKS_PER_SEC 1000000 > > Hello Xiang, > > Thank you. I agree: no Kconfig option. CLOCKS_PER_SEC will always be > 1000000, as the specification requires. > > If there are no objections, these are the next steps: > > 1. I open steps 1 and 2 as normal pull requests. They do not change > behaviour. > 2. I open step 3 as a draft pull request, with the "!" mark and the > BREAKING CHANGE section, and I add the link to this thread. > 3. When the build and runtime logs from real hardware are in the pull > request, I start the vote. > > Thank you, > Marco Casaroli > > On Fri, Oct 23, 2026 at 10:26 AM Xiang Xiao <[email protected]> wrote: > > > > 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 > > >
