You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
lib: os: timespec_util: reimplement and test with broad inputs
Originally, the timespec_to_timeout() and timespec_from_timeout() tests
assumed that tv_sec and tv_nsec values divided evenly with the number of
ticks per second (CONFIG_SYS_CLOCK_TICKS_PER_SEC). However, those
assumptions broke down when testing with 32768 ticks/s .
Upon further investigation, there were additional corner cases
discovered that were not handled in an ideal or safe way.
Part of this fix involved identifying several "domains" and special
values that have semantic meaning that must be handled particularly
carefully.
Additional hidden-API constants were made to simplify the solution.
K_TICK_MIN (1)
K_TICK_MAX (UINT32_MAX-1 in 32-bit, INT64_MAX in 64-bit)
K_TS_NO_WAIT (like K_NO_WAIT)
K_TS_FOREVER (like K_FOREVER)
1. Converting a negative k_timeout_t
These only exist in 64-bit representation and actually encode absolute
timepoints via ticks. Since the stated purpose of the conversion
functions is to convert between durations, we must reject absolute
time points in timespec_from_timeout().
2. Converting a negative timespec
We assume that this duration means a timeout has already expired, and
round these up to K_NO_WAIT in timespec_to_timeout().
3. Due to the larger numeric space in the timespec representation,
the reverse mapping of timespec to k_timeout_t is "fuzzy". However,
K_NO_WAIT (K_TS_NO_WAIT) and K_FOREVER (K_TS_FOREVER) must remain
semantically equivalent. The previous implementation also held this
to be true, but the test cases are a bit clearer about it now.
4. Also, due to the larger numeric space in timespec representation,
there was a special requirement to round up to the nearest tick
boundary for any timespec in the strictly exclusive range
(K_TS_NO_WAIT, K_TS_MAX). We must round up, since
a) rounding down to K_NO_WAIT is most certainly not representative
of a non-zero finite duration delay
b) the kernel operates on tick boundaries
However, since it's possible that rounding up might not _always_ be
the right thing to do, in order to allow the application to make
more informed decisions, we created a modified
timespec_to_timeout_rem() that also returns the remainder (or
difference) between the requested time to convert and resulting
k_timeout_t. The difference is expressed as a timespec object.
5. Above the K_TS_MAX boundary, which is the highest possible
timespec that can be represented by a tick, and specifically in the
64-bit timeout representation, there is a domain that cannot be
rounded up to K_TS_FOREVER and should always be rounded down to
K_TS_MAX.
This is to ensure that finite durations remain finite (even if
they are beyond the heat death of the universe).
Signed-off-by: Chris Friedt <cfriedt@tenstorrent.com>
0 commit comments