apache / nuttx

Apache NuttX is a mature, real-time embedded operating system (RTOS)
https://nuttx.apache.org/
Apache License 2.0
2.6k stars 1.11k forks source link

clock() and CLOCKS_PER_SEC is not POSIX compliant #3516

Open btashton opened 3 years ago

btashton commented 3 years ago

NuttX defines CLOCKS_PER_SEC as:

#ifdef CONFIG_USEC_PER_TICK
# define CLK_TCK           (1000000/CONFIG_USEC_PER_TICK)
# define CLOCKS_PER_SEC    (1000000/CONFIG_USEC_PER_TICK)
#else
# define CLK_TCK           (100)
# define CLOCKS_PER_SEC    (100)
#endif

But the POSIX standard defines it as always one million. https://pubs.opengroup.org/onlinepubs/9699919799/functions/clock.html

btashton commented 3 years ago

@patacongo do you have any thoughts on this one?

patacongo commented 3 years ago

@patacongo do you have any thoughts on this one?

This implies that OpenGroup.org expects the system timer to ALWAYS have a resolution of 1 MSec. Just changing the the setting to a million would break all architectures. And, if all system timer APIs were modified to report / accept the time in "ticks" at a resolution of 1 MSec, then there were would be loss of functionality that is very important to an embedded system.

patacongo commented 3 years ago

You are not the only one confused: https://stackoverflow.com/questions/10455905/why-is-clocks-per-sec-not-the-actual-number-of-clocks-per-second

xiaoxiang781216 commented 3 years ago

From the thread:

The only thing the C99 N1256 standard draft says about CLOCKS_PER_SEC is that:
CLOCKS_PER_SEC which expands to an expression with type clock_t (described below) that is the number per second of the value returned by the clock function

And the quote from opengroup:

The functionality described on this reference page is aligned with the ISO C standard. Any conflict between the requirements described here and the ISO C standard is unintentional. This volume of POSIX.1-2017 defers to the ISO C standard. 

A value different from 1000000 is acceptable.

btashton commented 3 years ago

Ah yes I see that the N1256 says nothing about this needing to be 1000000. Unfortunate that the open posix test suite asserts this value.

patacongo commented 3 years ago

Ah yes I see that the N1256 says nothing about this needing to be 1000000. Unfortunate that the open posix test suite asserts this value.

Then it must also be a POSIX error that the return value of clock() is incorrect: https://pubs.opengroup.org/onlinepubs/9699919799/functions/clock.html

But clock() would fail a POSIX test anyway because it is supposed to be the CPU time used by a process, not the elapsed time since reset.

In general, I believe that we have to comply with POSIX requirements, whether we like them or not.

Interestingly, the older CLK_TCK does not seem to have any required value.

patacongo commented 3 years ago

I see you closed this. Is that what we should do? It appears to be a real POSIX non-conformance problem.

btashton commented 3 years ago

My reading of the opengroup page is that it is OK if CLOCKS_PER_SEC is not 1M, as it is suppose to be the definition of C N1256 standard (which has no requirement for this), it just usually is 1M. What is important is that clock() / CLOCKS_PER_SEC is gives to process duration. Because we are using clock_systime_ticks this is not correct.

My understanding is that we should to make clock() return the process ticks. It would be nice if we made CLOCKS_PER_SEC be 1M, but it would be ideal to just hide this in the clock() interfaces and use a real CLOCKS_PER_SEC in the OS internals. This second bit I don't think is technically required.